diff --git a/.eslintrc.js b/.eslintrc.js index 5c90923..e2534a3 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -55,6 +55,7 @@ module.exports = { "@typescript-eslint/no-unused-vars": "off", "no-control-regex": "off", "no-eval": "off", - "no-unused-expressions": "off" + "no-unused-expressions": "off", + "import/order": "off" } }; diff --git a/.gitignore b/.gitignore index 94fd8de..7c27bda 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,14 @@ node_modules -.vscode audio chrome data fonts icon img -js +js/* movies save Game.rpgproject package-lock.json -/ts/plugins -*.code-workspace +*.rar +!js/plugins.js \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..8776363 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,25 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "nwjs", + "request": "launch", + "name": "Launch NWjs with Build", + "nwjsVersion": "any", + "webRoot": "${workspaceFolder}", + "reloadAfterAttached": false, + "preLaunchTask": "tsc: build - tsconfig.json" + }, + { + "type": "nwjs", + "request": "launch", + "name": "Launch NWjs", + "nwjsVersion": "any", + "webRoot": "${workspaceFolder}", + "reloadAfterAttached": false + } + ] +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..6beee12 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,23 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "type": "typescript", + "tsconfig": "tsconfig.json", + "problemMatcher": ["$tsc"], + "options": { + "shell": { + "executable": "powershell.exe" + } + } + }, + { + "type": "typescript", + "tsconfig": "tsconfig.json", + "option": "watch", + "problemMatcher": ["$tsc-watch"] + } + ] +} diff --git a/index.html b/index.html index 090ad82..0bb9452 100644 --- a/index.html +++ b/index.html @@ -11,12 +11,15 @@ - Dragon Slayers Demo + Testbench diff --git a/js/plugins.js b/js/plugins.js new file mode 100644 index 0000000..1671c76 --- /dev/null +++ b/js/plugins.js @@ -0,0 +1,267 @@ +// Generated by RPG Maker. +// Do not edit this file directly. +var $plugins = [ + { + name: "Community_Basic", + status: false, + description: "Basic plugin for manipulating important parameters.", + parameters: { + cacheLimit: "20", + screenWidth: "816", + screenHeight: "624", + changeWindowWidthTo: "", + changeWindowHeightTo: "", + renderingMode: "auto", + alwaysDash: "off" + } + }, + { + name: "MadeWithMv", + status: false, + description: + 'Show a Splash Screen "Made with MV" and/or a Custom Splash Screen before going to main screen.', + parameters: { + "Show Made With MV": "true", + "Made with MV Image": "MadeWithMv", + "Show Custom Splash": "false", + "Custom Image": "", + "Fade Out Time": "120", + "Fade In Time": "120", + "Wait Time": "160" + } + }, + { + name: "Stronk_YEP_CoreEngine", + status: true, + description: + "v1.31 Needed for the majority of Yanfly Engine Scripts. Also\r\ncontains bug fixes found inherently in RPG Maker.", + parameters: { + "Open Console": "false", + "Collection Clear": "true", + "---Gold---": "", + "Gold Max": "99999999", + "Gold Font Size": "20", + "Gold Icon": "313", + "Gold Overlap": "A lotta", + "---Items---": "", + "Default Max": "99", + "Quantity Text Size": "20", + "---Parameters---": "", + "Max Level": "99", + "Actor MaxHP": "9999", + "Actor MaxMP": "9999", + "Actor Parameter": "999", + "Enemy MaxHP": "999999", + "Enemy MaxMP": "9999", + "Enemy Parameter": "999", + "---Battle---": "", + "Animation Rate": "4", + "Flash Target": "false", + "Show Events Transition": "true", + "Show Events Snapshot": "true", + "---Map Optimization---": "", + "Refresh Update HP": "true", + "Refresh Update MP": "true", + "Refresh Update TP": "false", + "---Font---": "", + "Chinese Font": "SimHei, Heiti TC, sans-serif", + "Korean Font": "Dotum, AppleGothic, sans-serif", + "Default Font": "GameFont, Verdana, Arial, Courier New", + "Font Size": "28", + "Text Align": "left", + "---Windows---": "", + "Digit Grouping": "true", + "Line Height": "36", + "Icon Width": "32", + "Icon Height": "32", + "Face Width": "144", + "Face Height": "144", + "Window Padding": "18", + "Text Padding": "6", + "Window Opacity": "192", + "Gauge Outline": "true", + "Gauge Height": "18", + "Menu TP Bar": "true", + "---Window Colors---": "", + "Color: Normal": "0", + "Color: System": "16", + "Color: Crisis": "17", + "Color: Death": "18", + "Color: Gauge Back": "19", + "Color: HP Gauge 1": "20", + "Color: HP Gauge 2": "21", + "Color: MP Gauge 1": "22", + "Color: MP Gauge 2": "23", + "Color: MP Cost": "23", + "Color: Power Up": "24", + "Color: Power Down": "25", + "Color: TP Gauge 1": "28", + "Color: TP Gauge 2": "29", + "Color: TP Cost Color": "29" + } + }, + { + name: "Stronk_YEP_BattleEngineCore", + status: true, + description: + "v1.50 Have more control over the flow of the battle system\r\nwith this plugin and alter various aspects to your liking.", + parameters: { + "---General---": "", + "Action Speed": "agi", + "Default System": "dtb", + "---Escape---": "", + "Escape Ratio": "0.5 * $gameParty.agility() / $gameTroop.agility()", + "Fail Escape Boost": "0.10", + "---Animation---": "", + "Animation Base Delay": "0", + "Animation Next Delay": "0", + "Certain Hit Animation": "0", + "Physical Animation": "52", + "Magical Animation": "51", + "Enemy Attack Animation": "39", + "Reflect Animation": "42", + "Motion Waiting": "false", + "---Frontview---": "", + "Front Position X": + "Graphics.boxWidth / 8 + Graphics.boxWidth / 4 * index", + "Front Position Y": "Graphics.boxHeight - 180", + "Front Actor Sprite": "false", + "Front Sprite Priority": "1", + "---Sideview---": "", + "Home Position X": + "screenWidth - 16 - (maxSize + 2) * 32 + index * 32", + "Home Position Y": + "screenHeight - statusHeight - maxSize * 48 + (index+1) * 48 - 32", + "Side Sprite Priority": "1", + "---Sprites---": "", + "Default X Anchor": "0.50", + "Default Y Anchor": "1.00", + "Step Distance": "48", + "Flinch Distance": "12", + "Show Shadows": "true", + "---Damage Popups---": "", + "Popup Duration": "128", + "Newest Popup Bottom": "true", + "Popup Overlap Rate": "0.9", + "Critical Popup": "255, 0, 0, 160", + "Critical Duration": "60", + "---Tick-Settings---": "", + "Timed States": "false", + "Timed Buffs": "false", + "Turn Time": "100", + "AI Self Turns": "true", + "---Window Settings---": "", + "Lower Windows": "true", + "Window Rows": "4", + "Command Window Rows": "4", + "Command Alignment": "center", + "Start Actor Command": "true", + "Current Max": "false", + "---Selection Help---": "", + "Mouse Over": "true", + "Select Help Window": "true", + "User Help Text": "User", + "Ally Help Text": "Ally", + "Allies Help Text": "Allies", + "Enemy Help Text": "Enemy", + "Enemies Help Text": "Enemies", + "All Help Text": "All %1", + "Random Help Text": "%2 Random %1", + "---Enemy Select---": "", + "Visual Enemy Select": "true", + "Show Enemy Name": "true", + "Show Select Box": "false", + "Enemy Font Size": "20", + "Enemy Auto Select": "this.furthestRight()", + "---Actor Select---": "", + "Visual Actor Select": "true", + "---Battle Log---": "", + "Show Emerge Text": "false", + "Show Pre-Emptive Text": "true", + "Show Surprise Text": "true", + "Optimize Speed": "true", + "Show Action Text": "false", + "Show State Text": "false", + "Show Buff Text": "false", + "Show Counter Text": "true", + "Show Reflect Text": "true", + "Show Substitute Text": "true", + "Show Fail Text": "false", + "Show Critical Text": "false", + "Show Miss Text": "false", + "Show Evasion Text": "false", + "Show HP Text": "false", + "Show MP Text": "false", + "Show TP Text": "false" + } + }, + { + name: "Stronk_YEP_BaseParamControl", + status: true, + description: + "v1.04 Gain control over the method of calculation for base\r\nparameters: MaxHP, MaxMP, ATK, DEF, MAT, MDF, AGI, LUK.", + parameters: { + "---MaxHP---": "", + "MHP Formula": "(base + plus) * paramRate * buffRate + flat", + "MHP Maximum": "customMax || (user.isActor() ? 9999 : 999999)", + "MHP Minimum": "customMin || 1", + "---MaxMP---": "", + "MMP Formula": "(base + plus) * paramRate * buffRate + flat", + "MMP Maximum": "customMax || (user.isActor() ? 9999 : 9999)", + "MMP Minimum": "customMin || 0", + "---Attack---": "", + "ATK Formula": "(base + plus) * paramRate * buffRate + flat", + "ATK Maximum": "customMax || (user.isActor() ? 999 : 999)", + "ATK Minimum": "customMin || 1", + "---Defense---": "", + "DEF Formula": "(base + plus) * paramRate * buffRate + flat", + "DEF Maximum": "customMax || (user.isActor() ? 999 : 999)", + "DEF Minimum": "customMin || 1", + "---M.Attack---": "", + "MAT Formula": "(base + plus) * paramRate * buffRate + flat", + "MAT Maximum": "customMax || (user.isActor() ? 999 : 999)", + "MAT Minimum": "customMin || 1", + "---M.Defense---": "", + "MDF Formula": "(base + plus) * paramRate * buffRate + flat", + "MDF Maximum": "customMax || (user.isActor() ? 999 : 999)", + "MDF Minimum": "customMin || 1", + "---Agility---": "", + "AGI Formula": "(base + plus) * paramRate * buffRate + flat", + "AGI Maximum": "customMax || (user.isActor() ? 999 : 999)", + "AGI Minimum": "customMin || 1", + "---Luck---": "", + "LUK Formula": "(base + plus) * paramRate * buffRate + flat", + "LUK Maximum": "customMax || (user.isActor() ? 999 : 999)", + "LUK Minimum": "customMin || 1", + "LUK Effect": "Math.max(1.0 + (user.luk - target.luk) * 0.001, 0.0)" + } + }, + { + name: "Stronk_YEP_ExtraParamFormula", + status: true, + description: + "v1.04 Control the formulas of the extra parameters for\r\nHIT, EVA, CRI, CEV, MEV, MRF, CNT, HRG, MRG, and TRG.", + parameters: { + "HIT Formula": "(base + plus) * rate + flat", + "EVA Formula": "(base + plus) * rate + flat", + "CRI Formula": "(base + plus) * rate + flat", + "CEV Formula": "(base + plus) * rate + flat", + "MEV Formula": "(base + plus) * rate + flat", + "MRF Formula": "(base + plus) * rate + flat", + "CNT Formula": "(base + plus) * rate + flat", + "HRG Formula": "(base + plus) * rate + flat", + "MRG Formula": "(base + plus) * rate + flat", + "TRG Formula": "(base + plus) * rate + flat" + } + }, + { + name: "Stronk_YEP_LoadCustomFonts", + status: true, + description: + "v1.01 Load custom fonts from the /fonts/ folder. This will\r\nallow you to use custom fonts without installing them.", + parameters: { + "Font Filenames": "cc-wild-words.ttf, ds-pixel-cyr.ttf", + "Font Families": "CC Wild Words, DS Pixel Cyr" + } + } +]; diff --git a/package.json b/package.json index 5a909e9..7bffabd 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "stronk-v1.1.0", "main": "index.html", "js-flags": "--expose-gc", - "chromium-args": "--mixed-context --remote-debugging-port=9223 --load-extension=chrome --limit-fps=60", + "chromium-args": "--mixed-context --remote-debugging-port=9223 --limit-fps=60 --disable-features=nw2", "window": { "title": "STRONK! v.0.1.0", "toolbar": false, @@ -18,7 +18,6 @@ "devDependencies": { "@types/lz-string": "^1.3.33", "@types/node": "^11.13.13", - "@types/pixi.js": "^4.8.8", "@typescript-eslint/eslint-plugin": "^1.9.0", "bestzip": "^1.1.3", "concat-with-sourcemaps": "^1.0.4", @@ -46,9 +45,9 @@ "lodash": "^4.17.15", "lz-string": "^1.4.4", "nw": "^0.41.1", - "pixi-picture": "^1.3.1", - "pixi-tilemap": "^1.2.4", - "pixi.js": "^4.8.8", + "pixi-picture": "^1.3.2", + "pixi-tilemap": "^2.0.3", + "pixi.js": "^5.2.1", "source-map-support": "^0.5.13", "ts-node": "^8.2.0", "typescript": "^3.5.1" diff --git a/ts/core/Bitmap.ts b/ts/core/Bitmap.ts index a568e97..e670823 100644 --- a/ts/core/Bitmap.ts +++ b/ts/core/Bitmap.ts @@ -121,9 +121,11 @@ export class Bitmap { const height = Graphics.height; const bitmap = new Bitmap(width, height); const context = bitmap._context; - const renderTexture = PIXI.RenderTexture.create(width, height); + const renderTexture = PIXI.RenderTexture.create({ + width: width, + height: height + }); if (stage) { - // @ts-ignore Graphics.renderer.render(stage, renderTexture); stage.worldTransform.identity(); context.drawImage( @@ -286,8 +288,7 @@ export class Bitmap { height = Math.max(height || 0, 1); this._canvas.width = width; this._canvas.height = height; - this._baseTexture.width = width; - this._baseTexture.height = height; + this._baseTexture.setSize(width, height); } /** @@ -1031,9 +1032,8 @@ export class Bitmap { private _createBaseTexture(source) { this.__baseTexture = new PIXI.BaseTexture(source); - this.__baseTexture.mipmap = false; - this.__baseTexture.width = source.width; - this.__baseTexture.height = source.height; + this.__baseTexture.mipmap = PIXI.MIPMAP_MODES.OFF; + this.__baseTexture.setSize(source.width, source.height); if (this._smooth) { this._baseTexture.scaleMode = PIXI.SCALE_MODES.LINEAR; diff --git a/ts/core/Graphics.ts b/ts/core/Graphics.ts index 1c3a30a..5e75943 100644 --- a/ts/core/Graphics.ts +++ b/ts/core/Graphics.ts @@ -114,7 +114,7 @@ export abstract class Graphics { */ public static BLEND_SCREEN: number = 3; - public static renderer: PIXI.WebGLRenderer; + public static renderer: PIXI.Renderer; private static _rendererType: any; private static _boxWidth: number; @@ -695,22 +695,23 @@ export abstract class Graphics { } public static printFullError(name: string, message: string, stack: string) { - if (Graphics._errorPrinter) { - Graphics._errorPrinter.innerHTML = Graphics._makeFullErrorHtml( + const stackArray = this.processErrorStackMessage(stack); + if (this._errorPrinter) { + this._errorPrinter.innerHTML = this._makeFullErrorHtml( name, message, - Graphics.processErrorStackMessage(stack) + stackArray ); } - Graphics._applyCanvasFilter(); - Graphics._clearUpperCanvas(); + this._applyCanvasFilter(); + this._clearUpperCanvas(); } private static _makeFullErrorHtml( name: string, message: string, stack: string[] - ) { + ): string { let text = ""; for (var i = 2; i < stack.length; ++i) { text += "" + stack[i] + "
"; @@ -730,7 +731,7 @@ export abstract class Graphics { const data = stack.split(/(?:\r\n|\r|\n)/); data.unshift("Game has encountered a bug. Please report it.
"); for (let i = 1; i < data.length; ++i) { - data[i] = data[i].replace(/[\(](.*[\/])/, "("); + data[i] = data[i].replace(/[(](.*[/])/, "("); } data.push( '
Press F5 to restart the game.' + @@ -956,9 +957,13 @@ export abstract class Graphics { private static _createRenderer = function() { const width = Graphics.width; const height = Graphics.height; - const options = { view: Graphics._canvas }; + const options = { + view: Graphics._canvas, + width: width, + height: height + }; try { - Graphics.renderer = new PIXI.WebGLRenderer(width, height, options); + Graphics.renderer = new PIXI.Renderer(options); if (Graphics.renderer && Graphics.renderer.textureGC) { Graphics.renderer.textureGC.maxIdle = 1; } diff --git a/ts/core/Input.ts b/ts/core/Input.ts index b4c1375..a8adfeb 100644 --- a/ts/core/Input.ts +++ b/ts/core/Input.ts @@ -185,7 +185,7 @@ export class Input { private static shouldPreventDefault(keycode: number): boolean { switch (keycode) { case 8: // backspace - case 9: // ??? + case 9: // ??? (Blame Yanfly) case 33: // pageup case 34: // pagedown case 37: // left arrow diff --git a/ts/core/JsonEx.ts b/ts/core/JsonEx.ts index 3ab2019..f895fb8 100644 --- a/ts/core/JsonEx.ts +++ b/ts/core/JsonEx.ts @@ -1,3 +1,5 @@ +import * as _ from "lodash"; + export abstract class JsonEx { /** * The maximum depth of objects. @@ -53,8 +55,8 @@ export abstract class JsonEx { * @param {Object} object The object to be copied * @return {Object} The copied object */ - public static makeDeepCopy(object): object { - return this.parse(this.stringify(object)); + public static makeDeepCopy(object: T): T { + return _.cloneDeep(object); } private static _id: number = 1; diff --git a/ts/core/ScreenSprite.ts b/ts/core/ScreenSprite.ts index 36eeb5b..ae6de1f 100644 --- a/ts/core/ScreenSprite.ts +++ b/ts/core/ScreenSprite.ts @@ -10,16 +10,6 @@ export class ScreenSprite extends PIXI.Container { public _blue: number; public _colorText: string; - public static YEPWarned = false; - public static warnYep() { - if (!ScreenSprite.YEPWarned) { - console.log( - "Deprecation warning. Please update YEP_CoreEngine. ScreenSprite is not a sprite, it has graphics inside." - ); - ScreenSprite.YEPWarned = true; - } - } - public constructor() { super(); @@ -32,14 +22,6 @@ export class ScreenSprite extends PIXI.Container { this._blue = -1; this._colorText = ""; this.setBlack(); - - if (Utils.RPGMAKER_VERSION && Utils.RPGMAKER_VERSION >= "1.3.0") return; - this.scale.x = Graphics.boxWidth * 10; - this.scale.y = Graphics.boxHeight * 10; - this.anchor.x = 0.5; - this.anchor.y = 0.5; - this.x = 0; - this.y = 0; } /** @@ -101,7 +83,6 @@ export class ScreenSprite extends PIXI.Container { } public get anchor(): Point { - ScreenSprite.warnYep(); this.scale.x = 1; this.scale.y = 1; return new Point(0, 0); diff --git a/ts/core/Sprite.ts b/ts/core/Sprite.ts index 7deb386..f4b8aa8 100644 --- a/ts/core/Sprite.ts +++ b/ts/core/Sprite.ts @@ -62,7 +62,6 @@ export class Sprite extends PIXI.Sprite { public ry: number; public dy: number; - public _renderWebGL_PIXI = PIXI.WebGLRenderer.prototype.render; protected _isPicture: boolean; private _bitmap: any; @@ -252,13 +251,15 @@ export class Sprite extends PIXI.Sprite { } else if (this._bitmap) { this.texture.frame = Rectangle.emptyRectangle; } else { - this.texture.baseTexture.width = Math.max( - this.texture.baseTexture.width, - this._frame.x + this._frame.width - ); - this.texture.baseTexture.height = Math.max( - this.texture.baseTexture.height, - this._frame.y + this._frame.height + this.texture.baseTexture.setSize( + Math.max( + this.texture.baseTexture.width, + this._frame.x + this._frame.width + ), + Math.max( + this.texture.baseTexture.height, + this._frame.y + this._frame.height + ) ); this.texture.frame = this._frame; } @@ -381,46 +382,12 @@ export class Sprite extends PIXI.Sprite { context.drawImage(this._bitmap.canvas, x, y, w, h, 0, 0, w, h); } - /** - * checks if we need to speed up custom blendmodes - * @param renderer - * @private - */ - public _speedUpCustomBlendModes(renderer: { - plugins: { picture: any }; - renderingToScreen: any; - _activeRenderTarget: { root: any }; - _lastObjectRendered: any; - }) { - const picture = renderer.plugins.picture; - const blend = this.blendMode; - if (renderer.renderingToScreen && renderer._activeRenderTarget.root) { - if (picture.drawModes[blend]) { - const stage = renderer._lastObjectRendered; - const f = stage._filters; - if (!f || !f[0]) { - setTimeout(function() { - const f = stage._filters; - if (!f || !f[0]) { - stage.filters = [Sprite.voidFilter]; - stage.filterArea = new PIXI.Rectangle( - 0, - 0, - Graphics.width, - Graphics.height - ); - } - }, 0); - } - } - } - } /** * @method _renderWebGL * @param {Object} renderer * @private */ - public _renderWebGL(renderer) { + public _render(renderer: PIXI.Renderer) { if (this.bitmap) { this.bitmap.touch(); } @@ -432,19 +399,13 @@ export class Sprite extends PIXI.Sprite { this._bitmap.checkDirty(); } - // copy of pixi-v4 internal code this.calculateVertices(); if (this.pluginName === "sprite" && this._isPicture) { - // use heavy renderer, which reduces artifacts and applies corrent blendMode, - // but does not use multitexture optimization - this._speedUpCustomBlendModes(renderer); - renderer.setObjectRenderer(renderer.plugins.picture); - renderer.plugins.picture.render(this); + renderer.batch.setObjectRenderer(renderer.plugins.picture); + renderer.batch.renderer.render(this); } else { - // use pixi super-speed renderer - renderer.setObjectRenderer(renderer.plugins[this.pluginName]); - renderer.plugins[this.pluginName].render(this); + super._render(renderer); } } } diff --git a/ts/core/Tilemap.ts b/ts/core/Tilemap.ts index 4e3bb66..a3b1e53 100644 --- a/ts/core/Tilemap.ts +++ b/ts/core/Tilemap.ts @@ -1,9 +1,9 @@ +import "pixi-tilemap"; import * as PIXI from "pixi.js"; +import { ConfigManager } from "../managers/ConfigManager"; import { PluginManager } from "../managers/PluginManager"; import { Bitmap } from "./Bitmap"; -import { Graphics } from "./Graphics"; import { Point } from "./Point"; -import { ConfigManager } from "../managers/ConfigManager"; export class Tilemap extends PIXI.Container { /** @@ -91,80 +91,420 @@ export class Tilemap extends PIXI.Container { // Autotile shape number to coordinates of tileset images public static FLOOR_AUTOTILE_TABLE = [ - [[2, 4], [1, 4], [2, 3], [1, 3]], - [[2, 0], [1, 4], [2, 3], [1, 3]], - [[2, 4], [3, 0], [2, 3], [1, 3]], - [[2, 0], [3, 0], [2, 3], [1, 3]], - [[2, 4], [1, 4], [2, 3], [3, 1]], - [[2, 0], [1, 4], [2, 3], [3, 1]], - [[2, 4], [3, 0], [2, 3], [3, 1]], - [[2, 0], [3, 0], [2, 3], [3, 1]], - [[2, 4], [1, 4], [2, 1], [1, 3]], - [[2, 0], [1, 4], [2, 1], [1, 3]], - [[2, 4], [3, 0], [2, 1], [1, 3]], - [[2, 0], [3, 0], [2, 1], [1, 3]], - [[2, 4], [1, 4], [2, 1], [3, 1]], - [[2, 0], [1, 4], [2, 1], [3, 1]], - [[2, 4], [3, 0], [2, 1], [3, 1]], - [[2, 0], [3, 0], [2, 1], [3, 1]], - [[0, 4], [1, 4], [0, 3], [1, 3]], - [[0, 4], [3, 0], [0, 3], [1, 3]], - [[0, 4], [1, 4], [0, 3], [3, 1]], - [[0, 4], [3, 0], [0, 3], [3, 1]], - [[2, 2], [1, 2], [2, 3], [1, 3]], - [[2, 2], [1, 2], [2, 3], [3, 1]], - [[2, 2], [1, 2], [2, 1], [1, 3]], - [[2, 2], [1, 2], [2, 1], [3, 1]], - [[2, 4], [3, 4], [2, 3], [3, 3]], - [[2, 4], [3, 4], [2, 1], [3, 3]], - [[2, 0], [3, 4], [2, 3], [3, 3]], - [[2, 0], [3, 4], [2, 1], [3, 3]], - [[2, 4], [1, 4], [2, 5], [1, 5]], - [[2, 0], [1, 4], [2, 5], [1, 5]], - [[2, 4], [3, 0], [2, 5], [1, 5]], - [[2, 0], [3, 0], [2, 5], [1, 5]], - [[0, 4], [3, 4], [0, 3], [3, 3]], - [[2, 2], [1, 2], [2, 5], [1, 5]], - [[0, 2], [1, 2], [0, 3], [1, 3]], - [[0, 2], [1, 2], [0, 3], [3, 1]], - [[2, 2], [3, 2], [2, 3], [3, 3]], - [[2, 2], [3, 2], [2, 1], [3, 3]], - [[2, 4], [3, 4], [2, 5], [3, 5]], - [[2, 0], [3, 4], [2, 5], [3, 5]], - [[0, 4], [1, 4], [0, 5], [1, 5]], - [[0, 4], [3, 0], [0, 5], [1, 5]], - [[0, 2], [3, 2], [0, 3], [3, 3]], - [[0, 2], [1, 2], [0, 5], [1, 5]], - [[0, 4], [3, 4], [0, 5], [3, 5]], - [[2, 2], [3, 2], [2, 5], [3, 5]], - [[0, 2], [3, 2], [0, 5], [3, 5]], - [[0, 0], [1, 0], [0, 1], [1, 1]] + [ + [2, 4], + [1, 4], + [2, 3], + [1, 3] + ], + [ + [2, 0], + [1, 4], + [2, 3], + [1, 3] + ], + [ + [2, 4], + [3, 0], + [2, 3], + [1, 3] + ], + [ + [2, 0], + [3, 0], + [2, 3], + [1, 3] + ], + [ + [2, 4], + [1, 4], + [2, 3], + [3, 1] + ], + [ + [2, 0], + [1, 4], + [2, 3], + [3, 1] + ], + [ + [2, 4], + [3, 0], + [2, 3], + [3, 1] + ], + [ + [2, 0], + [3, 0], + [2, 3], + [3, 1] + ], + [ + [2, 4], + [1, 4], + [2, 1], + [1, 3] + ], + [ + [2, 0], + [1, 4], + [2, 1], + [1, 3] + ], + [ + [2, 4], + [3, 0], + [2, 1], + [1, 3] + ], + [ + [2, 0], + [3, 0], + [2, 1], + [1, 3] + ], + [ + [2, 4], + [1, 4], + [2, 1], + [3, 1] + ], + [ + [2, 0], + [1, 4], + [2, 1], + [3, 1] + ], + [ + [2, 4], + [3, 0], + [2, 1], + [3, 1] + ], + [ + [2, 0], + [3, 0], + [2, 1], + [3, 1] + ], + [ + [0, 4], + [1, 4], + [0, 3], + [1, 3] + ], + [ + [0, 4], + [3, 0], + [0, 3], + [1, 3] + ], + [ + [0, 4], + [1, 4], + [0, 3], + [3, 1] + ], + [ + [0, 4], + [3, 0], + [0, 3], + [3, 1] + ], + [ + [2, 2], + [1, 2], + [2, 3], + [1, 3] + ], + [ + [2, 2], + [1, 2], + [2, 3], + [3, 1] + ], + [ + [2, 2], + [1, 2], + [2, 1], + [1, 3] + ], + [ + [2, 2], + [1, 2], + [2, 1], + [3, 1] + ], + [ + [2, 4], + [3, 4], + [2, 3], + [3, 3] + ], + [ + [2, 4], + [3, 4], + [2, 1], + [3, 3] + ], + [ + [2, 0], + [3, 4], + [2, 3], + [3, 3] + ], + [ + [2, 0], + [3, 4], + [2, 1], + [3, 3] + ], + [ + [2, 4], + [1, 4], + [2, 5], + [1, 5] + ], + [ + [2, 0], + [1, 4], + [2, 5], + [1, 5] + ], + [ + [2, 4], + [3, 0], + [2, 5], + [1, 5] + ], + [ + [2, 0], + [3, 0], + [2, 5], + [1, 5] + ], + [ + [0, 4], + [3, 4], + [0, 3], + [3, 3] + ], + [ + [2, 2], + [1, 2], + [2, 5], + [1, 5] + ], + [ + [0, 2], + [1, 2], + [0, 3], + [1, 3] + ], + [ + [0, 2], + [1, 2], + [0, 3], + [3, 1] + ], + [ + [2, 2], + [3, 2], + [2, 3], + [3, 3] + ], + [ + [2, 2], + [3, 2], + [2, 1], + [3, 3] + ], + [ + [2, 4], + [3, 4], + [2, 5], + [3, 5] + ], + [ + [2, 0], + [3, 4], + [2, 5], + [3, 5] + ], + [ + [0, 4], + [1, 4], + [0, 5], + [1, 5] + ], + [ + [0, 4], + [3, 0], + [0, 5], + [1, 5] + ], + [ + [0, 2], + [3, 2], + [0, 3], + [3, 3] + ], + [ + [0, 2], + [1, 2], + [0, 5], + [1, 5] + ], + [ + [0, 4], + [3, 4], + [0, 5], + [3, 5] + ], + [ + [2, 2], + [3, 2], + [2, 5], + [3, 5] + ], + [ + [0, 2], + [3, 2], + [0, 5], + [3, 5] + ], + [ + [0, 0], + [1, 0], + [0, 1], + [1, 1] + ] ]; public static WALL_AUTOTILE_TABLE = [ - [[2, 2], [1, 2], [2, 1], [1, 1]], - [[0, 2], [1, 2], [0, 1], [1, 1]], - [[2, 0], [1, 0], [2, 1], [1, 1]], - [[0, 0], [1, 0], [0, 1], [1, 1]], - [[2, 2], [3, 2], [2, 1], [3, 1]], - [[0, 2], [3, 2], [0, 1], [3, 1]], - [[2, 0], [3, 0], [2, 1], [3, 1]], - [[0, 0], [3, 0], [0, 1], [3, 1]], - [[2, 2], [1, 2], [2, 3], [1, 3]], - [[0, 2], [1, 2], [0, 3], [1, 3]], - [[2, 0], [1, 0], [2, 3], [1, 3]], - [[0, 0], [1, 0], [0, 3], [1, 3]], - [[2, 2], [3, 2], [2, 3], [3, 3]], - [[0, 2], [3, 2], [0, 3], [3, 3]], - [[2, 0], [3, 0], [2, 3], [3, 3]], - [[0, 0], [3, 0], [0, 3], [3, 3]] + [ + [2, 2], + [1, 2], + [2, 1], + [1, 1] + ], + [ + [0, 2], + [1, 2], + [0, 1], + [1, 1] + ], + [ + [2, 0], + [1, 0], + [2, 1], + [1, 1] + ], + [ + [0, 0], + [1, 0], + [0, 1], + [1, 1] + ], + [ + [2, 2], + [3, 2], + [2, 1], + [3, 1] + ], + [ + [0, 2], + [3, 2], + [0, 1], + [3, 1] + ], + [ + [2, 0], + [3, 0], + [2, 1], + [3, 1] + ], + [ + [0, 0], + [3, 0], + [0, 1], + [3, 1] + ], + [ + [2, 2], + [1, 2], + [2, 3], + [1, 3] + ], + [ + [0, 2], + [1, 2], + [0, 3], + [1, 3] + ], + [ + [2, 0], + [1, 0], + [2, 3], + [1, 3] + ], + [ + [0, 0], + [1, 0], + [0, 3], + [1, 3] + ], + [ + [2, 2], + [3, 2], + [2, 3], + [3, 3] + ], + [ + [0, 2], + [3, 2], + [0, 3], + [3, 3] + ], + [ + [2, 0], + [3, 0], + [2, 3], + [3, 3] + ], + [ + [0, 0], + [3, 0], + [0, 3], + [3, 3] + ] ]; public static WATERFALL_AUTOTILE_TABLE = [ - [[2, 0], [1, 0], [2, 1], [1, 1]], - [[0, 0], [1, 0], [0, 1], [1, 1]], - [[2, 0], [3, 0], [2, 1], [3, 1]], - [[0, 0], [3, 0], [0, 1], [3, 1]] + [ + [2, 0], + [1, 0], + [2, 1], + [1, 1] + ], + [ + [0, 0], + [1, 0], + [0, 1], + [1, 1] + ], + [ + [2, 0], + [3, 0], + [2, 1], + [3, 1] + ], + [ + [0, 0], + [3, 0], + [0, 1], + [3, 1] + ] ]; public static isVisibleTile(tileId: number) { @@ -432,27 +772,15 @@ export class Tilemap extends PIXI.Container { } } }; - - /** - * PIXI render method - * - * @method renderCanvas - * @param {Object} pixi renderer - */ - public renderCanvas(renderer: PIXI.CanvasRenderer) { - this._hackRenderer(renderer); - super.renderCanvas(renderer); - } - /** * PIXI render method * * @method renderWebGL * @param {Object} pixi renderer */ - public renderWebGL(renderer: PIXI.WebGLRenderer) { + public render(renderer: PIXI.Renderer) { this._hackRenderer(renderer); - super.renderWebGL(renderer); + super.render(renderer); } /** @@ -576,9 +904,7 @@ export class Tilemap extends PIXI.Container { * @method _hackRenderer * @private */ - protected _hackRenderer( - renderer: PIXI.CanvasRenderer | PIXI.WebGLRenderer - ) { + protected _hackRenderer(renderer: PIXI.Renderer) { let af = this.animationFrame % 4; if (af === 3) { af = 1; diff --git a/ts/core/TilingSprite.ts b/ts/core/TilingSprite.ts index d239b2b..87df7d9 100644 --- a/ts/core/TilingSprite.ts +++ b/ts/core/TilingSprite.ts @@ -1,12 +1,11 @@ import * as PIXI from "pixi.js"; -import { Graphics } from "./Graphics"; +import { Bitmap } from "./Bitmap"; import { Point } from "./Point"; import { Rectangle } from "./Rectangle"; import { Sprite } from "./Sprite"; import { Utils } from "./Utils"; -import { Bitmap } from "./Bitmap"; -export class TilingSprite extends PIXI.extras.TilingSprite { +export class TilingSprite extends PIXI.TilingSprite { /** * The image for the tiling sprite. * @@ -58,15 +57,15 @@ export class TilingSprite extends PIXI.extras.TilingSprite { public constructor(bitmap?: any) { super(new PIXI.Texture(new PIXI.BaseTexture())); this._bitmap = null; - this._width = 0; - this._height = 0; + this.width = 0; + this.height = 0; this._frame = new Rectangle(); this.spriteId = Sprite._counter++; this.origin = new Point(); this.bitmap = bitmap; } - public _renderWebGL(renderer: any) { + public render(renderer: PIXI.Renderer) { if (this._bitmap) { this._bitmap.touch(); } @@ -74,8 +73,8 @@ export class TilingSprite extends PIXI.extras.TilingSprite { if (this._bitmap) { this._bitmap.checkDirty(); } - this._speedUpCustomBlendModes(renderer); - super._renderWebGL(renderer); + // this._speedUpCustomBlendModes(renderer); + super.render(renderer); } } @@ -103,8 +102,8 @@ export class TilingSprite extends PIXI.extras.TilingSprite { public move(x?: number, y?: number, width?: number, height?: number) { this.x = x || 0; this.y = y || 0; - this._width = width || 0; - this._height = height || 0; + this.width = width || 0; + this.height = height || 0; } /** @@ -142,35 +141,35 @@ export class TilingSprite extends PIXI.extras.TilingSprite { frame.height = this._bitmap.height; } this.texture.frame = frame; - this.texture._updateUvs(); + this.texture.updateUvs(); this.tilingTexture = null; } - private _speedUpCustomBlendModes(renderer: PIXI.WebGLRenderer) { - const picture = renderer.plugins.picture; - const blend = this.blendMode; - if (renderer.renderingToScreen && renderer._activeRenderTarget.root) { - if (picture.drawModes[blend]) { - // @ts-ignore - const stage = renderer._lastObjectRendered; - // @ts-ignore - const f = stage._filters; - if (!f || !f[0]) { - setTimeout(function() { - // @ts-ignore - const f = stage._filters; - if (!f || !f[0]) { - stage.filters = [Sprite.voidFilter]; - stage.filterArea = new PIXI.Rectangle( - 0, - 0, - Graphics.width, - Graphics.height - ); - } - }, 0); - } - } - } - } + // private _speedUpCustomBlendModes(renderer: PIXI.Renderer) { + // const picture = renderer.plugins.picture; + // const blend = this.blendMode; + // if (renderer.renderingToScreen && renderer._activeRenderTarget.root) { + // if (picture.drawModes[blend]) { + // // @ts-ignore + // const stage = renderer._lastObjectRendered; + // // @ts-ignore + // const f = stage._filters; + // if (!f || !f[0]) { + // setTimeout(function() { + // // @ts-ignore + // const f = stage._filters; + // if (!f || !f[0]) { + // stage.filters = [Sprite.voidFilter]; + // stage.filterArea = new PIXI.Rectangle( + // 0, + // 0, + // Graphics.width, + // Graphics.height + // ); + // } + // }, 0); + // } + // } + // } + // } } diff --git a/ts/core/ToneSprite.ts b/ts/core/ToneSprite.ts index 84eadb2..bf86cf0 100644 --- a/ts/core/ToneSprite.ts +++ b/ts/core/ToneSprite.ts @@ -1,7 +1,7 @@ import * as PIXI from "pixi.js"; +import { ConfigManager } from "../managers/ConfigManager"; import { Graphics } from "./Graphics"; import { Utils } from "./Utils"; -import { ConfigManager } from "../managers/ConfigManager"; export class ToneSprite extends PIXI.Container { private _red: number; @@ -84,13 +84,4 @@ export class ToneSprite extends PIXI.Container { this._blue = Utils.clamp(Math.round(b || 0), -255, 255); this._gray = Utils.clamp(Math.round(gray || 0), 0, 255); } - - /** - * @method _renderWebGL - * @param {Object} renderSession - * @private - */ - public _renderWebGL(renderer: PIXI.WebGLRenderer) { - // Not supported - } } diff --git a/ts/core/TouchInput.ts b/ts/core/TouchInput.ts index 1ce2fb3..8147ec0 100644 --- a/ts/core/TouchInput.ts +++ b/ts/core/TouchInput.ts @@ -13,6 +13,8 @@ interface TouchInputEvent { declare let window: any; export class TouchInput { + static _mouseOverX: number; + static _mouseOverY: number; public static get wheelX(): number { return this._wheelX; } @@ -186,6 +188,8 @@ export class TouchInput { const y = Graphics.pageToCanvasY(event.pageY); this.onMove(x, y); } + this._mouseOverX = Graphics.pageToCanvasX(event.pageX); + this._mouseOverY = Graphics.pageToCanvasY(event.pageY); } private static onMouseUp(event: MouseEvent) { diff --git a/ts/core/Window.ts b/ts/core/Window.ts index 5428f46..f199136 100644 --- a/ts/core/Window.ts +++ b/ts/core/Window.ts @@ -4,8 +4,19 @@ import { Point } from "./Point"; import { Rectangle } from "./Rectangle"; import { Sprite } from "./Sprite"; import { Utils } from "./Utils"; +import { ConfigManager } from "../managers/ConfigManager"; export class Window extends PIXI.Container { + /** + * The maximum width a window can be without having to handle widescreen formatting + */ + public static get maxWidthOfWindow() { + return Math.min( + (ConfigManager.currentResolution.heightPx / 3) * 4, + ConfigManager.currentResolution.widthPx + ); + } + public origin: Point; public active: boolean; public downArrowVisible: boolean; @@ -120,7 +131,7 @@ export class Window extends PIXI.Container { * @param {Number} width The width of the window * @param {Number} height The height of the window */ - public move(x, y, width, height) { + public move(x: number, y: number, width: number, height: number) { this.x = x || 0; this.y = y || 0; if (this._width !== width || this._height !== height) { @@ -157,7 +168,7 @@ export class Window extends PIXI.Container { * @param {Number} width The width of the cursor * @param {Number} height The height of the cursor */ - public setCursorRect(x, y, width, height) { + public setCursorRect(x: number, y: number, width: number, height: number) { const cx = Math.floor(x || 0); const cy = Math.floor(y || 0); const cw = Math.floor(width || 0); @@ -185,7 +196,7 @@ export class Window extends PIXI.Container { * @param {Number} g The green value in the range (-255, 255) * @param {Number} b The blue value in the range (-255, 255) */ - public setTone(r, g, b) { + public setTone(r: number, g: number, b: number) { const tone = this._colorTone; if (r !== tone[0] || g !== tone[1] || b !== tone[2]) { this._colorTone = [r, g, b]; @@ -200,7 +211,7 @@ export class Window extends PIXI.Container { * @param {Object} child The child to add * @return {Object} The child that was added */ - public addChildToBack(child) { + public addChildToBack(child: Sprite) { const containerIndex = this.children.indexOf( this._windowSpriteContainer ); diff --git a/ts/core/WindowLayer.ts b/ts/core/WindowLayer.ts index 26dd9ad..78e75c8 100644 --- a/ts/core/WindowLayer.ts +++ b/ts/core/WindowLayer.ts @@ -1,4 +1,5 @@ import * as PIXI from "pixi.js"; +import { Window } from "./Window"; export class WindowLayer extends PIXI.Container { /** @@ -31,7 +32,6 @@ export class WindowLayer extends PIXI.Container { public static voidFilter = new PIXI.filters.AlphaFilter(); - private _windowRect: any; private _width: number; private _height: number; private _windowMask: PIXI.Graphics; @@ -45,8 +45,6 @@ export class WindowLayer extends PIXI.Container { this._windowMask.beginFill(0xffffff, 1); this._windowMask.drawRect(0, 0, 0, 0); this._windowMask.endFill(); - // @ts-ignore - this._windowRect = this._windowMask.graphicsData[0].shape; this.filterArea = new PIXI.Rectangle(); this.filters = [WindowLayer.voidFilter]; @@ -88,11 +86,11 @@ export class WindowLayer extends PIXI.Container { } /** - * @method _renderWebGL + * @method _render * @param {Object} renderSession * @private */ - public renderWebGL(renderer: PIXI.WebGLRenderer) { + public render(renderer: PIXI.Renderer) { if (!this.visible || !this.renderable) { return; } @@ -101,46 +99,42 @@ export class WindowLayer extends PIXI.Container { return; } - renderer.flush(); - // @ts-ignore - this.filterArea.copy(this); - // @ts-ignore Bad PIXI typing - renderer.filterManager.pushFilter(this, this.filters); - renderer.currentRenderer.start(); + renderer.batch.flush(); + this.filterArea.copyFrom( + new PIXI.Rectangle(this.x, this.y, this.width, this.height) + ); + renderer.filter.push(this, this.filters); + renderer.batch.currentRenderer.start(); const shift = new PIXI.Point(); - const rt = renderer._activeRenderTarget; - const projectionMatrix = rt.projectionMatrix; + const projection = renderer.projection; + const projectionMatrix = projection.projectionMatrix; shift.x = Math.round( - ((projectionMatrix.tx + 1) / 2) * rt.sourceFrame.width + ((projectionMatrix.tx + 1) / 2) * projection.sourceFrame.width ); shift.y = Math.round( - ((projectionMatrix.ty + 1) / 2) * rt.sourceFrame.height + ((projectionMatrix.ty + 1) / 2) * projection.sourceFrame.height ); - for (let i = 0; i < this.children.length; i++) { - const child = this.children[i]; - // @ts-ignore + for (const child of this.children as Window[]) { if (child._isWindow && child.visible && child.openness > 0) { this._maskWindow(child, shift); - // @ts-ignore Another bad typing - renderer.maskManager.pushScissorMask(this, this._windowMask); - renderer.clear(); - renderer.maskManager.popScissorMask(); - renderer.currentRenderer.start(); - child.renderWebGL(renderer); - renderer.currentRenderer.flush(); + renderer.mask.push(child, new PIXI.MaskData(this._windowMask)); + renderer.mask.pop(child); + renderer.batch.currentRenderer.start(); + child.render(renderer); + renderer.batch.currentRenderer.flush(); } } - renderer.flush(); - renderer.filterManager.popFilter(); - renderer.maskManager.popScissorMask(); + renderer.batch.flush(); + renderer.filter.pop(); + renderer.mask.pop(this); for (let j = 0; j < this.children.length; j++) { - // @ts-ignore - if (!this.children[j]._isWindow) { - this.children[j].renderWebGL(renderer); + const child = this.children[j] as Window; + if (!child._isWindow) { + this.children[j].render(renderer); } } } @@ -151,17 +145,14 @@ export class WindowLayer extends PIXI.Container { * @private */ private _maskWindow(window, shift) { - // @ts-ignore - this._windowMask._currentBounds = null; - this._windowMask.boundsDirty = Number(true); - const rect = this._windowRect; - rect.x = this.x + shift.x + window.x; - rect.y = + this._windowMask.clear(); + this._windowMask.x = this.x + shift.x + window.x; + this._windowMask.y = this.x + shift.y + window.y + (window.height / 2) * (1 - window._openness / 255); - rect.width = window.width; - rect.height = (window.height * window._openness) / 255; + this._windowMask.width = window.width; + this._windowMask.height = (window.height * window._openness) / 255; } } diff --git a/ts/globals.d.ts b/ts/globals.d.ts index 3d72115..27265b2 100644 --- a/ts/globals.d.ts +++ b/ts/globals.d.ts @@ -1,25 +1,27 @@ /** - * Global variable declaration and global type modifications + * Global variable declaration and global type modifications. + * * Typescript does not allow for d.ts files that merge types to use ES6 imports! + * * Instead, use import("") syntax for type imports. */ -declare let $plugins: any; -declare let $dataActors: any; -declare let $dataClasses: any; -declare let $dataSkills: any; -declare let $dataItems: any; -declare let $dataWeapons: any; -declare let $dataArmors: any; -declare let $dataEnemies: any; -declare let $dataTroops: any; -declare let $dataStates: any; -declare let $dataAnimations: any; -declare let $dataTilesets: any; -declare let $dataCommonEvents: any; -declare let $dataSystem: any; -declare let $dataMapInfos: any; -declare let $dataMap: any; +declare let $plugins: import("./interfaces/IPlugin").IPlugin[]; +declare let $dataActors: import("./interfaces/Actor").Actor[]; +declare let $dataClasses: import("./interfaces/Class").Class[]; +declare let $dataSkills: import("./interfaces/Skill").Skill[]; +declare let $dataItems: import("./interfaces/Item").Item[]; +declare let $dataWeapons: import("./interfaces/Weapon").Weapon[]; +declare let $dataArmors: import("./interfaces/Armor").Armor[]; +declare let $dataEnemies: import("./interfaces/Enemy").Enemy[]; +declare let $dataTroops: import("./interfaces/Troop").Troop[]; +declare let $dataStates: import("./interfaces/State").State[]; +declare let $dataAnimations: import("./interfaces/Animation").Animation[]; +declare let $dataTilesets: import("./interfaces/Tileset").Tileset[]; +declare let $dataCommonEvents: import("./interfaces/CommonEvent").CommonEvent[]; +declare let $dataSystem: import("./interfaces/System").System; +declare let $dataMapInfos: import("./interfaces/MapInfo").MapInfo[]; +declare let $dataMap: import("./interfaces/Map").Map; declare let $gameTemp: import("./objects/Game_Temp").Game_Temp; declare let $gameSystem: import("./objects/Game_System").Game_System; declare let $gameScreen: import("./objects/Game_Screen").Game_Screen; diff --git a/ts/interfaces/Actor.ts b/ts/interfaces/Actor.ts index 55daaa6..0203e61 100644 --- a/ts/interfaces/Actor.ts +++ b/ts/interfaces/Actor.ts @@ -1,6 +1,15 @@ import { Trait } from "./Trait"; -export interface Actor { +export interface Actor extends YanflyBaseParams { + reflectAnimationId: number; + spriteCannotMove: any; + anchorX: any; + anchorY: any; + plusParams: any; + rateParams: any; + flatParams: any; + maxParams: any; + minParams: any; id: number; battlerName: string; characterIndex: 0; diff --git a/ts/interfaces/Armor.ts b/ts/interfaces/Armor.ts index 328a963..002cca5 100644 --- a/ts/interfaces/Armor.ts +++ b/ts/interfaces/Armor.ts @@ -1,6 +1,6 @@ import { Trait } from "./Trait"; -export interface Armor { +export interface Armor extends YanflyBaseParams { id: number; atypeId: number; description: string; diff --git a/ts/interfaces/Class.ts b/ts/interfaces/Class.ts index e6967c4..2901eb5 100644 --- a/ts/interfaces/Class.ts +++ b/ts/interfaces/Class.ts @@ -1,6 +1,15 @@ import { Trait } from "./Trait"; -export interface Class { +export interface Class extends YanflyBaseParams { + reflectAnimationId: number; + spriteCannotMove: any; + anchorX: any; + anchorY: any; + plusParams: any; + rateParams: any; + flatParams: any; + maxParams: any; + minParams: any; id: number; expParams: number[]; traits: Trait[]; diff --git a/ts/interfaces/Enemy.ts b/ts/interfaces/Enemy.ts index 81e4f5e..389c19e 100644 --- a/ts/interfaces/Enemy.ts +++ b/ts/interfaces/Enemy.ts @@ -1,6 +1,9 @@ import { Trait } from "./Trait"; -export interface Enemy { +export interface Enemy extends YanflyBaseParams { + attackAnimationId: any; + reflectAnimationId: number; + spriteCannotMove: any; id: number; actions: EnemyAction[]; battlerHue: number; diff --git a/ts/interfaces/Item.ts b/ts/interfaces/Item.ts index b7dc46c..168b29a 100644 --- a/ts/interfaces/Item.ts +++ b/ts/interfaces/Item.ts @@ -1,4 +1,4 @@ -export interface Item { +export interface Item extends YanflyBaseParams { id: number; animationId: number; consumable: boolean; @@ -17,6 +17,7 @@ export interface Item { speed: number; successRate: number; tpGain: number; + params: any[]; } interface Damage { diff --git a/ts/interfaces/Skill.ts b/ts/interfaces/Skill.ts index e9a963f..2d4bcf7 100644 --- a/ts/interfaces/Skill.ts +++ b/ts/interfaces/Skill.ts @@ -1,4 +1,4 @@ -export interface Skill { +export interface Skill extends YanflyBaseParams { id: number; animationId: number; damage: Damage; @@ -21,6 +21,7 @@ export interface Skill { successRate: number; tpCost: number; tpGain: number; + params: any[]; } interface Effect { diff --git a/ts/interfaces/State.ts b/ts/interfaces/State.ts index a8e468a..f78a034 100644 --- a/ts/interfaces/State.ts +++ b/ts/interfaces/State.ts @@ -1,6 +1,11 @@ import { Trait } from "./Trait"; -export interface State { +export interface State extends YanflyBaseParams { + anchorX: any; + anchorY: any; + reflectAnimationId: number; + spriteCannotMove: any; + reapplyRules: number; id: number; autoRemovalTiming: number; chanceByDamage: number; diff --git a/ts/interfaces/System.ts b/ts/interfaces/System.ts index 7a235fc..f7614ad 100644 --- a/ts/interfaces/System.ts +++ b/ts/interfaces/System.ts @@ -1,6 +1,9 @@ import { Audio } from "./Audio"; export interface System { + titleBgm(titleBgm: any); + battleBgm: any; + encryptionKey: any; airship: Airship; armorTypes: string[]; attackMotions: AttackMotion[]; @@ -122,6 +125,7 @@ interface AttackMotion { } interface Airship { + bgm: any; Audio: Audio; characterIndex: number; characterName: string; diff --git a/ts/interfaces/Weapon.ts b/ts/interfaces/Weapon.ts index d4754aa..6889d87 100644 --- a/ts/interfaces/Weapon.ts +++ b/ts/interfaces/Weapon.ts @@ -1,6 +1,6 @@ import { Trait } from "./Trait"; -export interface Weapon { +export interface Weapon extends YanflyBaseParams { id: number; animationId: number; description: string; diff --git a/ts/interfaces/YanflyBaseParams.ts b/ts/interfaces/YanflyBaseParams.ts new file mode 100644 index 0000000..9b0f5c0 --- /dev/null +++ b/ts/interfaces/YanflyBaseParams.ts @@ -0,0 +1,10 @@ +interface YanflyBaseParams { + plusParams?: any[]; + rateParams?: any[]; + flatParams?: any[]; + maxParams?: any[]; + minParams?: any[]; + plusXParams?: any[]; + rateXParams?: any[]; + flatXParams?: any[]; +} diff --git a/ts/main.ts b/ts/main.ts index a34df9e..b90c195 100644 --- a/ts/main.ts +++ b/ts/main.ts @@ -1,24 +1,15 @@ +import * as PIXI from "pixi.js"; import "source-map-support/register"; - -import "pixi.js"; - -import "pixi-picture"; -import "pixi-tilemap"; - import { PluginManager } from "./managers/PluginManager"; import { SceneManager } from "./managers/SceneManager"; -import { Scene_Boot } from "./scenes/Scene_Boot"; -declare const $plugins; +PluginManager.setup($plugins); // ============================================================================= // main.js // ============================================================================= -PIXI.glCore.VertexArrayObject.FORCE_NATIVE = true; -PIXI.settings.GC_MODE = PIXI.GC_MODES.AUTO; -PIXI.tilemap.TileRenderer.DO_CLEAR = true; - +window.PIXI = PIXI; window.$dataActors = null; window.$dataClasses = null; window.$dataSkills = null; @@ -49,8 +40,6 @@ window.$gameMap = null; window.$gamePlayer = null; window.$testEvent = null; -PluginManager.setup($plugins); - window.onload = function() { - SceneManager.run(Scene_Boot); + SceneManager.run(require("./scenes/Scene_Boot").Scene_Boot); }; diff --git a/ts/managers/BattleManager.ts b/ts/managers/BattleManager.ts index 3a792af..969c088 100644 --- a/ts/managers/BattleManager.ts +++ b/ts/managers/BattleManager.ts @@ -1,7 +1,13 @@ +/* eslint-disable standard/computed-property-even-spacing */ +import { JsonEx } from "../core/JsonEx"; import { Utils } from "../core/Utils"; import { Game_Action } from "../objects/Game_Action"; +import { Game_Actor } from "../objects/Game_Actor"; import { Game_Battler } from "../objects/Game_Battler"; +import { Game_Enemy } from "../objects/Game_Enemy"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; import { Scene_Gameover } from "../scenes/Scene_Gameover"; +import { Sprite_Battler } from "../sprites/Sprite_Battler"; import { AudioManager } from "./AudioManager"; import { SceneManager } from "./SceneManager"; import { SoundManager } from "./SoundManager"; @@ -14,28 +20,61 @@ interface Rewards { } export abstract class BattleManager { - public static _canEscape: any; - public static _canLose: any; - public static _phase: string; - public static _battleTest: boolean; - public static _eventCallback: any; - public static _preemptive: boolean; - public static _surprise: boolean; - public static _actorIndex: number; - public static _actionForcedBattler: any; - public static _mapBgm: any; - public static _mapBgs: any; - public static _actionBattlers: any[]; - public static _subject: any; - public static _action: any; - public static _targets: any[]; - public static _logWindow: any; - public static _statusWindow: any; - public static _spriteset: any; - public static _escapeRatio: number; - public static _escaped: boolean; - public static _rewards: Rewards; - public static _turnForced: boolean; + private static _canEscape: any; + private static _canLose: any; + private static _phase: string; + private static _battleTest: boolean; + private static _eventCallback: any; + private static _preemptive: boolean; + private static _surprise: boolean; + private static _actorIndex: number; + private static _actionForcedBattler: any; + private static _mapBgm: any; + private static _mapBgs: any; + private static _actionBattlers: any[]; + private static _subject: Game_Battler; + private static _action: any; + private static _targets: any[]; + private static _logWindow: any; + private static _statusWindow: any; + private static _spriteset: any; + private static _escapeRatio: number; + private static _escaped: boolean; + private static _rewards: Rewards; + private static _turnForced: boolean; + private static _forceSelection: boolean; + private static _allSelection: boolean; + private static _victoryPhase: boolean; + private static _forceActionQueue: any[]; + private static _escapeFailBoost: any; + private static _timeBasedStates: any; + private static _timeBasedBuffs: any; + private static _registeredSprites: any; + private static _spritePriority: any; + private static _processTurn: boolean; + private static _windowLayer: any; + private static _enteredEndPhase: boolean; + private static _performedBattlers: any; + private static _processingForcedAction: any; + private static _allTargets: any; + private static _individualTargets: any; + private static _phaseSteps: string[]; + private static _returnPhase: string; + private static _actionList: any[]; + private static _preForcePhase: string; + private static _target: any; + private static _conditionFlags: any; + private static _trueFlags: any; + private static _actSeq: any; + private static _bypassMoveToStartLocation: boolean; + + public static get bypassMoveToStartLocation(): boolean { + return BattleManager._bypassMoveToStartLocation; + } + + public static get processingTurn(): boolean { + return BattleManager._processTurn; + } public static setup(troopId, canEscape, canLose) { this.initMembers(); @@ -73,6 +112,10 @@ export abstract class BattleManager { items: null }; this._turnForced = false; + this._forceSelection = false; + this._allSelection = false; + this._victoryPhase = false; + this._forceActionQueue = []; } public static isBattleTest() { @@ -95,6 +138,10 @@ export abstract class BattleManager { this._statusWindow = statusWindow; } + public static get spriteset(): any { + return BattleManager._spriteset; + } + public static setSpriteset(spriteset) { this._spriteset = spriteset; } @@ -143,7 +190,30 @@ export abstract class BattleManager { } public static makeEscapeRatio() { - this._escapeRatio = (0.5 * $gameParty.agility()) / $gameTroop.agility(); + if (this.isDTB()) { + let code = Yanfly.Param.BECEscRatio; + try { + this._escapeRatio = eval(code); + } catch (e) { + this._escapeRatio = 0; + Yanfly.Util.displayError(e, code, "ESCAPE RATIO FORMULA ERROR"); + } + code = Yanfly.Param.BECEscFail; + try { + this._escapeFailBoost = eval(code); + } catch (e) { + this._escapeFailBoost = 0; + Yanfly.Util.displayError( + e, + code, + "ESCAPE FAIL BOOST FORMULA ERROR" + ); + } + } else { + this._escapeFailBoost = 0.1; + this._escapeRatio = + (0.5 * $gameParty.agility()) / $gameTroop.agility(); + } } public static update() { @@ -158,6 +228,15 @@ export abstract class BattleManager { case "action": this.updateAction(); break; + case "phaseChange": + this.updatePhase(); + break; + case "actionList": + this.updateActionList(); + break; + case "actionTargetList": + this.updateActionTargetList(); + break; case "turnEnd": this.updateTurnEnd(); break; @@ -169,10 +248,13 @@ export abstract class BattleManager { } public static updateEvent() { + if (this._processingForcedAction) return false; switch (this._phase) { case "start": case "turn": case "turnEnd": + case "actionList": + case "actionTargetList": if (this.isActionForced()) { this.processForcedAction(); return true; @@ -246,18 +328,6 @@ export abstract class BattleManager { this.changeActor(-1, ""); } - public static changeActor(newActorIndex, lastActorActionState) { - const lastActor = this.actor(); - this._actorIndex = newActorIndex; - const newActor = this.actor(); - if (lastActor) { - lastActor.setActionState(lastActorActionState); - } - if (newActor) { - newActor.setActionState("inputting"); - } - } - public static startBattle() { this._phase = "start"; $gameSystem.onBattleStart(); @@ -266,24 +336,6 @@ export abstract class BattleManager { this.displayStartMessages(); } - public static displayStartMessages() { - $gameTroop.enemyNames().forEach(function(name) { - $gameMessage.add(Utils.format(TextManager.emerge, name)); - }); - if (this._preemptive) { - $gameMessage.add( - Utils.format(TextManager.preemptive, $gameParty.name()) - ); - } else if (this._surprise) { - $gameMessage.add( - Utils.format(TextManager.surprise, $gameParty.name()) - ); - } - $gameTroop.members().forEach(function(enemy) { - enemy.recoverAll(); - }); - } - public static startInput() { this._phase = "input"; $gameParty.makeActions(); @@ -307,7 +359,7 @@ export abstract class BattleManager { break; } } - } while (!this.actor().canInput()); + } while (this.actor() && !this.actor().canInput()); } public static selectPreviousCommand() { @@ -318,7 +370,7 @@ export abstract class BattleManager { return; } } - } while (!this.actor().canInput()); + } while (this.actor() && !this.actor().canInput()); } public static refreshStatus() { @@ -326,12 +378,17 @@ export abstract class BattleManager { } public static startTurn() { + this._enteredEndPhase = false; this._phase = "turn"; this.clearActor(); $gameTroop.increaseTurn(); + $gameParty.onTurnStart(); + $gameTroop.onTurnStart(); + this._performedBattlers = []; this.makeActionOrders(); $gameParty.requestMotionRefresh(); this._logWindow.startTurn(); + this._subject = this.getNextSubject(); } public static updateTurn() { @@ -347,6 +404,7 @@ export abstract class BattleManager { } public static processTurn() { + this._processTurn = true; const subject = this._subject; const action = subject.currentAction(); if (action) { @@ -363,9 +421,18 @@ export abstract class BattleManager { this._logWindow.displayRegeneration(subject); this._subject = this.getNextSubject(); } + this._processTurn = false; } public static endTurn() { + if (this.isTurnBased() && this._spriteset.isPopupPlaying()) return; + if (this.isTurnBased() && this._enteredEndPhase) { + this._phase = "turnEnd"; + this._preemptive = false; + this._surprise = false; + return; + } + this._enteredEndPhase = true; this._phase = "turnEnd"; this._preemptive = false; this._surprise = false; @@ -378,6 +445,7 @@ export abstract class BattleManager { if (this.isForcedTurn()) { this._turnForced = false; } + BattleManager.refreshAllMembers(); } public static isForcedTurn() { @@ -389,17 +457,30 @@ export abstract class BattleManager { } public static getNextSubject() { - while (true) { - const battler = this._actionBattlers.shift(); - if (!battler) { - return null; + // if ($gameTroop.turnCount() <= 0) return; + this._performedBattlers = this._performedBattlers || []; + this.makeActionOrders(); + for (;;) { + const battlerArray = []; + for (let i = 0; i < this._actionBattlers.length; ++i) { + const obj = this._actionBattlers[i]; + if (!this._performedBattlers.includes(obj)) + battlerArray.push(obj); } + this._actionBattlers = battlerArray; + const battler = this._actionBattlers.shift(); + if (!battler) return null; if (battler.isBattleMember() && battler.isAlive()) { + this.pushPerformedBattler(battler); return battler; } } } + public static pushPerformedBattler(battler: any) { + this._performedBattlers.push(battler); + } + public static allBattleMembers(): Game_Battler[] { return [...$gameParty.members(), ...$gameTroop.members()]; } @@ -423,15 +504,22 @@ export abstract class BattleManager { public static startAction() { const subject = this._subject; + if (!subject) return this.endAction(); const action = subject.currentAction(); - const targets = action.makeTargets(); - this._phase = "action"; this._action = action; - this._targets = targets; - subject.useItem(action.item()); + if (!this._action) return this.endAction(); + if (!this._action.item()) return this.endAction(); + const targets = action.makeTargets(); + this.setTargets(targets); + this._allTargets = targets.slice(); + this._individualTargets = targets.slice(); + this._phase = "phaseChange"; + this._phaseSteps = ["setup", "whole", "target", "follow", "finish"]; + this._returnPhase = ""; + this._actionList = []; + subject.useItem(this._action.item()); this._action.applyGlobal(); - this.refreshStatus(); - this._logWindow.startAction(subject, action, targets); + this._logWindow.startAction(this._subject, this._action, this._targets); } public static updateAction() { @@ -439,27 +527,41 @@ export abstract class BattleManager { if (target) { this.invokeAction(this._subject, target); } else { - this.endAction(); + if (this._returnPhase === "target") { + this.setTargets([this._individualTargets[0]]); + this._phase = "actionTargetList"; + } else { + this.setTargets(this._allTargets.slice()); + this._phase = "actionList"; + } } } public static endAction() { + if (this._subject) { + this._subject.onAllActionsEnd(); + } + if (this._processingForcedAction) { + this._subject.removeCurrentAction(); + this._phase = this._preForcePhase; + } + this._processingForcedAction = false; + if (this.loadPreForceActionSettings()) return; this._logWindow.endAction(this._subject); this._phase = "turn"; } public static invokeAction(subject, target) { - this._logWindow.push("pushBaseLine"); - if (Math.random() < this._action.itemCnt(target)) { - this.invokeCounterAttack(subject, target); - } else if (Math.random() < this._action.itemMrf(target)) { + if (!Yanfly.Param.BECOptSpeed) this._logWindow.push("pushBaseLine"); + if (Math.random() < this._action.itemMrf(target)) { this.invokeMagicReflection(subject, target); + } else if (Math.random() < this._action.itemCnt(target)) { + this.invokeCounterAttack(subject, target); } else { this.invokeNormalAction(subject, target); } - subject.setLastTarget(target); - this._logWindow.push("popBaseLine"); - this.refreshStatus(); + if (subject) subject.setLastTarget(target); + if (!Yanfly.Param.BECOptSpeed) this._logWindow.push("popBaseLine"); } public static invokeNormalAction(subject, target) { @@ -468,12 +570,16 @@ export abstract class BattleManager { this._logWindow.displayActionResults(subject, realTarget); } - public static invokeCounterAttack(subject, target) { + public static invokeCounterAttack( + subject: Game_Battler, + target: Game_Battler + ) { const action = new Game_Action(target); + this._logWindow.displayCounter(target); action.setAttack(); action.apply(subject); - this._logWindow.displayCounter(target); this._logWindow.displayActionResults(target, subject); + if (subject.isDead()) subject.performCollapse(); } public static invokeMagicReflection(subject, target) { @@ -481,6 +587,7 @@ export abstract class BattleManager { this._logWindow.displayReflection(target); this._action.apply(subject); this._logWindow.displayActionResults(target, subject); + if (subject.isDead()) subject.performCollapse(); } public static applySubstitute(target) { @@ -503,6 +610,9 @@ export abstract class BattleManager { } public static forceAction(battler) { + if (this._subject) this._subject.clearResult(); + this.createForceActionFailSafes(); + this.savePreForceActionSettings(); this._actionForcedBattler = battler; const index = this._actionBattlers.indexOf(battler); if (index >= 0) { @@ -512,6 +622,8 @@ export abstract class BattleManager { public static processForcedAction() { if (this._actionForcedBattler) { + this._preForcePhase = this._phase; + this._processingForcedAction = true; this._turnForced = true; this._subject = this._actionForcedBattler; this._actionForcedBattler = null; @@ -525,7 +637,12 @@ export abstract class BattleManager { } public static checkBattleEnd() { - if (this._phase) { + if (this._phase === "actionList") return false; + else if (this._phase === "actionTargetList") return false; + else if (this._phase === "action") return false; + else if (this._phase === "phaseChange") return false; + else if ($gameTroop.isEventRunning()) return false; + else if (this._phase) { if (this.checkAbort()) { return true; } else if ($gameParty.isAllDead()) { @@ -549,6 +666,9 @@ export abstract class BattleManager { } public static processVictory() { + this._logWindow.clear(); + this._victoryPhase = true; + if (this._windowLayer) this._windowLayer.x = 0; $gameParty.removeBattleStates(); $gameParty.performVictory(); this.playVictoryMe(); @@ -563,17 +683,18 @@ export abstract class BattleManager { public static processEscape() { $gameParty.performEscape(); SoundManager.playEscape(); - const success = this._preemptive + let success = this._preemptive ? true : Math.random() < this._escapeRatio; + if ($gamePlayer.isDebugThrough()) success = true; if (success) { - $gameParty.removeBattleStates(); + $gameParty.performEscapeSuccess(); this.displayEscapeSuccessMessage(); this._escaped = true; this.processAbort(); } else { this.displayEscapeFailureMessage(); - this._escapeRatio += 0.1; + this._escapeRatio += this._escapeFailBoost; $gameParty.clearActions(); this.startTurn(); } @@ -717,4 +838,988 @@ export abstract class BattleManager { $gameParty.gainItem(item, 1); }); } + + public static isBattleSystem(value) { + return value.toLowerCase() === $gameSystem.getBattleSystem(); + } + + public static isDTB() { + return this.isBattleSystem("dtb"); + } + + public static isTurnBased() { + if (this.isDTB()) return true; + return false; + } + + public static isTickBased() { + return !this.isTurnBased(); + } + + public static tickRate() { + return 1; + } + + public static forceSelection() { + this._forceSelection = true; + } + + public static isForceSelection() { + return this._forceSelection; + } + + public static resetSelection() { + this._forceSelection = false; + } + + public static startAllSelection() { + this._allSelection = true; + } + + public static isAllSelection() { + return this._allSelection && this.isInputting(); + } + + public static stopAllSelection() { + this._allSelection = false; + } + + public static timeBasedStates() { + if (!$gameParty.inBattle()) return false; + if (this.isTurnBased()) return false; + if (this._timeBasedStates !== undefined) return this._timeBasedStates; + this._timeBasedStates = Yanfly.Param.BECTimeStates; + return this._timeBasedStates; + } + + public static timeBasedBuffs() { + if (!$gameParty.inBattle()) return false; + if (this.isTurnBased()) return false; + if (this._timeBasedBuffs !== undefined) return this._timeBasedBuffs; + this._timeBasedBuffs = Yanfly.Param.BECTimeBuffs; + return this._timeBasedBuffs; + } + + public static displayStartMessages() { + if (Yanfly.Param.BECEmergeText) { + $gameTroop.enemyNames().forEach(function(name) { + $gameMessage.add(Utils.format(TextManager.emerge, name)); + }); + } + if (this._preemptive && Yanfly.Param.BECPreEmpText) { + $gameMessage.add( + Utils.format(TextManager.preemptive, $gameParty.name()) + ); + } else if (this._surprise && Yanfly.Param.BECSurpText) { + $gameMessage.add( + Utils.format(TextManager.surprise, $gameParty.name()) + ); + } + } + + public static registerSprite( + battler: Game_Battler, + sprite: Sprite_Battler + ) { + let id = 0; + if (!this._registeredSprites) this._registeredSprites = {}; + if (battler.isActor()) id = 100000 + (battler as Game_Actor).actorId(); + if (battler.isEnemy()) id = 200000 + (battler as Game_Enemy).index(); + this._registeredSprites[id] = sprite; + } + + public static getSprite(battler: Game_Battler): Sprite_Battler { + let id = 0; + if (!this._registeredSprites) this._registeredSprites = {}; + if (battler.isActor()) id = 100000 + (battler as Game_Actor).actorId(); + if (battler.isEnemy()) id = 200000 + (battler as Game_Enemy).index(); + return this._registeredSprites[id]; + } + + public static setSpritePriority() { + if ($gameSystem.isSideView()) { + this._spritePriority = Yanfly.Param.BECSideSpPrio; + } else { + this._spritePriority = Yanfly.Param.BECFrontSprite; + } + if (this._spritePriority === false) this._spritePriority = 0; + if (this._spritePriority === true) this._spritePriority = 1; + } + + public static getSpritePriority() { + if (!this._spritePriority) this.setSpritePriority(); + return this._spritePriority; + } + + public static changeActor(newActorIndex, lastActorActionState) { + let lastActor = this.actor(); + this._actorIndex = newActorIndex; + let newActor = this.actor(); + if (lastActor) { + lastActor.setActionState(lastActorActionState); + lastActor.spriteReturnHome(); + } + if (newActor) { + newActor.setActionState("inputting"); + newActor.spriteStepForward(); + } + } + + public static createActions() { + $gameParty.createActions(); + $gameTroop.createActions(); + } + + public static clearInputtingAction() { + if (this.inputtingAction()) this.inputtingAction().clear(); + } + + public static refreshAllMembers() { + $gameParty.refreshMembers(); + $gameTroop.refreshMembers(); + } + + public static queueForceAction(user, skillId, target) { + let targetIndex = target.index(); + if (target === undefined) { + targetIndex = 0; + } else if (typeof target === "number") { + targetIndex = target; + } + let param = [ + user.isEnemy() ? 0 : 1, + user.isActor() ? user.actorId() : user.index(), + skillId, + targetIndex + ]; + let command = { + code: 339, + indent: 0, + parameters: param + }; + $gameTemp.forceActionQueue(command); + this.clearResults(); + if (this.isTickBased()) this._phase = "action"; + } + + public static addText(text, wait) { + if (!SceneManager.scene._logWindow) return; + wait = wait || 0; + SceneManager.scene._logWindow.addText(text); + if (wait <= 0) return; + let last = this._actionList[this._actionList.length - 1]; + if (last && last[0] === "WAIT") return; + this._actionList.push(["WAIT", [wait]]); + } + + public static clearResults() { + let group = this.allBattleMembers(); + let length = group.length; + for (let i = 0; i < length; ++i) { + let member = group[i]; + if (member) member.clearResult(); + } + this._allTargets = []; + this._targets = []; + this._target = undefined; + } + + public static createForceActionFailSafes() { + this._actionList = this._actionList || []; + this._targets = this._targets || []; + this._allTargets = this._allTargets || []; + this._individualTargets = this._individualTargets || []; + this._phaseSteps = this._phaseSteps || []; + this._conditionFlags = this._conditionFlags || []; + this._trueFlags = this._trueFlags || []; + } + + public static savePreForceActionSettings() { + let settings = this.setPreForceActionSettings(); + this._forceActionQueue.push(settings); + } + + public static setPreForceActionSettings() { + return { + subject: this._subject, + action: JsonEx.makeDeepCopy(this._action), + actionList: JsonEx.makeDeepCopy(this._actionList), + targets: this._targets.slice(), + allTargets: this._allTargets.slice(), + indTargets: this._individualTargets.slice(), + phaseSteps: JsonEx.makeDeepCopy(this._phaseSteps), + returnPhase: this._returnPhase, + phase: this._phase, + conditionFlags: JsonEx.makeDeepCopy(this._conditionFlags), + trueFlags: JsonEx.makeDeepCopy(this._trueFlags) + }; + } + + public static loadPreForceActionSettings() { + let settings = this._forceActionQueue[0]; + if (settings) { + this._forceActionQueue.shift(); + this.resetPreForceActionSettings(settings); + return this._subject && this._subject.isAppeared(); + } else { + return false; + } + } + + public static resetPreForceActionSettings(settings) { + this._subject = settings["subject"]; + this._action = settings["action"]; + this._actionList = settings["actionList"]; + this._targets = settings["targets"]; + this._allTargets = settings["allTargets"]; + this._individualTargets = settings["indTargets"]; + this._phaseSteps = settings["phaseSteps"]; + this._returnPhase = settings["returnPhase"]; + this._conditionFlags = settings["conditionFlags"]; + this._trueFlags = settings["trueFlags"]; + this._phase = settings["phase"]; + } + + public static setTargets(array) { + this._targets = []; + const max = array.length; + for (let i = 0; i < max; ++i) { + const target = array[i]; + if (target) this._targets.push(target); + } + } + + public static updatePhase() { + let phase = this._phaseSteps.shift(); + if (phase) this.createPhaseChanges(); + switch (phase) { + case "setup": + this.createSetupActions(); + break; + case "whole": + this.createWholeActions(); + break; + case "target": + this.createTargetActions(); + break; + case "follow": + this.createFollowActions(); + break; + case "finish": + this.createFinishActions(); + break; + default: + this.endAction(); + break; + } + } + + public static createPhaseChanges() { + this._phase = "actionList"; + this.setTargets(this._allTargets.slice()); + this._conditionFlags = []; + this._trueFlags = []; + } + + public static createSetupActions() { + $gameTemp.clearActionSequenceSettings(); + this._returnPhase = "setup"; + this._actionList = this._action.item().setupActions.slice(); + } + + public static createWholeActions() { + this._returnPhase = "whole"; + this._actionList = this._action.item().wholeActions.slice(); + } + + public static createTargetActions() { + this._returnPhase = "target"; + this._phase = "actionTargetList"; + this.setTargets([this._individualTargets[0]]); + this._actionList = this._action.item().targetActions.slice(); + } + + public static createFollowActions() { + this._returnPhase = "follow"; + this._actionList = this._action.item().followActions.slice(); + } + + public static createFinishActions() { + this._returnPhase = "finish"; + this._actionList = this._action.item().finishActions.slice(); + } + + public static updateActionList() { + for (;;) { + this._actSeq = this._actionList.shift(); + if (this._actSeq) { + if (!this.actionConditionsMet(this._actSeq)) continue; + let seqName = this._actSeq[0].toUpperCase(); + if ( + !this.processActionSequenceCheck(seqName, this._actSeq[1]) + ) { + break; + } + } else { + this._phase = "phaseChange"; + break; + } + } + } + + public static updateActionTargetList() { + for (;;) { + this._actSeq = this._actionList.shift(); + if (this._actSeq) { + if (!this.actionConditionsMet(this._actSeq)) continue; + let seqName = this._actSeq[0].toUpperCase(); + if ( + !this.processActionSequenceCheck(seqName, this._actSeq[1]) + ) { + break; + } + } else if (this._individualTargets.length > 0) { + this._individualTargets.shift(); + if (this._individualTargets.length > 0) { + this.setTargets([this._individualTargets[0]]); + this._actionList = this._action + .item() + .targetActions.slice(); + } else { + this._phase = "phaseChange"; + break; + } + } else { + this._phase = "phaseChange"; + break; + } + } + } + + public static processActionSequenceCheck(actionName, actionArgs) { + // IF condition + if (actionName.match(/IF[ ](.*)/i)) { + return this.actionIfConditions(actionName, actionArgs); + } + return this.processActionSequence(actionName, actionArgs); + } + + public static processActionSequence(actionName, actionArgs) { + // NO ACTION + if (actionName === "") { + return true; + } + // ACTION ANIMATION + if (actionName === "ACTION ANIMATION") { + return this.actionActionAnimation(actionArgs); + } + // ACTION EFFECT + if (actionName === "ACTION COMMON EVENT") { + return this.actionActionCommonEvent(); + } + // ACTION EFFECT + if (actionName === "ACTION EFFECT") { + return this.actionActionEffect(actionArgs); + } + // ANI WAIT: frames + if (["ANI WAIT", "ANIWAIT", "ANIMATION WAIT"].includes(actionName)) { + return this.actionAniWait(actionArgs[0]); + } + // CAST ANIMATION + if (actionName === "CAST ANIMATION") { + return this.actionCastAnimation(); + } + // CLEAR BATTLE LOG + if (actionName === "CLEAR BATTLE LOG") { + return this.actionClearBattleLog(); + } + // DEATH BREAK + if (actionName === "DEATH BREAK") { + return this.actionDeathBreak(); + } + // DISPLAY ACTION + if (actionName === "DISPLAY ACTION") { + return this.actionDisplayAction(); + } + // IMMORTAL: targets, true/false + if (actionName === "IMMORTAL") { + return this.actionImmortal(actionArgs); + } + // MOTION WAIT + if (actionName === "MOTION WAIT") { + return this.actionMotionWait(actionArgs); + } + // PERFORM ACTION + if (actionName === "PERFORM ACTION") { + return this.actionPerformAction(); + } + // PERFORM FINISH + if (actionName === "PERFORM FINISH") { + return this.actionPerformFinish(); + } + // PERFORM START + if (actionName === "PERFORM START") { + return this.actionPerformStart(); + } + // WAIT: frames + if (actionName === "WAIT") { + return this.actionWait(actionArgs[0]); + } + // WAIT FOR ANIMATION + if (actionName === "WAIT FOR ANIMATION") { + return this.actionWaitForAnimation(); + } + // WAIT FOR EFFECT + if (actionName === "WAIT FOR EFFECT") { + return this.actionWaitForEffect(); + } + // WAIT FOR MOVEMENT + if (actionName === "WAIT FOR MOVEMENT") { + return this.actionWaitForMovement(); + } + // WAIT FOR NEW LINE + if (actionName === "WAIT FOR NEW LINE") { + return this.actionWaitForNewLine(); + } + // WAIT FOR POPUPS + if (actionName === "WAIT FOR POPUPS") { + return this.actionWaitForPopups(); + } + return false; + } + + public static makeActionTargets(string) { + let targets = []; + string = string.toUpperCase(); + if (["SUBJECT", "USER"].includes(string)) { + return [this._subject]; + } + if (["TARGET", "TARGETS"].includes(string)) { + let group = this._targets; + for (let i = 0; i < group.length; ++i) { + let target = group[i]; + if (target && target.isAppeared()) targets.push(target); + } + return targets; + } + if (["ACTORS", "EXISTING ACTORS", "ALIVE ACTORS"].includes(string)) { + let group = $gameParty.aliveMembers(); + for (let i = 0; i < group.length; ++i) { + let target = group[i]; + if (target && target.isAppeared()) targets.push(target); + } + return targets; + } + if (["ACTORS ALL", "ALL ACTORS", "PARTY"].includes(string)) { + let group = $gameParty.battleMembers(); + for (let i = 0; i < group.length; ++i) { + let target = group[i]; + if (target && target.isAppeared()) targets.push(target); + } + return targets; + } + if (["DEAD ACTORS", "DEAD ACTOR"].includes(string)) { + let group = $gameParty.deadMembers(); + for (let i = 0; i < group.length; ++i) { + let target = group[i]; + if (target) targets.push(target); + } + return targets; + } + if (["ACTORS NOT USER", "ACTORS NOT SUBJECT"].includes(string)) { + let group = $gameParty.aliveMembers(); + for (let i = 0; i < group.length; ++i) { + let target = group[i]; + if (target && target !== this._subject && target.isAppeared()) { + targets.push(target); + } + } + return targets; + } + if ( + [ + "ENEMIES", + "EXISTING ENEMIES", + "ALIVE ENEMIES", + "TROOP", + "TROOPS" + ].includes(string) + ) { + let group = $gameTroop.aliveMembers(); + for (let i = 0; i < group.length; ++i) { + let target = group[i]; + if (target && target.isAppeared()) targets.push(target); + } + return targets; + } + if (["ENEMIES ALL", "ALL ENEMIES"].includes(string)) { + let group = $gameTroop.members(); + for (let i = 0; i < group.length; ++i) { + let target = group[i]; + if (target && target.isAppeared()) targets.push(target); + } + return targets; + } + if (["DEAD ENEMIES", "DEAD ENEMY"].includes(string)) { + let group = $gameTroop.deadMembers(); + for (let i = 0; i < group.length; ++i) { + let target = group[i]; + if (target) targets.push(target); + } + return targets; + } + if ( + [ + "ENEMIES NOT USER", + "ENEMIES NOT SUBJECT", + "TROOP NOT USER", + "TROOP NOT SUBJECT" + ].includes(string) + ) { + let group = $gameTroop.aliveMembers(); + for (let i = 0; i < group.length; ++i) { + let target = group[i]; + if (target && target !== this._subject && target.isAppeared()) { + targets.push(target); + } + } + return targets; + } + if (string.match(/ACTOR[ ](\d+)/i)) { + let target = $gameParty.battleMembers()[parseInt(RegExp.$1)]; + if (target && target.isAppeared()) return [target]; + } + if (string.match(/ENEMY[ ](\d+)/i)) { + let target = $gameTroop.members()[parseInt(RegExp.$1)]; + if (target && target.isAppeared()) return [target]; + } + if (["FRIEND", "FRIENDS", "ALLIES"].includes(string)) { + let group = this._action.friendsUnit().aliveMembers(); + for (let i = 0; i < group.length; ++i) { + let target = group[i]; + if (target && target.isAppeared()) targets.push(target); + } + return targets; + } + if (["ALL FRIENDS", "ALL ALLIES"].includes(string)) { + let group = this._action.friendsUnit().members(); + for (let i = 0; i < group.length; ++i) { + let target = group[i]; + if (target && target.isAppeared()) targets.push(target); + } + return targets; + } + if (["DEAD FRIEND", "DEAD FRIENDS", "DEAD ALLIES"].includes(string)) { + let group = this._action.friendsUnit().deadMembers(); + for (let i = 0; i < group.length; ++i) { + let target = group[i]; + if (target && target.isAppeared()) targets.push(target); + } + return targets; + } + if (["OPPONENT", "OPPONENTS", "RIVALS", "FOES"].includes(string)) { + let group = this._action.opponentsUnit().aliveMembers(); + for (let i = 0; i < group.length; ++i) { + let target = group[i]; + if (target && target.isAppeared()) targets.push(target); + } + return targets; + } + if (["ALL OPPONENTS", "ALL RIVALS", "ALL FOES"].includes(string)) { + let group = this._action.opponentsUnit().members(); + for (let i = 0; i < group.length; ++i) { + let target = group[i]; + if (target && target.isAppeared()) targets.push(target); + } + return targets; + } + if ( + [ + "DEAD OPPONENT", + "DEAD OPPONENTS", + "DEAD RIVALS", + "DEAD FOES" + ].includes(string) + ) { + let group = this._action.opponentsUnit().deadMembers(); + for (let i = 0; i < group.length; ++i) { + let target = group[i]; + if (target) targets.push(target); + } + return targets; + } + if (["FRIENDS NOT USER", "ALLIES NOT USER"].includes(string)) { + let group = this._action.friendsUnit().aliveMembers(); + for (let i = 0; i < group.length; ++i) { + let target = group[i]; + if (target && target !== this._subject && target.isAppeared()) { + targets.push(target); + } + } + return targets; + } + if (string.match(/(?:FRIEND|ALLY)[ ](\d+)/i)) { + let target = this._action.friendsUnit().members()[ + parseInt(RegExp.$1) + ]; + if (target && target.isAppeared()) return [target]; + } + if (string.match(/(?:OPPONENT|FOE|RIVAL)[ ](\d+)/i)) { + let target = this._action.opponentsUnit().members()[ + parseInt(RegExp.$1) + ]; + if (target && target.isAppeared()) return [target]; + } + if (["ALL ALIVE"].includes(string)) { + let group = this._action.friendsUnit().aliveMembers(); + group = group.concat(this._action.opponentsUnit().aliveMembers()); + for (let i = 0; i < group.length; ++i) { + let target = group[i]; + if (target && target.isAppeared()) targets.push(target); + } + return targets; + } + if (["ALL MEMBERS"].includes(string)) { + let group = this._action.friendsUnit().members(); + group = group.concat(this._action.opponentsUnit().members()); + for (let i = 0; i < group.length; ++i) { + let target = group[i]; + if (target && target.isAppeared()) targets.push(target); + } + return targets; + } + if (["ALL DEAD"].includes(string)) { + let group = this._action.friendsUnit().deadMembers(); + group = group.concat(this._action.opponentsUnit().deadMembers()); + for (let i = 0; i < group.length; ++i) { + let target = group[i]; + if (target) targets.push(target); + } + return targets; + } + if (["ALL NOT USER"].includes(string)) { + let group = this._action.friendsUnit().aliveMembers(); + group = group.concat(this._action.opponentsUnit().aliveMembers()); + for (let i = 0; i < group.length; ++i) { + let target = group[i]; + if (target && target !== this._subject && target.isAppeared()) { + targets.push(target); + } + } + return targets; + } + if (["FOCUS", "PARTICIPANTS"].includes(string)) { + let group = this._targets; + for (let i = 0; i < group.length; ++i) { + let target = group[i]; + if (target && target.isAppeared()) targets.push(target); + } + if (!targets.includes(this._subject)) targets.push(this._subject); + return targets; + } + if (["NOT FOCUS", "NONPARTICIPANTS"].includes(string)) { + let group = this._action.friendsUnit().members(); + group = group.concat(this._action.opponentsUnit().members()); + for (let i = 0; i < group.length; ++i) { + let target = group[i]; + if (target) { + if (target === this._subject) continue; + if (target.isHidden()) continue; + if (this._targets.includes(target)) continue; + + if (target.isDead()) { + if (!target.isActor()) { + continue; + } + } + + targets.push(target); + } + } + return targets; + } + if (string.match(/(?:CHAR|CHARA|CHARACTER)[ ](\d+)/i)) { + let actorId = parseInt(RegExp.$1); + let actor = $gameActors.actor(actorId); + if (actor && $gameParty.battleMembers().includes(actor)) { + return [actor]; + } + } + if (string.toUpperCase() === "FIRST") { + return [this._targets[0]]; + } + return targets; + } + + public static actionConditionsMet(actSeq) { + let ci = this._conditionFlags.length - 1; + let actionName = actSeq[0]; + let actionArgs = actSeq[1]; + let subject = this._subject; + let user = this._subject; + let target = this._targets[0]; + let targets = this._targets; + let action = this._action; + let item = this._action.item(); + if (actionName.match(/ELSE[ ]IF[ ](.*)/i)) { + if (this._conditionFlags.length <= 0) return false; + if (this._conditionFlags[ci]) { + this._conditionFlags[ci] = false; + this._trueFlags[ci] = true; + } else if (!this._conditionFlags[ci] && !this._trueFlags[ci]) { + let text = String(RegExp.$1); + try { + this._conditionFlags[ci] = eval(text); + this._trueFlags[ci] = eval(text); + } catch (e) { + Yanfly.Util.displayError( + e, + text, + "ACTION SEQUENCE IF CONDITION ERROR" + ); + this._conditionFlags[ci] = false; + this._trueFlags[ci] = false; + } + } + return false; + } else if (actionName.match(/ELSE[ ]*(.*)/i)) { + if (this._conditionFlags.length <= 0) return false; + if (this._conditionFlags[ci]) { + this._conditionFlags[ci] = false; + this._trueFlags[ci] = true; + } else if (!this._conditionFlags[ci] && !this._trueFlags[ci]) { + this._conditionFlags[ci] = true; + this._trueFlags[ci] = true; + } + return false; + } else if (actionName.toUpperCase() === "END") { + if (this._conditionFlags.length <= 0) return false; + this._conditionFlags.pop(); + this._trueFlags.pop(); + return false; + } + if (this._conditionFlags.length > 0) return this._conditionFlags[ci]; + return true; + } + + public static actionActionAnimation(actionArgs) { + let targets = this._targets; + if (actionArgs && actionArgs[0]) { + let targets = this.makeActionTargets(actionArgs[0]); + } + let mirror = false; + if (actionArgs && actionArgs[1]) { + if (actionArgs[1].toUpperCase() === "MIRROR") mirror = true; + } + let subject = this._subject; + let group = targets.filter(Yanfly.Util.onlyUnique); + let aniId = this._action.item().animationId; + if (aniId < 0) { + if (mirror) { + this._logWindow.showActorAtkAniMirror(subject, group); + } else { + this._logWindow.showAttackAnimation(subject, group); + } + } else { + this._logWindow.showNormalAnimation(group, aniId, mirror); + } + return true; + } + + public static actionActionCommonEvent() { + this._action.item().effects.forEach(function(effect) { + if (effect.code === Game_Action.EFFECT_COMMON_EVENT) { + $gameTemp.reserveCommonEvent(effect.dataId); + } + }, this); + return false; + } + + public static actionActionEffect(actionArgs) { + let targets = this._targets; + if (actionArgs && actionArgs[0]) { + let targets = this.makeActionTargets(actionArgs[0]); + } + targets.forEach(function(target) { + if (target !== undefined) { + let alreadyDead = target.isDead(); + this.invokeAction(this._subject, target); + if (target.isDead() && !alreadyDead) { + target.performCollapse(); + } + } + }, this); + return true; + } + + public static actionAniWait(frames) { + frames *= Yanfly.Param.AnimationRate || 4; + this._logWindow._waitCount = parseInt(frames); + return false; + } + + public static actionCastAnimation() { + if (!$gameSystem.isSideView() && this._subject.isActor()) return true; + if ( + !this._action.isAttack() && + !this._action.isGuard() && + this._action.isSkill() + ) { + if (this._action.item().castAnimation > 0) { + let ani = $dataAnimations[this._action.item().castAnimation]; + this._logWindow.showAnimation( + this._subject, + [this._subject], + this._action.item().castAnimation + ); + } + } + return true; + } + + public static actionClearBattleLog() { + this._logWindow.clear(); + return false; + } + + public static actionDeathBreak() { + if (this._subject.isDead()) { + this._targets = []; + this._actionList = []; + this._individualTargets = []; + this._phase = "phaseChange"; + return false; + } + return true; + } + + public static actionDisplayAction() { + this._logWindow.displayAction(this._subject, this._action.item()); + return false; + } + + public static actionIfConditions(actionName, actionArgs) { + let subject = this._subject; + let user = this._subject; + let target = this._targets[0]; + let critical = false; + if (target && target.result()) critical = target.result().critical; + let targets = this._targets; + let action = this._action; + let item = this._action.item(); + actionName = this._actSeq[0]; + if (actionName.match(/IF[ ](.*)/i)) { + let text = String(RegExp.$1); + try { + this._conditionFlags.push(eval(text)); + } catch (e) { + this._conditionFlags.push(false); + Yanfly.Util.displayError( + e, + text, + "ACTION SEQUENCE IF CONDITION ERROR" + ); + } + this._trueFlags.push(false); + let ci = this._conditionFlags.length; + } + return true; + } + + public static actionImmortal(actionArgs) { + let value = false; + let targets = this.makeActionTargets(actionArgs[0]).filter( + Yanfly.Util.onlyUnique + ); + try { + value = eval(String(actionArgs[1]).toLowerCase()); + } catch (e) { + value = false; + } + targets.forEach(function(target) { + if (value) { + target.addImmortal(); + } else { + let alreadyDead = target.isDead(); + target.removeImmortal(); + } + }, this); + return true; + } + + public static actionMotionWait(actionArgs) { + let targets = this.makeActionTargets(actionArgs[0]); + if (targets[0].isActor() && targets[0].isSpriteVisible()) { + this._logWindow._waitCount += 12; + return false; + } + return true; + } + + public static actionPerformAction() { + this._logWindow.performAction(this._subject, this._action); + if (this._subject.isActor() && this._subject.isSpriteVisible) { + this._logWindow._waitCount += 20; + return false; + } + return true; + } + + public static actionPerformFinish() { + this._logWindow.performActionEnd(this._subject); + $gameParty.aliveMembers().forEach(function(member) { + member.spriteReturnHome(); + }); + $gameTroop.aliveMembers().forEach(function(member) { + member.spriteReturnHome(); + }); + return true; + } + + public static actionPerformStart() { + this._logWindow.performActionStart(this._subject, this._action); + return true; + } + + public static actionWait(frames) { + this._logWindow._waitCount = parseInt(frames); + return false; + } + + public static actionWaitForAnimation() { + this._logWindow.waitForAnimation(); + return false; + } + + public static actionWaitForEffect() { + this._logWindow.waitForEffect(); + return false; + } + + public static actionWaitForMovement() { + this._logWindow.waitForMovement(); + return false; + } + + public static actionWaitForNewLine() { + this._logWindow.waitForNewLine(); + return false; + } + + public static actionWaitForPopups() { + this._logWindow.waitForPopups(); + return false; + } + + public static isVictoryPhase(): boolean { + return BattleManager._victoryPhase; + } + + public static get subject(): Game_Battler { + return BattleManager._subject; + } + + public static get action(): any { + return BattleManager._action; + } } diff --git a/ts/managers/DataManager.ts b/ts/managers/DataManager.ts index c9c5a26..eeb1c53 100644 --- a/ts/managers/DataManager.ts +++ b/ts/managers/DataManager.ts @@ -19,6 +19,7 @@ import { Scene_Boot } from "../scenes/Scene_Boot"; import { BattleManager } from "./BattleManager"; import { ImageManager } from "./ImageManager"; import { StorageManager } from "./StorageManager"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; export abstract class DataManager { private static _windowId = "RPGMV"; @@ -76,15 +77,652 @@ export abstract class DataManager { xhr.send(); }; - public static isDatabaseLoaded = function() { + public static isDatabaseLoaded() { DataManager.checkError(); for (let i = 0; i < DataManager._databaseFiles.length; i++) { if (!window[DataManager._databaseFiles[i].name]) { return false; } } + if (!Yanfly._loaded_YEP_CoreEngine) { + this.processCORENotetags1($dataItems); + this.processCORENotetags1($dataWeapons); + this.processCORENotetags1($dataArmors); + this.processCORENotetags2($dataEnemies); + this.processCORENotetags3($dataActors); + this.processCORENotetags4($dataClasses); + Yanfly._loaded_YEP_CoreEngine = true; + } + + if (!Yanfly._loaded_YEP_BaseParamControl) { + this.processBPCNotetags1($dataActors); + this.processBPCNotetags1($dataClasses); + this.processBPCNotetags1($dataEnemies); + this.processBPCNotetags1($dataWeapons); + this.processBPCNotetags1($dataArmors); + this.processBPCNotetags1($dataStates); + Yanfly._loaded_YEP_BaseParamControl = true; + } + + if (!Yanfly._loaded_YEP_ExtraParamFormula) { + this.processXParamNotetags($dataActors); + this.processXParamNotetags($dataClasses); + this.processXParamNotetags($dataEnemies); + this.processXParamNotetags($dataWeapons); + this.processXParamNotetags($dataArmors); + this.processXParamNotetags($dataStates); + Yanfly._loaded_YEP_ExtraParamFormula = true; + } + + if (!Yanfly._loaded_YEP_BattleEngineCore) { + this.processMELODYNotetags($dataSkills); + this.processMELODYNotetags($dataItems); + this.processBECNotetags1($dataSkills); + this.processBECNotetags2($dataSkills); + this.processBECNotetags2($dataItems); + this.processBECNotetags3($dataEnemies); + this.processBECNotetags4($dataActors); + this.processBECNotetags4($dataClasses); + this.processBECNotetags4($dataWeapons); + this.processBECNotetags4($dataArmors); + this.processBECNotetags4($dataEnemies); + this.processBECNotetags4($dataStates); + this.processBECNotetags5($dataActors, true); + this.processBECNotetags5($dataClasses, false); + this.processBECNotetags5($dataWeapons, false); + this.processBECNotetags5($dataArmors, false); + this.processBECNotetags5($dataStates, false); + this.processBECNotetags6($dataStates); + Yanfly._loaded_YEP_BattleEngineCore = true; + } + return true; - }; + } + + public static processCORENotetags1(group) { + for (let n = 1; n < group.length; n++) { + const obj = group[n]; + const notedata = obj.note.split(/[\r\n]+/); + + obj.maxItem = Yanfly.Param.MaxItem; + + for (let i = 0; i < notedata.length; i++) { + const line = notedata[i]; + if (line.match(/<(?:PRICE):[ ](\d+)>/i)) { + obj.price = parseInt(RegExp.$1); + } else if (line.match(/<(?:MAX ITEM):[ ](\d+)>/i)) { + obj.maxItem = Math.max(1, parseInt(RegExp.$1)); + } else if (line.match(/<(.*):[ ]([\+\-]\d+)>/i)) { + const stat = String(RegExp.$1).toUpperCase(); + const value = parseInt(RegExp.$2); + switch (stat) { + case "HP": + case "MAXHP": + case "MAX HP": + obj.params[0] = value; + break; + case "MP": + case "MAXMP": + case "MAX MP": + case "SP": + case "MAXSP": + case "MAX SP": + obj.params[1] = value; + break; + case "ATK": + case "STR": + obj.params[2] = value; + break; + case "DEF": + obj.params[3] = value; + break; + case "MAT": + case "INT" || "SPI": + obj.params[4] = value; + break; + case "MDF": + case "RES": + obj.params[5] = value; + break; + case "AGI": + case "SPD": + obj.params[6] = value; + break; + case "LUK": + obj.params[7] = value; + break; + case "EXP": + case "XP": + obj.exp = value; + break; + } + } + } + } + } + + public static processCORENotetags2(group) { + for (let n = 1; n < group.length; n++) { + const obj = group[n]; + const notedata = obj.note.split(/[\r\n]+/); + + for (let i = 0; i < notedata.length; i++) { + const line = notedata[i]; + if (line.match(/<(?:GOLD):[ ](\d+)>/i)) { + obj.gold = parseInt(RegExp.$1); + } else if (line.match(/<(.*):[ ](\d+)>/i)) { + const stat = String(RegExp.$1).toUpperCase(); + const value = parseInt(RegExp.$2); + switch (stat) { + case "HP": + case "MAXHP": + case "MAX HP": + obj.params[0] = value; + break; + case "MP": + case "MAXMP": + case "MAX MP": + case "SP": + case "MAXSP": + case "MAX SP": + obj.params[1] = value; + break; + case "ATK": + case "STR": + obj.params[2] = value; + break; + case "DEF": + obj.params[3] = value; + break; + case "MAT": + case "INT": + case "SPI": + obj.params[4] = value; + break; + case "MDF": + case "RES": + obj.params[5] = value; + break; + case "AGI": + case "SPD": + obj.params[6] = value; + break; + case "LUK": + obj.params[7] = value; + break; + case "EXP": + case "XP": + obj.exp = value; + break; + } + } + } + } + } + + public static processCORENotetags3(group) { + for (let n = 1; n < group.length; n++) { + const obj = group[n]; + const notedata = obj.note.split(/[\r\n]+/); + + obj.maxLevel = Yanfly.Param.MaxLevel; + + for (let i = 0; i < notedata.length; i++) { + const line = notedata[i]; + if (line.match(/<(?:MAX LEVEL):[ ](\d+)>/i)) { + obj.maxLevel = parseInt(RegExp.$1); + if (obj.maxLevel < 1) obj.maxLevel = 1; + } else if (line.match(/<(?:INITIAL LEVEL):[ ](\d+)>/i)) { + obj.initialLevel = parseInt(RegExp.$1); + if (obj.initialLevel < 1) obj.initialLevel = 1; + } + } + } + } + + public static processCORENotetags4(group) { + for (let n = 1; n < group.length; n++) { + const obj = group[n]; + const notedata = obj.note.split(/[\r\n]+/); + + obj.learnings.forEach(function(learning) { + if ( + learning.note.match( + /<(?:LEARN LEVEL|LEARN AT LEVEL):[ ](\d+)>/i + ) + ) { + learning.level = parseInt(RegExp.$1); + if (learning.level < 1) obj.maxLevel = 1; + } + }, this); + } + } + + public static processBPCNotetags1(group) { + for (let n = 1; n < group.length; n++) { + const obj = group[n]; + const notedata = obj.note.split(/[\r\n]+/); + + obj.plusParams = [0, 0, 0, 0, 0, 0, 0, 0]; + obj.rateParams = [1, 1, 1, 1, 1, 1, 1, 1]; + obj.flatParams = [0, 0, 0, 0, 0, 0, 0, 0]; + obj.maxParams = []; + obj.minParams = []; + + for (let i = 0; i < notedata.length; i++) { + const line = notedata[i]; + if (line.match(/<(.*) PLUS:[ ]([\+\-]\d+)>/i)) { + const text = String(RegExp.$1).toUpperCase(); + const value = parseInt(RegExp.$2); + const id = this.getParamId(text); + if (id !== null) obj.plusParams[id] = value; + } else if (line.match(/<(.*) RATE:[ ](\d+)([%ï¼…])>/i)) { + const text = String(RegExp.$1).toUpperCase(); + const rate = parseFloat(RegExp.$2) * 0.01; + const id = this.getParamId(text); + if (id !== null) obj.rateParams[id] = rate; + } else if (line.match(/<(.*) RATE:[ ](\d+).(\d+)>/i)) { + const text = String(RegExp.$1).toUpperCase(); + const rate = parseFloat( + String(RegExp.$2) + "." + String(RegExp.$3) + ); + const id = this.getParamId(text); + if (id !== null) obj.rateParams[id] = rate; + } else if (line.match(/<(.*) FLAT:[ ]([\+\-]\d+)>/i)) { + const text = String(RegExp.$1).toUpperCase(); + const value = parseInt(RegExp.$2); + const id = this.getParamId(text); + if (id !== null) obj.flatParams[id] = value; + } else if (line.match(/<(.*) MAX:[ ](\d+)>/i)) { + const text = String(RegExp.$1).toUpperCase(); + const value = parseInt(RegExp.$2); + const id = this.getParamId(text); + if (id !== null) obj.maxParams[id] = value; + } else if (line.match(/<(.*) MIN:[ ](\d+)>/i)) { + const text = String(RegExp.$1).toUpperCase(); + const value = parseInt(RegExp.$2); + const id = this.getParamId(text); + if (id !== null) obj.minParams[id] = value; + } + } + } + } + + public static processXParamNotetags(group) { + for (let n = 1; n < group.length; n++) { + const obj = group[n]; + const notedata = obj.note.split(/[\r\n]+/); + + obj.plusXParams = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + obj.rateXParams = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; + obj.flatXParams = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + + for (let i = 0; i < notedata.length; i++) { + const line = notedata[i]; + if (line.match(/<(.*) PLUS:[ ]([\+\-]\d+)([%ï¼…])>/i)) { + const text = String(RegExp.$1).toUpperCase(); + const rate = parseFloat(RegExp.$2) * 0.01; + const id = this.getXParamId(text); + if (id !== null) obj.plusXParams[id] = rate; + } else if (line.match(/<(.*) PLUS:[ ]([\+\-]\d+).(\d+)>/i)) { + const text = String(RegExp.$1).toUpperCase(); + const rate = parseFloat( + String(RegExp.$2) + "." + String(RegExp.$3) + ); + const id = this.getXParamId(text); + if (id !== null) obj.plusXParams[id] = rate; + } else if (line.match(/<(.*) RATE:[ ](\d+)([%ï¼…])>/i)) { + const text = String(RegExp.$1).toUpperCase(); + const rate = parseFloat(RegExp.$2) * 0.01; + const id = this.getXParamId(text); + if (id !== null) obj.rateXParams[id] = rate; + } else if (line.match(/<(.*) RATE:[ ](\d+).(\d+)>/i)) { + const text = String(RegExp.$1).toUpperCase(); + const rate = parseFloat( + String(RegExp.$2) + "." + String(RegExp.$3) + ); + const id = this.getXParamId(text); + if (id !== null) obj.rateXParams[id] = rate; + } else if (line.match(/<(.*) FLAT:[ ]([\+\-]\d+)([%ï¼…])>/i)) { + const text = String(RegExp.$1).toUpperCase(); + const rate = parseFloat(RegExp.$2) * 0.01; + const id = this.getXParamId(text); + if (id !== null) obj.flatXParams[id] = rate; + } else if (line.match(/<(.*) FLAT:[ ]([\+\-]\d+).(\d+)>/i)) { + const text = String(RegExp.$1).toUpperCase(); + const rate = parseFloat( + String(RegExp.$2) + "." + String(RegExp.$3) + ); + const id = this.getXParamId(text); + if (id !== null) obj.flatXParams[id] = rate; + } + } + } + } + + public static processMELODYNotetags(group) { + for (let n = 1; n < group.length; n++) { + const obj = group[n]; + if (obj.actionsMade) { + continue; + } + obj.actionsMade = true; + const notedata = obj.note.split(/[\r\n]+/); + + var actionType = 0; + this.setDefaultActions(obj); + + for (let i = 0; i < notedata.length; i++) { + const line = notedata[i]; + if (line.match(/<(?:SETUP ACTION|setup)>/i)) { + actionType = 1; + obj.setupActions = []; + } else if (line.match(/<\/(?:SETUP ACTION|setup)>/i)) { + actionType = 0; + } else if (line.match(/<(?:WHOLE ACTION|whole)>/i)) { + actionType = 2; + obj.wholeActions = []; + } else if (line.match(/<\/(?:WHOLE ACTION|whole)>/i)) { + actionType = 0; + } else if (line.match(/<(?:TARGET ACTION|target)>/i)) { + actionType = 3; + obj.targetActions = []; + } else if (line.match(/<\/(?:TARGET ACTION|target)>/i)) { + actionType = 0; + } else if (line.match(/<(?:FOLLOW ACTION|follow)>/i)) { + actionType = 4; + obj.followActions = []; + } else if (line.match(/<\/(?:FOLLOW ACTION|follow)>/i)) { + actionType = 0; + } else if (line.match(/<(?:FINISH ACTION|finish)>/i)) { + actionType = 5; + obj.finishActions = []; + } else if (line.match(/<\/(?:FINISH ACTION|finish)>/i)) { + actionType = 0; + } else { + this.convertSequenceLine(obj, line, actionType); + } + } + } + } + + public static getParamId(string: string) { + if (["MHP", , "MAXHP", "MAX HP", "HP"].includes(string)) { + return 0; + } else if (["MMP", , "MAXMP", "MAX MP", "MP"].includes(string)) { + return 1; + } else if (["ATK", "ATTACK"].includes(string)) { + return 2; + } else if (["DEF", "DEFENSE"].includes(string)) { + return 3; + } else if ( + ["MAT", "MAGIC ATTACK", "M.ATTACK", "INT"].includes(string) + ) { + return 4; + } else if ( + ["MDF", "MAGIC DEFENSE", "M.DEFENSE", "RES"].includes(string) + ) { + return 5; + } else if (["AGI", "AGILITY", "SPD"].includes(string)) { + return 6; + } else if (["LUK", "LUK"].includes(string)) { + return 7; + } else { + return null; + } + } + + public static getXParamId(string) { + if (["HIT", "HIT RATE"].includes(string)) { + return 0; + } else if (["EVA", "EVADE", "EVASION"].includes(string)) { + return 1; + } else if (["CRI", "CRITICAL", "CRITICAL HIT"].includes(string)) { + return 2; + } else if ( + ["CEV", "CRITICAL EVADE", "CRITICAL EVASION"].includes(string) + ) { + return 3; + } else if (["MEV", "MAGIC EVADE", "MAGIC EVASION"].includes(string)) { + return 4; + } else if ( + ["MRF", "MAGIC REFLECT", "MAGIC REFLECTION"].includes(string) + ) { + return 5; + } else if (["CNT", "COUNTER", "COUNTERATTACK"].includes(string)) { + return 6; + } else if (["HRG", "HP REGEN", "HP REGENERATION"].includes(string)) { + return 7; + } else if (["MRG", "MP REGEN", "MP REGENERATION"].includes(string)) { + return 8; + } else if (["TRG", "TP REGEN", "TP REGENERATION"].includes(string)) { + return 9; + } else { + return null; + } + } + + public static setDefaultActions(obj) { + obj.setupActions = Yanfly.BEC.DefaultActionSetup.slice(); + if (this.isWholeAction(obj)) { + obj.wholeActions = Yanfly.BEC.DefaultActionWhole.slice(); + this.addActionEffects(obj, obj.wholeActions); + obj.targetActions = []; + } else { + obj.wholeActions = []; + obj.targetActions = Yanfly.BEC.DefaultActionTarget.slice(); + this.addActionEffects(obj, obj.targetActions); + } + obj.followActions = Yanfly.BEC.DefaultActionFollow.slice(); + obj.finishActions = Yanfly.BEC.DefaultActionFinish.slice(); + } + + public static isWholeAction(obj) { + if (obj.animationId > 0 && $dataAnimations[obj.animationId]) { + let animation = $dataAnimations[obj.animationId]; + if (animation.position === 3) return true; + if (animation.position !== 3 && [2, 8, 10].includes(obj.scope)) + return true; + } + return false; + } + + public static addActionEffects(obj, array) { + for (;;) { + array[array.length] = ["ACTION EFFECT"]; + array[array.length] = ["DEATH BREAK"]; + obj.repeats -= 1; + if (obj.repeats <= 0) break; + array[array.length] = ["WAIT", [8]]; + } + obj.repeats = 1; + } + + public static convertSequenceLine(obj, line, actionType) { + if (actionType <= 0 || actionType > 5) return; + let seqArgs; + if (line.match(/[ ]*(.*):[ ](.*)/i)) { + Yanfly.BEC.SeqType = RegExp.$1.trim(); + seqArgs = RegExp.$2.split(","); + let length = seqArgs.length; + for (let i = 0; i < length; ++i) { + seqArgs[i] = seqArgs[i].trim(); + } + } else { + Yanfly.BEC.SeqType = line.trim(); + seqArgs = []; + } + let array = [Yanfly.BEC.SeqType, seqArgs]; + if (actionType === 1) obj.setupActions[obj.setupActions.length] = array; + if (actionType === 2) obj.wholeActions[obj.wholeActions.length] = array; + if (actionType === 3) + obj.targetActions[obj.targetActions.length] = array; + if (actionType === 4) + obj.followActions[obj.followActions.length] = array; + if (actionType === 5) + obj.finishActions[obj.finishActions.length] = array; + } + + public static processBECNotetags1(group) { + let note1 = /<(?:CAST ANIMATION|cast ani):[ ](\d+)>/i; + for (let n = 1; n < group.length; n++) { + let obj = group[n]; + let notedata = obj.note.split(/[\r\n]+/); + + obj.castAnimation = 0; + if (obj.hitType === 0) obj.castAnimation = Yanfly.Param.CastCertHit; + if (obj.hitType === 1) + obj.castAnimation = Yanfly.Param.CastPhysical; + if (obj.hitType === 2) obj.castAnimation = Yanfly.Param.CastMagical; + + for (let i = 0; i < notedata.length; i++) { + let line = notedata[i]; + if (line.match(note1)) { + obj.castAnimation = parseInt(RegExp.$1); + } + } + } + } + + public static processBECNotetags2(group) { + let note1 = /<(?:ACTION COPY):[ ](.*):[ ]*(\d+)>/i; + let note2 = /<(?:SPEED):[ ]([\+\-]\d+)>/i; + let note3 = /<(?:DISPLAY NAME|DISPLAY TEXT):[ ](.*)>/i; + let note4 = /<(?:DISPLAY ICON):[ ](\d+)>/i; + for (let n = 1; n < group.length; n++) { + let obj = group[n]; + let notedata = obj.note.split(/[\r\n]+/); + + obj.battleDisplayText = obj.name; + obj.battleDisplayIcon = obj.iconIndex; + + for (let i = 0; i < notedata.length; i++) { + let line = notedata[i]; + if (line.match(note1)) { + let text = String(RegExp.$1).toUpperCase(); + let target; + if (["I", "ITEM"].includes(text)) { + target = $dataItems[parseInt(RegExp.$2)]; + } else if (["S", "SKILL"].includes(text)) { + target = $dataSkills[parseInt(RegExp.$2)]; + } + if (target) { + obj.setupActions = target.setupActions.slice(); + obj.wholeActions = target.wholeActions.slice(); + obj.targetActions = target.targetActions.slice(); + obj.followActions = target.followActions.slice(); + obj.finishActions = target.finishActions.slice(); + } + } else if (line.match(note2)) { + obj.speed = parseInt(RegExp.$1); + } else if (line.match(note3)) { + obj.battleDisplayText = String(RegExp.$1); + } else if (line.match(note4)) { + obj.battleDisplayIcon = parseInt(RegExp.$1); + } + } + } + } + + public static processBECNotetags3(group) { + let note1 = /<(?:ATTACK ANIMATION|attack ani):[ ](\d+)>/i; + for (let n = 1; n < group.length; n++) { + let obj = group[n]; + let notedata = obj.note.split(/[\r\n]+/); + + obj.attackAnimationId = Yanfly.Param.EnemyAtkAni; + + for (let i = 0; i < notedata.length; i++) { + let line = notedata[i]; + if (line.match(note1)) { + obj.attackAnimationId = parseInt(RegExp.$1); + } + } + } + } + + public static processBECNotetags4(group) { + let note1 = /<(?:REFLECT ANIMATION|reflect ani):[ ](\d+)>/i; + for (let n = 1; n < group.length; n++) { + let obj = group[n]; + let notedata = obj.note.split(/[\r\n]+/); + + obj.reflectAnimationId = 0; + obj.spriteCannotMove = false; + + for (let i = 0; i < notedata.length; i++) { + let line = notedata[i]; + if (line.match(note1)) { + obj.reflectAnimationId = parseInt(RegExp.$1); + } else if (line.match(/<(?:SPRITE CANNOT MOVE)>/i)) { + obj.spriteCannotMove = true; + } + } + } + } + + public static processBECNotetags5(group, isActor) { + for (let n = 1; n < group.length; n++) { + let obj = group[n]; + let notedata = obj.note.split(/[\r\n]+/); + + if (isActor) { + obj.anchorX = Yanfly.Param.BECAnchorX; + obj.anchorY = Yanfly.Param.BECAnchorY; + } + + for (let i = 0; i < notedata.length; i++) { + let line = notedata[i]; + if (line.match(/<(?:ANCHOR X):[ ](\d+)[.](\d+)>/i)) { + obj.anchorX = eval( + String(RegExp.$1) + "." + String(RegExp.$2) + ); + } else if (line.match(/<(?:ANCHOR Y):[ ](\d+)[.](\d+)>/i)) { + obj.anchorY = eval( + String(RegExp.$1) + "." + String(RegExp.$2) + ); + } + } + } + } + + public static processBECNotetags6(group) { + let note1a = /<(?:ACTION START):[ ](\d+)>/i; + let note1b = /<(?:ACTION START):[ ](\d+)[ ](?:THROUGH|to)[ ](\d+)>/i; + let note2a = /<(?:TURN START):[ ](\d+)>/i; + let note2b = /<(?:TURN START):[ ](\d+)[ ](?:THROUGH|to)[ ](\d+)>/i; + for (let n = 1; n < group.length; n++) { + let obj = group[n]; + let notedata = obj.note.split(/[\r\n]+/); + + for (let i = 0; i < notedata.length; i++) { + let line = notedata[i]; + if (line.match(note1a)) { + let turns = parseInt(RegExp.$1); + obj.autoRemovalTiming = 3; + obj.maxTurns = turns; + obj.minTurns = turns; + } else if (line.match(note1b)) { + let turns1 = parseInt(RegExp.$1); + let turns2 = parseInt(RegExp.$2); + obj.autoRemovalTiming = 3; + obj.maxTurns = turns1; + obj.minTurns = turns2; + } else if (line.match(note2a)) { + let turns = parseInt(RegExp.$1); + obj.autoRemovalTiming = 4; + obj.maxTurns = turns; + obj.minTurns = turns; + } else if (line.match(note2b)) { + let turns1 = parseInt(RegExp.$1); + let turns2 = parseInt(RegExp.$2); + obj.autoRemovalTiming = 4; + obj.maxTurns = turns1; + obj.minTurns = turns2; + } + } + } + } public static loadMapData = function(mapId) { if (mapId > 0) { @@ -103,12 +741,14 @@ export abstract class DataManager { }; public static makeEmptyMap = function() { - $dataMap = {}; - $dataMap.data = []; - $dataMap.events = []; - $dataMap.width = 100; - $dataMap.height = 100; - $dataMap.scrollType = 3; + //@ts-ignore + $dataMap = { + data: [], + events: [], + width: 100, + height: 100, + scrollType: 3 + }; }; public static isMapLoaded = function() { diff --git a/ts/managers/PluginManager.ts b/ts/managers/PluginManager.ts index 1c2a6b9..59ab1dd 100644 --- a/ts/managers/PluginManager.ts +++ b/ts/managers/PluginManager.ts @@ -24,11 +24,11 @@ export class PluginManager { } public static parameters(name) { - return this._parameters[name.toLowerCase()] || {}; + return this._parameters[name] || {}; } public static setParameters(name, parameters) { - this._parameters[name.toLowerCase()] = parameters; + this._parameters[name] = parameters; } public static loadScript(name) { diff --git a/ts/managers/SceneManager.ts b/ts/managers/SceneManager.ts index 5c6d3ba..ba2647b 100644 --- a/ts/managers/SceneManager.ts +++ b/ts/managers/SceneManager.ts @@ -4,11 +4,11 @@ import { Input } from "../core/Input"; import { TouchInput } from "../core/TouchInput"; import { Utils } from "../core/Utils"; import { WebAudio } from "../core/WebAudio"; +import { Scene_Base } from "../scenes/Scene_Base"; import { AudioManager } from "./AudioManager"; +import { ConfigManager } from "./ConfigManager"; import { ImageManager } from "./ImageManager"; import { PluginManager } from "./PluginManager"; -import { Scene_Base } from "../scenes/Scene_Base"; -import { ConfigManager } from "./ConfigManager"; declare const nw: any; @@ -223,6 +223,10 @@ export abstract class SceneManager { case 116: // F5 if (Utils.isNwjs()) { location.reload(); + if (Utils.isOptionValid("test")) { + const win = nw.Window.get(); + win.closeDevTools(); + } } break; case 119: // F8 diff --git a/ts/managers/TextManager.ts b/ts/managers/TextManager.ts index 2f05948..7b5176f 100644 --- a/ts/managers/TextManager.ts +++ b/ts/managers/TextManager.ts @@ -11,7 +11,7 @@ export abstract class TextManager { return $dataSystem.terms.commands[commandId] || ""; } - public static message(messageId: string) { + public static message(messageId: string): string { return $dataSystem.terms.messages[messageId] || ""; } diff --git a/ts/objects/Game_Action.ts b/ts/objects/Game_Action.ts index 0f74ae1..b560eac 100644 --- a/ts/objects/Game_Action.ts +++ b/ts/objects/Game_Action.ts @@ -1,9 +1,11 @@ import { Utils } from "../core/Utils"; import { Game_Item } from "./Game_Item"; -import { Weapon } from "../interfaces/Weapon"; import { Skill } from "../interfaces/Skill"; import { Item } from "../interfaces/Item"; -import { Armor } from "../interfaces/Armor"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; +import { BattleManager } from "../managers/BattleManager"; +import { Game_ActionResult } from "./Game_ActionResult"; +import { Game_Battler } from "./Game_Battler"; export class Game_Action { public static EFFECT_RECOVER_HP = 11; @@ -31,7 +33,7 @@ export class Game_Action { private _targetIndex: number; private _reflectionTarget: any; - public constructor(subject?, forcing?) { + public constructor(subject?: Game_Battler, forcing?: boolean) { this._subjectActorId = 0; this._subjectEnemyIndex = -1; this._forcing = forcing || false; @@ -155,6 +157,10 @@ export class Game_Action { } public needsSelection() { + if ($gameParty.inBattle() && (this.item() as Item).scope === 0) + return false; + if ($gameParty.inBattle() && BattleManager.isForceSelection()) + return true; return this.checkItemScope([1, 7, 9]); } @@ -268,14 +274,34 @@ export class Game_Action { } public speed() { - const agi = this.subject().agi; - let speed = agi + Utils.randomInt(Math.floor(5 + agi / 4)); - if (this.item()) { - speed += (this.item() as Skill | Item).speed; - } - if (this.isAttack()) { - speed += this.subject().attackSpeed(); + const user = this.subject(); + const a = user; + const maxhp = user.mhp; + const mhp = user.mhp; + const hp = user.hp; + const maxmp = user.mmp; + const mmp = user.mmp; + const mp = user.mp; + const maxtp = user.maxTp(); + const mtp = user.maxTp(); + const tp = user.tp; + const atk = user.atk; + const def = user.def; + const mat = user.mat; + const int = user.mat; + const mdf = user.mdf; + //const res = user.res; + const agi = user.agi; + const luk = user.luk; + const code = Yanfly.Param.BECActionSpeed; + let speed = 0; + try { + speed = eval(code); + } catch (e) { + Yanfly.Util.displayError(e, code, "ACTION SPEED FORMULA ERROR"); } + if (this.item()) speed += (this.item() as Item).speed; + if (this.isAttack()) speed += this.subject().attackSpeed(); return speed; } @@ -393,7 +419,7 @@ export class Game_Action { } } - public evaluateWithTarget(target) { + public evaluateWithTarget(target: Game_Battler) { if (this.isHpEffect()) { const value = this.makeDamageValue(target, false); if (this.isForOpponent()) { @@ -405,7 +431,7 @@ export class Game_Action { } } - public testApply(target) { + public testApply(target: Game_Battler) { return ( this.isForDeadFriend() === target.isDead() && ($gameParty.inBattle() || @@ -416,7 +442,7 @@ export class Game_Action { ); } - public hasItemAnyValidEffects(target) { + public hasItemAnyValidEffects(target: Game_Battler) { return (this.item() as Skill | Item).effects.some(function(effect) { return this.testItemEffect(target, effect); }, this); @@ -457,7 +483,7 @@ export class Game_Action { } } - public itemCnt(target) { + public itemCnt(target: Game_Battler) { if (this.isPhysical() && target.canMove()) { return target.cnt; } else { @@ -465,7 +491,7 @@ export class Game_Action { } } - public itemMrf(target) { + public itemMrf(target: Game_Battler) { if (this.isMagical()) { return target.mrf; } else { @@ -473,7 +499,7 @@ export class Game_Action { } } - public itemHit(target) { + public itemHit(target: Game_Battler) { if (this.isPhysical()) { return ( (this.item() as Item).successRate * 0.01 * this.subject().hit @@ -483,7 +509,7 @@ export class Game_Action { } } - public itemEva(target) { + public itemEva(target: Game_Battler) { if (this.isPhysical()) { return target.eva; } else if (this.isMagical()) { @@ -493,15 +519,19 @@ export class Game_Action { } } - public itemCri(target) { + public itemCri(target: Game_Battler) { return (this.item() as Item).damage.critical ? this.subject().cri * (1 - target.cev) : 0; } - public apply(target) { - const result = target.result(); - this.subject().clearResult(); + public apply(target: Game_Battler) { + target.result = null; + target.result = new Game_ActionResult(); + this.subject().result = null; + this.subject().result = new Game_ActionResult(); + const result = target.result; + this.subject().clearResult; result.clear(); result.used = this.testApply(target); result.missed = result.used && Math.random() >= this.itemHit(target); @@ -519,6 +549,11 @@ export class Game_Action { }, this); this.applyItemUserEffect(target); } + if ($gameParty.inBattle()) { + target.startDamagePopup(); + target.performResultEffects(); + if (target !== this.subject()) this.subject().startDamagePopup(); + } } public makeDamageValue(target, critical) { @@ -546,28 +581,30 @@ export class Game_Action { return value; } - public evalDamageFormula(target) { + public evalDamageFormula(target: Game_Battler) { + const item = this.item() as Skill | Item; + const a = this.subject(); + const b = target; + const v = $gameVariables._data; try { - const item = this.item(); - const a = this.subject(); - const b = target; - const v = $gameVariables._data; - const sign = - [3, 4].indexOf((item as Skill | Item).damage.type) > -1 - ? -1 - : 1; let value = - Math.max(eval((item as Skill | Item).damage.formula), 0) * sign; + Math.max(eval(item.damage.formula), 0) * + ([3, 4].includes(item.damage.type) ? -1 : 1); if (isNaN(value)) { value = 0; } return value; } catch (e) { + Yanfly.Util.displayError( + e, + item.damage.formula, + "DAMAGE FORMULA ERROR" + ); return 0; } } - public calcElementRate(target) { + public calcElementRate(target: Game_Battler) { if ((this.item() as Skill | Item).damage.elementId < 0) { return this.elementsMaxRate( target, @@ -610,7 +647,7 @@ export class Game_Action { } public executeDamage(target, value) { - const result = target.result(); + const result = target.result; if (value === 0) { result.critical = false; } @@ -759,6 +796,9 @@ export class Game_Action { chance *= this.subject().attackStatesRate(stateId); chance *= this.lukEffectRate(target); if (Math.random() < chance) { + if (stateId === target.deathStateId()) { + if (target.isImmortal()) target.removeImmortal(); + } target.addState(stateId); this.makeSuccess(target); } @@ -768,13 +808,17 @@ export class Game_Action { } public itemEffectAddNormalState(target, effect) { + let stateId = effect.dataId; let chance = effect.value1; if (!this.isCertainHit()) { - chance *= target.stateRate(effect.dataId); + chance *= target.stateRate(stateId); chance *= this.lukEffectRate(target); } if (Math.random() < chance) { - target.addState(effect.dataId); + if (stateId === target.deathStateId()) { + if (target.isImmortal()) target.removeImmortal(); + } + target.addState(stateId); this.makeSuccess(target); } } @@ -836,11 +880,11 @@ export class Game_Action { public itemEffectCommonEvent(target, effect) {} - public makeSuccess(target) { - target.result().success = true; + public makeSuccess(target: Game_Battler) { + target.result.success = true; } - public applyItemUserEffect(target) { + public applyItemUserEffect(target: Game_Battler) { const value = Math.floor( (this.item() as Skill | Item).tpGain * this.subject().tcr ); @@ -848,10 +892,19 @@ export class Game_Action { } public lukEffectRate(target) { - return Math.max(1.0 + (this.subject().luk - target.luk) * 0.001, 0.0); + const item = this.item(); + const skill = this.item(); + const a = this.subject(); + const user = this.subject(); + const subject = this.subject(); + const b = target; + const s = $gameSwitches._data; + const v = $gameVariables._data; + return eval(Yanfly.Param.BPCLukEffectRate); } public applyGlobal() { + if ($gameParty.inBattle()) return; (this.item() as Skill | Item).effects.forEach(function(effect) { if (effect.code === Game_Action.EFFECT_COMMON_EVENT) { $gameTemp.reserveCommonEvent(effect.dataId); diff --git a/ts/objects/Game_Actor.ts b/ts/objects/Game_Actor.ts index e0a0839..625ab20 100644 --- a/ts/objects/Game_Actor.ts +++ b/ts/objects/Game_Actor.ts @@ -1,13 +1,14 @@ import { Utils } from "../core/Utils"; +import { Weapon } from "../interfaces/Weapon"; import { BattleManager } from "../managers/BattleManager"; import { DataManager } from "../managers/DataManager"; import { SoundManager } from "../managers/SoundManager"; import { TextManager } from "../managers/TextManager"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; +import { Sprite_Actor } from "../sprites/Sprite_Actor"; import { Game_Action } from "./Game_Action"; import { Game_Battler, Game_Battler_OnLoad } from "./Game_Battler"; import { Game_Item, Game_Item_OnLoad } from "./Game_Item"; -import { Weapon } from "../interfaces/Weapon"; -import { Armor } from "../interfaces/Armor"; export interface Game_Actor_OnLoad extends Game_Battler_OnLoad { _actorId: number; @@ -29,9 +30,12 @@ export interface Game_Actor_OnLoad extends Game_Battler_OnLoad { _lastCommandSymbol: string; _profile: any; _stateSteps: {}; + _weaponImageId: number; } export class Game_Actor extends Game_Battler { + private _anchorX: any; + private _anchorY: any; private _actorId: number; private _name: string; private _nickname: string; @@ -51,10 +55,12 @@ export class Game_Actor extends Game_Battler { private _lastCommandSymbol: string; private _profile: any; private _stateSteps: {}; + private _weaponImageId: number; public constructor(actorId: number, gameLoadInput?: Game_Actor_OnLoad) { super(gameLoadInput); if (gameLoadInput) { + this._weaponImageId = gameLoadInput._weaponImageId; this._actorId = gameLoadInput._actorId; this._name = gameLoadInput._name; this._nickname = gameLoadInput._nickname; @@ -111,6 +117,7 @@ export class Game_Actor extends Game_Battler { this._lastMenuSkill = new Game_Item(); this._lastBattleSkill = new Game_Item(); this._lastCommandSymbol = ""; + this._weaponImageId = 0; } public setup(actorId) { @@ -127,6 +134,20 @@ export class Game_Actor extends Game_Battler { this.initEquips(actor.equips); this.clearParamPlus(); this.recoverAll(); + this.clearCustomParamLimits(); + this.clearXParamPlus(); + } + + public clearWeaponAnimation() { + this._weaponImageId = 0; + } + + public isWeaponAnimationRequested() { + return this._weaponImageId > 0; + } + + public weaponImageId() { + return this._weaponImageId; } public actorId() { @@ -246,6 +267,7 @@ export class Game_Actor extends Game_Battler { } public isMaxLevel() { + if (this.maxLevel() === 0) return false; return this._level >= this.maxLevel(); } @@ -285,7 +307,7 @@ export class Game_Actor extends Game_Battler { return slots; } - public equips() { + public equips(): any[] { return this._equips.map(function(item) { return item.object(); }); @@ -452,8 +474,11 @@ export class Game_Actor extends Game_Battler { } public refresh() { + this._anchorX = undefined; + this._anchorY = undefined; this.releaseUnequippableItems(false); super.refresh(); + if ($gameParty.inBattle()) this.requestStatusRefresh(); } public isActor() { @@ -505,7 +530,7 @@ export class Game_Actor extends Game_Battler { } public traitObjects() { - let objects = super.traitObjects(); + let objects = super.traitObjects() as any[]; objects = objects.concat([this.actor(), this.currentClass()]); const equips = this.equips(); for (let i = 0; i < equips.length; i++) { @@ -538,22 +563,35 @@ export class Game_Actor extends Game_Battler { public paramMax(paramId) { if (paramId === 0) { - return 9999; // MHP + return Yanfly.Param.ActorMaxHp; + } else if (paramId === 1) { + return Yanfly.Param.ActorMaxMp; + } else { + return Yanfly.Param.ActorParam; } - return super.paramMax(paramId); } public paramBase(paramId) { + if (this.level > 99) { + let i = this.currentClass().params[paramId][99]; + const j = this.currentClass().params[paramId][98]; + i += (i - j) * (this.level - 99); + return i; + } return this.currentClass().params[paramId][this._level]; } - public paramPlus(paramId) { + public paramPlus(paramId: number) { let value = super.paramPlus(paramId); - const equips = this.equips(); - for (let i = 0; i < equips.length; i++) { - const item = equips[i]; - if (item) { - value += (item as Weapon | Armor).params[paramId]; + value += this.actor().plusParams[paramId]; + value += this.currentClass().plusParams[paramId]; + const length = this.equips().length; + for (let i = 0; i < length; ++i) { + const obj = this.equips()[i]; + if (!obj) continue; + value += obj.params[paramId]; + if (obj.plusParams) { + value += obj.plusParams[paramId]; } } return value; @@ -657,7 +695,7 @@ export class Game_Actor extends Game_Battler { } public learnSkill(skillId) { - if (!this.isLearnedSkill(skillId)) { + if (!this._skills.includes(skillId)) { this._skills.push(skillId); this._skills.sort(function(a, b) { return a - b; @@ -682,7 +720,7 @@ export class Game_Actor extends Game_Battler { public changeClass(classId, keepExp) { if (keepExp) { - this._exp[classId] = this.currentExp(); + this._exp[classId] = this._exp[this._classId]; } this._classId = classId; this.changeExp(this._exp[this._classId] || 0, false); @@ -704,7 +742,8 @@ export class Game_Actor extends Game_Battler { } public isSpriteVisible() { - return $gameSystem.isSideView(); + if ($gameSystem.isSideView()) return true; + return Yanfly.Param.BECFrontSprite; } public startAnimation(animationId, mirror, delay) { @@ -735,22 +774,6 @@ export class Game_Actor extends Game_Battler { super.performActionEnd(); } - public performAttack() { - const weapons = this.weapons(); - const wtypeId = weapons[0] ? (weapons[0] as Weapon).wtypeId : 0; - const attackMotion = $dataSystem.attackMotions[wtypeId]; - if (attackMotion) { - if (attackMotion.type === 0) { - this.requestMotion("thrust"); - } else if (attackMotion.type === 1) { - this.requestMotion("swing"); - } else if (attackMotion.type === 2) { - this.requestMotion("missile"); - } - this.startWeaponAnimation(attackMotion.weaponImageId); - } - } - public performDamage() { super.performDamage(); if (this.isSpriteVisible()) { @@ -868,23 +891,19 @@ export class Game_Actor extends Game_Battler { } public showAddedStates() { - this.result() - .addedStateObjects() - .forEach(function(state) { - if (state.message1) { - $gameMessage.add(this._name + state.message1); - } - }, this); + this.result.addedStateObjects().forEach(function(state) { + if (state.message1) { + $gameMessage.add(this._name + state.message1); + } + }, this); } public showRemovedStates() { - this.result() - .removedStateObjects() - .forEach(function(state) { - if (state.message4) { - $gameMessage.add(this._name + state.message4); - } - }, this); + this.result.removedStateObjects().forEach(function(state) { + if (state.message4) { + $gameMessage.add(this._name + state.message4); + } + }, this); } public stepsForTurn() { @@ -894,7 +913,7 @@ export class Game_Actor extends Game_Battler { public turnEndOnMap() { if ($gameParty.steps() % this.stepsForTurn() === 0) { this.onTurnEnd(); - if (this.result().hpDamage > 0) { + if (this.result.hpDamage > 0) { this.performMapDamage(); } } @@ -996,4 +1015,227 @@ export class Game_Actor extends Game_Battler { } return super.meetsUsableItemConditions(item); } + + public paramRate(paramId: number) { + let rate = super.paramRate(paramId); + rate *= this.actor().rateParams[paramId]; + rate *= this.currentClass().rateParams[paramId]; + const length = this.equips().length; + for (let i = 0; i < length; ++i) { + const obj = this.equips()[i]; + if (obj && obj.rateParams) { + rate *= obj.rateParams[paramId]; + } + } + return rate; + } + + public paramFlat(paramId: number) { + let value = Game_Battler.prototype.paramFlat.call(this, paramId); + value += this.actor().flatParams[paramId]; + value += this.currentClass().flatParams[paramId]; + const length = this.equips().length; + for (let i = 0; i < length; ++i) { + const obj = this.equips()[i]; + if (obj && obj.flatParams) { + value += obj.flatParams[paramId]; + } + } + return value; + } + + public customParamMax(paramId: number) { + let value = super.customParamMax(paramId); + if (this.actor().maxParams[paramId]) { + value = Math.max(value, this.actor().maxParams[paramId]); + } + if (this.currentClass().maxParams[paramId]) { + value = Math.max(value, this.currentClass().maxParams[paramId]); + } + const length = this.equips().length; + for (let i = 0; i < length; ++i) { + const obj = this.equips()[i]; + if (obj && obj.maxParams && obj.maxParams[paramId]) { + value = Math.max(value, obj.maxParams[paramId]); + } + } + return value; + } + + public customParamMin(paramId: number) { + let value = super.customParamMin(paramId); + if (this.actor().minParams[paramId]) { + value = Math.max(value, this.actor().minParams[paramId]); + } + if (this.currentClass().minParams[paramId]) { + value = Math.max(value, this.currentClass().minParams[paramId]); + } + const length = this.equips().length; + for (let i = 0; i < length; ++i) { + const obj = this.equips()[i]; + if (obj && obj.minParams && obj.minParams[paramId]) { + value = Math.max(value, obj.minParams[paramId]); + } + } + return value; + } + + public reflectAnimationId() { + if (this.actor().reflectAnimationId > 0) { + return this.actor().reflectAnimationId; + } + if (this.currentClass().reflectAnimationId > 0) { + return this.currentClass().reflectAnimationId; + } + for (let i = 0; i < this.equips().length; ++i) { + let equip = this.equips()[i]; + if (equip && equip.reflectAnimationId > 0) { + return equip.reflectAnimationId; + } + } + return super.reflectAnimationId(); + } + + public spriteCanMove() { + if (this.actor().spriteCannotMove) return false; + if (this.currentClass().spriteCannotMove) return false; + for (let i = 0; i < this.equips().length; ++i) { + let equip = this.equips()[i]; + if (equip && equip.spriteCannotMove) return false; + } + return super.spriteCanMove(); + } + + public spriteWidth() { + if ($gameSystem.isSideView() && this.battler()) { + return this.battler().mainSprite.width; + } else { + return 1; + } + } + + public spriteHeight() { + if ($gameSystem.isSideView() && this.battler()) { + return this.battler().mainSprite.height; + } else { + return 1; + } + } + + public anchorX() { + if (this._anchorX !== undefined) return this._anchorX; + let length = this.states().length; + for (let i = 0; i < length; ++i) { + let obj = this.states()[i]; + if (obj && obj.anchorX !== undefined) { + this._anchorX = obj.anchorX; + return this._anchorX; + } + } + length = this.equips().length; + for (let i = 0; i < length; ++i) { + let obj = this.equips()[i]; + if (obj && obj.anchorX !== undefined) { + this._anchorX = obj.anchorX; + return this._anchorX; + } + } + if (this.currentClass().anchorX !== undefined) { + this._anchorX = this.currentClass().anchorX; + return this._anchorX; + } + this._anchorX = this.actor().anchorX; + return this._anchorX; + } + + public anchorY() { + if (this._anchorY !== undefined) return this._anchorY; + let length = this.states().length; + for (let i = 0; i < length; ++i) { + let obj = this.states()[i]; + if (obj && obj.anchorY !== undefined) { + this._anchorY = obj.anchorY; + return this._anchorY; + } + } + length = this.equips().length; + for (let i = 0; i < length; ++i) { + let obj = this.equips()[i]; + if (obj && obj.anchorY !== undefined) { + this._anchorY = obj.anchorY; + return this._anchorY; + } + } + if (this.currentClass().anchorY !== undefined) { + this._anchorY = this.currentClass().anchorY; + return this._anchorY; + } + this._anchorY = this.actor().anchorY; + return this._anchorY; + } + + public spriteFacePoint(pointX, pointY) { + if (this.spritePosX() > pointX) { + this.spriteFaceForward(); + } else { + this.spriteFaceBackward(); + } + } + + public spriteFaceAwayPoint(pointX, pointY) { + if (this.spritePosX() > pointX) { + this.spriteFaceBackward(); + } else { + this.spriteFaceForward(); + } + } + + public performAttack() { + let weapons = this.weapons(); + let wtypeId = weapons[0] ? weapons[0].wtypeId : 0; + let attackMotion = $dataSystem.attackMotions[wtypeId]; + if (attackMotion) { + if (attackMotion.type === 0) { + this.forceMotion("thrust"); + } else if (attackMotion.type === 1) { + this.forceMotion("swing"); + } else if (attackMotion.type === 2) { + this.forceMotion("missile"); + } + this.startWeaponAnimation(attackMotion.weaponImageId); + } + } + + public startWeaponAnimation(weaponImageId) { + this._weaponImageId = weaponImageId; + const actor = this.battler() as Sprite_Actor; + if (actor.setupWeaponAnimation) { + actor.setupWeaponAnimation(); + } else { + throw new Error("Sprite is not a Sprite_Actor"); + } + } + + public attackMotion() { + let weapons = this.weapons(); + let wtypeId = weapons[0] ? weapons[0].wtypeId : 0; + let attackMotion = $dataSystem.attackMotions[wtypeId]; + if (attackMotion) { + if (attackMotion.type === 0) { + return "thrust"; + } else if (attackMotion.type === 1) { + return "swing"; + } else if (attackMotion.type === 2) { + return "missile"; + } + } + return "thrust"; + } + + public performEscapeSuccess() { + if (this.battler()) { + this.performEscape(); + this.battler().startMove(300, 0, 60); + } + } } diff --git a/ts/objects/Game_Battler.ts b/ts/objects/Game_Battler.ts index 9f6a7d8..ccf71ae 100644 --- a/ts/objects/Game_Battler.ts +++ b/ts/objects/Game_Battler.ts @@ -1,7 +1,10 @@ +import { JsonEx } from "../core/JsonEx"; import { Utils } from "../core/Utils"; import { BattleManager } from "../managers/BattleManager"; import { DataManager } from "../managers/DataManager"; import { SoundManager } from "../managers/SoundManager"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; +import { Sprite_Battler } from "../sprites/Sprite_Battler"; import { Game_Action } from "./Game_Action"; import { Game_ActionResult } from "./Game_ActionResult"; import { Game_BattlerBase, Game_BattlerBase_OnLoad } from "./Game_BattlerBase"; @@ -9,14 +12,13 @@ import { Game_BattlerBase, Game_BattlerBase_OnLoad } from "./Game_BattlerBase"; export interface Game_Battler_OnLoad extends Game_BattlerBase_OnLoad { _actions: any[]; _speed: number; - _result: Game_ActionResult; + _actionState: string; _lastTargetIndex: number; _animations: any[]; - _damagePopup: boolean; + _damagePopup: any[]; _effectType: any; _motionType: any; - _weaponImageId: number; _motionRefresh: boolean; _selected: boolean; } @@ -24,16 +26,24 @@ export interface Game_Battler_OnLoad extends Game_BattlerBase_OnLoad { export abstract class Game_Battler extends Game_BattlerBase { private _actions: any[]; private _speed: number; - private _result: Game_ActionResult; private _actionState: string; private _lastTargetIndex: number; private _animations: any[]; - private _damagePopup: boolean; + private _damagePopup: any[]; private _effectType: any; private _motionType: any; - private _weaponImageId: number; + private _motionRefresh: boolean; private _selected: boolean; + private _selfTurnCount: number; + private _flinched: boolean; + + public get result(): Game_ActionResult { + return this._result; + } + public set result(value: Game_ActionResult) { + this._result = value; + } public constructor(gameLoadInput?: Game_Battler_OnLoad) { super(gameLoadInput); @@ -48,7 +58,6 @@ export abstract class Game_Battler extends Game_BattlerBase { this._damagePopup = gameLoadInput._damagePopup; this._effectType = gameLoadInput._effectType; this._motionType = gameLoadInput._motionType; - this._weaponImageId = gameLoadInput._weaponImageId; this._motionRefresh = gameLoadInput._motionRefresh; this._selected = gameLoadInput._selected; } @@ -62,10 +71,9 @@ export abstract class Game_Battler extends Game_BattlerBase { this._actionState = ""; this._lastTargetIndex = 0; this._animations = []; - this._damagePopup = false; + this._damagePopup = []; this._effectType = null; this._motionType = null; - this._weaponImageId = 0; this._motionRefresh = false; this._selected = false; } @@ -75,11 +83,7 @@ export abstract class Game_Battler extends Game_BattlerBase { } public clearDamagePopup() { - this._damagePopup = false; - } - - public clearWeaponAnimation() { - this._weaponImageId = 0; + this._damagePopup = []; } public clearEffect() { @@ -97,10 +101,9 @@ export abstract class Game_Battler extends Game_BattlerBase { public requestMotion(motionType) { this._motionType = motionType; - } - - public requestMotionRefresh() { - this._motionRefresh = true; + if (this.battler()) { + this.battler().startMotion(motionType); + } } public select() { @@ -116,7 +119,8 @@ export abstract class Game_Battler extends Game_BattlerBase { } public isDamagePopupRequested() { - return this._damagePopup; + if (!this._damagePopup) this.clearDamagePopup(); + return this._damagePopup.length > 0; } public isEffectRequested() { @@ -127,15 +131,22 @@ export abstract class Game_Battler extends Game_BattlerBase { return !!this._motionType; } - public isWeaponAnimationRequested() { - return this._weaponImageId > 0; - } - public isMotionRefreshRequested() { return this._motionRefresh; } public isSelected() { + if ($gameParty.inBattle() && BattleManager.isAllSelection()) { + if (!this.isAppeared()) return false; + let action = BattleManager.inputtingAction(); + if (action && action.item()) { + if (this.isDead() && this.isEnemy()) return false; + if (this.isDead() && this.isActor()) + return action.isForDeadFriend(); + if (action.isForFriend() && this.isActor()) return true; + if (action.isForOpponent() && this.isEnemy()) return true; + } + } return this._selected; } @@ -147,25 +158,39 @@ export abstract class Game_Battler extends Game_BattlerBase { return this._motionType; } - public weaponImageId() { - return this._weaponImageId; - } - public shiftAnimation() { return this._animations.shift(); } public startAnimation(animationId, mirror, delay) { + if (!$dataAnimations[animationId]) return; const data = { animationId: animationId, mirror: mirror, delay: delay }; this._animations.push(data); } public startDamagePopup() { - this._damagePopup = true; + let result = this.result; + if (result.missed || result.evaded) { + let copyResult = JsonEx.makeDeepCopy(result); + copyResult.hpAffected = false; + copyResult.mpDamage = 0; + this._damagePopup.push(copyResult); + } + if (result.hpAffected) { + let copyResult = JsonEx.makeDeepCopy(result); + copyResult.mpDamage = 0; + this._damagePopup.push(copyResult); + } + if (result.mpDamage !== 0) { + let copyResult = JsonEx.makeDeepCopy(result); + copyResult.hpAffected = false; + this._damagePopup.push(copyResult); + } } - public startWeaponAnimation(weaponImageId) { - this._weaponImageId = weaponImageId; + public shiftDamagePopup() { + if (!this._damagePopup) this.clearDamagePopup(); + return this._damagePopup.shift(); } public action(index) { @@ -184,15 +209,12 @@ export abstract class Game_Battler extends Game_BattlerBase { this._actions = []; } - public result() { - return this._result; - } - public clearResult() { this._result.clear(); } public refresh() { + this._baseParamCache = undefined; super.refresh(); if (this.hp === 0) { this.addState(this.deathStateId()); @@ -210,6 +232,7 @@ export abstract class Game_Battler extends Game_BattlerBase { this.resetStateCounts(stateId); this._result.pushAddedState(stateId); } + if (this.canAddStateFreeTurn(stateId)) this.setStateFreeTurn(stateId); } public isStateAddable(stateId) { @@ -236,17 +259,6 @@ export abstract class Game_Battler extends Game_BattlerBase { }, this); } - public removeState(stateId) { - if (this.isStateAffected(stateId)) { - if (stateId === this.deathStateId()) { - this.revive(); - } - this.eraseState(stateId); - this.refresh(); - this._result.pushRemovedState(stateId); - } - } - public escape() { if ($gameParty.inBattle()) { this.hide(); @@ -397,6 +409,10 @@ export abstract class Game_Battler extends Game_BattlerBase { } else if (DataManager.isItem(item)) { this.consumeItem(item); } + this.refresh(); + if (!$gameParty.inBattle()) return; + this.increaseSelfTurnCount(); + this.updateStateActionStart(); } public consumeItem(item) { @@ -461,11 +477,35 @@ export abstract class Game_Battler extends Game_BattlerBase { } public regenerateAll() { + this.clearResult(); + const lifeState = this.isAlive(); if (this.isAlive()) { this.regenerateHp(); this.regenerateMp(); this.regenerateTp(); } + if ($gameParty.inBattle()) { + if (!BattleManager.timeBasedStates()) this.updateStateTurns(); + if (!BattleManager.timeBasedBuffs()) { + this.updateBuffTurns(); + this.removeBuffsAuto(); + } + if (this.isDead() && lifeState === true) { + this.performCollapse(); + } + this.startDamagePopup(); + } + } + + public addImmortal() { + this._immortalState = true; + } + + public removeImmortal() { + const alreadyDead = this.isDead(); + this._immortalState = false; + this.refresh(); + if (this.isDead() && !alreadyDead) this.performCollapse(); } public onBattleStart() { @@ -474,22 +514,16 @@ export abstract class Game_Battler extends Game_BattlerBase { if (!this.isPreserveTp()) { this.initTp(); } + this._freeStateTurn = []; + this._immortalState = false; + this._selfTurnCount = 0; } public onAllActionsEnd() { this.clearResult(); this.removeStatesAuto(1); this.removeBuffsAuto(); - } - - public onTurnEnd() { - this.clearResult(); - this.regenerateAll(); - if (!BattleManager.isForcedTurn()) { - this.updateStateTurns(); - this.updateBuffTurns(); - } - this.removeStatesAuto(2); + if (!BattleManager.processTurn) this.updateStateActionEnd(); } public onBattleEnd() { @@ -501,6 +535,8 @@ export abstract class Game_Battler extends Game_BattlerBase { this.clearTp(); } this.appear(); + this._freeStateTurn = []; + this._immortalState = false; } public onDamage(value) { @@ -550,6 +586,7 @@ export abstract class Game_Battler extends Game_BattlerBase { public performActionStart(action) { if (!action.isGuard()) { this.setActionState("acting"); + this.spriteStepForward(); } } @@ -557,12 +594,16 @@ export abstract class Game_Battler extends Game_BattlerBase { public performActionEnd() { this.setActionState("done"); + this.spriteReturnHome(); } - public performDamage() {} + public performDamage() { + this.performFlinch(); + } public performMiss() { SoundManager.playMiss(); + this.performFlinch(); } public performRecovery() { @@ -571,10 +612,18 @@ export abstract class Game_Battler extends Game_BattlerBase { public performEvasion() { SoundManager.playEvasion(); + this.performFlinch(); + } + + public performFlinch() { + if (this._flinched || !$gameSystem.isSideView()) return; + this._flinched = true; + this.spriteStepFlinch(); } public performMagicEvasion() { SoundManager.playMagicEvasion(); + this.performFlinch(); } public performCounter() { @@ -583,11 +632,468 @@ export abstract class Game_Battler extends Game_BattlerBase { public performReflection() { SoundManager.playReflection(); + if (!$gameSystem.isSideView() && this.isActor()) return; + let animationId = this.reflectAnimationId(); + let mirror = this.isActor(); + this.startAnimation(animationId, mirror, 0); + } + + public performSubstitute(target) { + if (!$gameSystem.isSideView()) return; + this._flinched = true; + if (BattleManager.action.isForAll()) { + this.spriteStepForward(); + target.spriteStepSubBack(); + } else { + this.spriteStepToSubstitute(target); + target.spriteStepSubBack(); + } + } + + public setBattler(sprite: Sprite_Battler) { + BattleManager.registerSprite(this, sprite); + } + + public battler() { + return BattleManager.getSprite(this); + } + + public performCollapse() { + if ($gameParty.inBattle()) this.forceMotion(this.deadMotion()); } - public performSubstitute(target) {} + public forceMotion(motionType) { + this._motionType = motionType; + if (this.battler()) { + this.battler().forceMotion(motionType); + } + } - public performCollapse() {} + public performResultEffects() { + let result = this.result; + if (result.missed && result.physical) this.performMiss(); + if (result.evaded) { + if (result.physical) { + this.performEvasion(); + } else { + this.performMagicEvasion(); + } + } + if (result.hpAffected) { + if (result.hpDamage > 0 && !result.drain) { + this.performDamage(); + } + if (result.hpDamage < 0) { + this.performRecovery(); + } + } + if (this.isAlive() && result.mpDamage !== 0 && result.mpDamage < 0) { + this.performRecovery(); + } + if (this.isAlive() && result.tpDamage !== 0 && result.tpDamage < 0) { + this.performRecovery(); + } + } public abstract isSpriteVisible(): boolean; + + public paramPlus(paramId: number) { + let value = super.paramPlus(paramId); + const length = this.states().length; + for (let i = 0; i < length; ++i) { + const obj = this.states()[i]; + if (obj && obj.plusParams) { + value += obj.plusParams[paramId]; + } + } + return value; + } + + public paramRate(paramId: number) { + let rate = super.paramRate(paramId); + const length = this.states().length; + for (let i = 0; i < length; ++i) { + const obj = this.states()[i]; + if (obj && obj.rateParams) { + rate *= obj.rateParams[paramId]; + } + } + return rate; + } + + public customParamMax(paramId: number) { + let value = super.customParamMax(paramId); + const length = this.states().length; + for (let i = 0; i < length; ++i) { + const obj = this.states()[i]; + if (obj && obj.maxParams && obj.maxParams[paramId]) { + value = Math.max(value, obj.maxParams[paramId]); + } + } + return value; + } + + public customParamMin(paramId) { + let value = super.customParamMin(paramId); + const length = this.states().length; + for (let i = 0; i < length; ++i) { + const obj = this.states()[i]; + if (obj && obj.minParams && obj.minParams[paramId]) { + value = Math.max(value, obj.minParams[paramId]); + } + } + return value; + } + + public xparamPlus(id) { + let value = super.xparamPlus(id); + let length = this.states().length; + for (let i = 0; i < length; ++i) { + let obj = this.states()[i]; + if (obj && obj.plusXParams) value += obj.plusXParams[id]; + } + return value; + } + + public xparamRate(id) { + let value = super.xparamRate(id); + let length = this.states().length; + for (let i = 0; i < length; ++i) { + let obj = this.states()[i]; + if (obj && obj.rateXParams) value *= obj.rateXParams[id]; + } + return value; + } + + public xparamFlat(id) { + let value = super.xparamFlat(id); + let length = this.states().length; + for (let i = 0; i < length; ++i) { + let obj = this.states()[i]; + if (obj && obj.flatXParams) value += obj.flatXParams[id]; + } + return value; + } + + public spriteStepForward() { + if ($gameSystem.isSideView() && this.battler()) { + this.battler().stepForward(); + } + } + + public spriteStepBack() { + if ($gameSystem.isSideView() && this.battler()) { + this.battler().stepBack(); + } + } + + public spriteStepSubBack() { + if ($gameSystem.isSideView() && this.battler()) { + this.battler().stepSubBack(); + } + } + + public spriteStepToSubstitute(target) { + if ($gameSystem.isSideView() && this.battler()) { + this.battler().stepToSubstitute(target); + } + } + + public spriteStepFlinch() { + if ($gameSystem.isSideView() && this.battler()) { + this.battler().stepFlinch(); + } + } + + public spriteReturnHome() { + if ($gameSystem.isSideView() && this.battler()) { + this._flinched = false; + this.spriteFaceForward(); + this.battler().stepBack(); + if (this.numActions() <= 0) { + this.setActionState("undecided"); + } + this.battler().refreshMotion(); + } + } + + public reflectAnimationId() { + for (let i = 0; i < this.states().length; ++i) { + let state = this.states()[i]; + if (state.reflectAnimationId > 0) return state.reflectAnimationId; + } + return Yanfly.Param.BECReflectAni; + } + + public spriteCanMove() { + if (!$gameSystem.isSideView()) return false; + for (let i = 0; i < this.states().length; ++i) { + let state = this.states()[i]; + if (state.spriteCannotMove) return false; + } + return this.canMove(); + } + + public spritePosX() { + if ($gameSystem.isSideView() && this.battler()) { + return this.battler().x; + } else if (this.battler()) { + return this.battler().x; + } else { + return 0; + } + } + + public spritePosY() { + if ($gameSystem.isSideView() && this.battler()) { + return this.battler().y; + } else if (this.battler()) { + return this.battler().y; + } else { + return 0; + } + } + + public spriteWidth() { + if ( + $gameSystem.isSideView() && + this.battler() && + this.battler().bitmap + ) { + return this.battler().bitmap.width; + } else if (this.battler() && this.battler().bitmap) { + return this.battler().bitmap.width; + } else { + return 1; + } + } + + public spriteHeight() { + if ( + $gameSystem.isSideView() && + this.battler() && + this.battler().bitmap + ) { + return this.battler().bitmap.height; + } else if (this.battler() && this.battler().bitmap) { + return this.battler().bitmap.height; + } else { + return 1; + } + } + + public anchorX() { + return Yanfly.Param.BECAnchorX; + } + + public anchorY() { + return Yanfly.Param.BECAnchorY; + } + + public spriteHomeX() { + if ($gameSystem.isSideView() && this.battler()) { + return this.battler().homeX; + } else { + return 0; + } + } + + public spriteHomeY() { + if ($gameSystem.isSideView() && this.battler()) { + return this.battler().homeY; + } else { + return 0; + } + } + + public setMirror(value) { + if ( + $gameSystem.isSideView() && + this.battler() && + this.spriteCanMove() + ) { + this.battler().setMirror(value); + } + } + + public spriteFaceForward() { + this.setMirror(false); + } + + public spriteFaceBackward() { + this.setMirror(true); + } + + public spriteFacePoint(pointX, pointY) { + if (this.spritePosX() > pointX) { + this.spriteFaceBackward(); + } else { + this.spriteFaceForward(); + } + } + + public spriteFaceAwayPoint(pointX, pointY) { + if (this.spritePosX() > pointX) { + this.spriteFaceForward(); + } else { + this.spriteFaceBackward(); + } + } + + public spriteFaceTarget(target) { + if (!target) return; + let pointX = target.spritePosX(); + let pointY = target.spritePosY(); + this.spriteFacePoint(pointX, pointY); + } + + public spriteFaceAwayTarget(target) { + if (!target) return; + let pointX = target.spritePosX(); + let pointY = target.spritePosY(); + this.spriteFaceAwayPoint(pointX, pointY); + } + + public spriteFaceHome() { + let pointX = this.spriteHomeX(); + let pointY = this.spriteHomeY(); + this.spriteFacePoint(pointX, pointY); + } + + public spriteFaceAwayHome() { + let pointX = this.spriteHomeX(); + let pointY = this.spriteHomeY(); + this.spriteFaceAwayPoint(pointX, pointY); + } + + public attackMotion() { + return "thrust"; + } + + public performAttack() {} + + public forceMotionRefresh() { + if (!$gameParty.inBattle()) return; + if (this.battler()) this.battler().refreshMotion(); + } + + public requestMotionRefresh() { + let deadMotion = this.deadMotion(); + if (this.isDead() && this._motionType !== deadMotion) { + this.requestMotion(deadMotion); + } + if (this.isDead() && this._motionType === deadMotion) return; + if (this._motionType === "victory") return; + if (this._motionType === "escape" && !BattleManager.isInputting()) + return; + if (this._motionType === "guard" && !BattleManager.isInputting()) + return; + this.clearMotion(); + if (this.battler() && BattleManager.isInputting()) { + this.battler().refreshMotion(); + } + } + + public onTurnStart() { + this.updateStateTurnStart(); + } + + public onTurnEnd() { + this.clearResult(); + if (BattleManager.isTurnBased()) { + this.regenerateAll(); + } else if (BattleManager.isTickBased() && !BattleManager.isTurnEnd()) { + this.regenerateAll(); + } + this.removeStatesAuto(2); + } + + public updateTick() { + if (BattleManager.timeBasedStates()) this.updateStateTicks(); + if (BattleManager.timeBasedBuffs()) this.updateBuffTicks(); + } + + public increaseSelfTurnCount() { + if (this._selfTurnCount === undefined) this._selfTurnCount = 0; + this._selfTurnCount += 1; + } + + public turnCount() { + if (BattleManager.isTurnBased()) return $gameTroop.turnCount(); + if (BattleManager.isTickBased() && Yanfly.Param.BECAISelfTurn) { + return this._selfTurnCount; + } + return $gameTroop.turnCount(); + } + + public createActions() { + if (this.currentAction()) return; + this.makeActions(); + } + + public canAddStateFreeTurn(stateId) { + if (!$gameParty.inBattle()) return false; + if (BattleManager.subject !== this) return false; + if ($dataStates[stateId].autoRemovalTiming !== 1) return false; + // if (Imported.YEP_BuffsStatesCore) { + // if ($dataStates[stateId].reapplyRules === 0) return false; + // } + return true; + } + + public setStateFreeTurn(stateId) { + this._freeStateTurn = this._freeStateTurn || []; + this._freeStateTurn.push(stateId); + } + + public idleMotion() { + return "walk"; + } + + public deadMotion() { + return "dead"; + } + + public sleepMotion() { + return "sleep"; + } + + public chantMotion() { + return "chant"; + } + + public guardMotion() { + return "guard"; + } + + public abnormalMotion() { + return "abnormal"; + } + + public dyingMotion() { + return "dying"; + } + + public waitMotion() { + return "wait"; + } + + public recoverAll() { + super.recoverAll(); + if ($gameParty.inBattle()) this.forceMotionRefresh(); + } + + public updateBuffTicks() { + let needRefresh = false; + for (let i = 0; i < this._buffTurns.length; i++) { + if (this._buffTurns[i] <= 0) continue; + let value = BattleManager.tickRate() / Yanfly.Param.BECTurnTime; + let shown1 = Math.ceil(this._buffTurns[i]); + this._buffTurns[i] -= value; + let shown2 = Math.ceil(this._buffTurns[i]); + if (shown1 !== shown2) needRefresh = true; + if (this._buffTurns[i] <= 0) this.removeBuff(i); + } + if (needRefresh) this.refresh(); + } } diff --git a/ts/objects/Game_BattlerBase.ts b/ts/objects/Game_BattlerBase.ts index ecdf517..f80d3d5 100644 --- a/ts/objects/Game_BattlerBase.ts +++ b/ts/objects/Game_BattlerBase.ts @@ -1,5 +1,8 @@ import { Utils } from "../core/Utils"; import { DataManager } from "../managers/DataManager"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; +import { BattleManager } from "../managers/BattleManager"; +import { Game_ActionResult } from "./Game_ActionResult"; export interface Game_BattlerBase_OnLoad { _hp: any; @@ -11,6 +14,7 @@ export interface Game_BattlerBase_OnLoad { _stateTurns: number[]; _buffs: number[]; _buffTurns: number[]; + _result: Game_ActionResult; } export class Game_BattlerBase { @@ -45,15 +49,26 @@ export class Game_BattlerBase { public static ICON_BUFF_START = 32; public static ICON_DEBUFF_START = 48; - private _hp: any; - private _mp: any; - private _tp: any; - private _hidden: boolean; - private _paramPlus: number[]; - private _states: number[]; - private _stateTurns: number[]; - private _buffs: number[]; - private _buffTurns: number[]; + protected _hp: any; + protected _mp: any; + protected _tp: any; + protected _hidden: boolean; + protected _paramPlus: number[]; + protected _states: number[]; + protected _stateTurns: number[]; + + protected _baseParamCache: any; + protected _paramLimitMin: number[]; + protected _paramLimitMax: number[]; + protected _xparamPlus: number[]; + protected _xparam: any; + protected _immortalState: any; + protected _statusRefreshRequested: boolean; + protected _freeStateTurn: any; + + protected _buffs: number[]; + protected _buffTurns: number[]; + protected _result: Game_ActionResult; public constructor(gameLoadInput?: Game_BattlerBase_OnLoad) { this.initMembers(); @@ -66,8 +81,7 @@ export class Game_BattlerBase { this._paramPlus = gameLoadInput._paramPlus; this._states = gameLoadInput._states; this._stateTurns = gameLoadInput._stateTurns; - this._buffs = gameLoadInput._buffs; - this._buffTurns = gameLoadInput._buffTurns; + this._result = gameLoadInput._result; } } @@ -203,12 +217,23 @@ export class Game_BattlerBase { this.clearParamPlus(); this.clearStates(); this.clearBuffs(); + this.clearCustomParamLimits(); + this.clearXParamPlus(); + } + + public clearCustomParamLimits() { + this._paramLimitMin = [0, 0, 0, 0, 0, 0, 0, 0]; + this._paramLimitMax = [0, 0, 0, 0, 0, 0, 0, 0]; } public clearParamPlus() { this._paramPlus = [0, 0, 0, 0, 0, 0, 0, 0]; } + public clearXParamPlus() { + this._xparamPlus = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + } + public clearStates() { this._states = []; this._stateTurns = []; @@ -244,14 +269,6 @@ export class Game_BattlerBase { return this._stateTurns[stateId] === 0; } - public updateStateTurns() { - this._states.forEach(function(stateId) { - if (this._stateTurns[stateId] > 0) { - this._stateTurns[stateId]--; - } - }, this); - } - public clearBuffs() { this._buffs = [0, 0, 0, 0, 0, 0, 0, 0]; this._buffTurns = [0, 0, 0, 0, 0, 0, 0, 0]; @@ -434,21 +451,51 @@ export class Game_BattlerBase { } public paramMin(paramId) { - if (paramId === 1) { - return 0; // MMP - } else { - return 1; + const customMin = this.customParamMin(paramId); + const a = this; + const user = this; + const subject = this; + const b = this; + const target = this; + const s = $gameSwitches._data; + const v = $gameVariables._data; + const code = Yanfly.Param.BPCMinimum[paramId]; + let value = 0; + try { + value = eval(code); + } catch (e) { + Yanfly.Util.displayError(e, code, "CUSTOM PARAM MIN FORMULA ERROR"); } + value = Math.ceil(value); + return value; } public paramMax(paramId) { - if (paramId === 0) { - return 999999; // MHP - } else if (paramId === 1) { - return 9999; // MMP - } else { - return 999; + const customMax = this.customParamMax(paramId); + const a = this; + const user = this; + const subject = this; + const b = this; + const target = this; + const s = $gameSwitches._data; + const v = $gameVariables._data; + const code = Yanfly.Param.BPCMaximum[paramId]; + let value = 0; + try { + value = eval(code); + } catch (e) { + Yanfly.Util.displayError(e, code, "CUSTOM PARAM MAX FORMULA ERROR"); + } + value = Math.ceil(value); + return value; + } + + public customParamMax(paramId: any) { + if (!this._paramLimitMax) { + this.clearCustomParamLimits(); } + const value = this._paramLimitMax[paramId]; + return value; } public paramRate(paramId) { @@ -459,16 +506,66 @@ export class Game_BattlerBase { return this._buffs[paramId] * 0.25 + 1.0; } - public param(paramId) { - let value = this.paramBase(paramId) + this.paramPlus(paramId); - value *= this.paramRate(paramId) * this.paramBuffRate(paramId); - const maxValue = this.paramMax(paramId); - const minValue = this.paramMin(paramId); - return Math.round(Utils.clamp(value, minValue, maxValue)); + public customParamMin(paramId) { + if (!this._paramLimitMin) { + this.clearCustomParamLimits(); + } + const value = this._paramLimitMin[paramId]; + return value; } - public xparam(xparamId) { - return this.traitsSum(Game_BattlerBase.TRAIT_XPARAM, xparamId); + public param(paramId) { + this._baseParamCache = this._baseParamCache || []; + if (this._baseParamCache[paramId]) { + return this._baseParamCache[paramId]; + } + const base = this.paramBase(paramId); + const plus = this.paramPlus(paramId); + const paramRate = this.paramRate(paramId); + const buffRate = this.paramBuffRate(paramId); + const flat = this.paramFlat(paramId); + const minValue = this.paramMin(paramId); + const maxValue = Math.max(minValue, this.paramMax(paramId)); + const a = this; + const user = this; + const subject = this; + const b = this; + const target = this; + const s = $gameSwitches._data; + const v = $gameVariables._data; + const code = Yanfly.Param.BPCFormula[paramId]; + let value = 0; + try { + value = eval(code); + } catch (e) { + Yanfly.Util.displayError(e, code, "CUSTOM PARAM FORMULA ERROR"); + } + value = Math.round(Utils.clamp(value, minValue, maxValue)); + this._baseParamCache[paramId] = value; + return this._baseParamCache[paramId]; + } + + public xparam(id) { + if (this._xparam && this._xparam[id] !== undefined) + return this._xparam[id]; + if (this._xparam === undefined) this._xparam = {}; + const base = this.traitsSum(Game_BattlerBase.TRAIT_XPARAM, id); + const plus = this.xparamPlus(id); + const rate = this.xparamRate(id); + const flat = this.xparamFlat(id); + const a = this; + const user = this; + const subject = this; + const s = $gameSwitches._data; + const v = $gameVariables._data; + const code = Yanfly.Param.XParamFormula[id]; + try { + this._xparam[id] = eval(code); + } catch (e) { + this._xparam[id] = 0; + Yanfly.Util.displayError(e, code, "EXTRA PARAM FORMULA ERROR"); + } + return this._xparam[id]; } public sparam(sparamId) { @@ -492,9 +589,14 @@ export class Game_BattlerBase { } public isStateResist(stateId) { + if (stateId === this.deathStateId() && this.isImmortal()) return true; return this.stateResistSet().indexOf(stateId) > -1; } + public isImmortal() { + return this._immortalState; + } + public attackElements() { return this.traitsSet(Game_BattlerBase.TRAIT_ATTACK_ELEMENT); } @@ -635,16 +737,19 @@ export class Game_BattlerBase { } public setHp(hp) { + if (this._hp === hp) return; this._hp = hp; this.refresh(); } public setMp(mp) { + if (this._mp === mp) return; this._mp = mp; this.refresh(); } public setTp(tp) { + if (this._tp === tp) return; this._tp = tp; this.refresh(); } @@ -660,12 +765,14 @@ export class Game_BattlerBase { this._hp = Utils.clamp(this._hp, 0, this.mhp); this._mp = Utils.clamp(this._mp, 0, this.mmp); this._tp = Utils.clamp(this._tp, 0, this.maxTp()); + this._xparam = undefined; } public recoverAll() { this.clearStates(); this._hp = this.mhp; this._mp = this.mmp; + this.refresh(); } public hpRate() { @@ -826,6 +933,7 @@ export class Game_BattlerBase { } public paySkillCost(skill) { + this.requestStatusRefresh(); this._mp -= this.skillMpCost(skill); this._tp -= this.skillTpCost(skill); } @@ -909,4 +1017,530 @@ export class Game_BattlerBase { public canGuard() { return this.canUse($dataSkills[this.guardSkillId()]); } + + public mapRegenUpdateCheck(type) { + if ($gameParty.inBattle()) return true; + if (type === "hp") { + return Yanfly.Param.RefreshUpdateHp; + } else if (type === "mp") { + return Yanfly.Param.RefreshUpdateMp; + } else if (type === "tp") { + return Yanfly.Param.RefreshUpdateTp; + } + } + + public setParam(id, value) { + this._paramPlus[id] = 0; + this._baseParamCache = []; + this._paramPlus[id] = value - this.param(id); + this.refresh(); + } + + public setMaxHp(value) { + this.setParam(0, value); + } + + public setMaxMp(value) { + this.setParam(1, value); + } + + public setAtk(value) { + this.setParam(2, value); + } + + public setDef(value) { + this.setParam(3, value); + } + + public setMat(value) { + this.setParam(4, value); + } + + public setMdf(value) { + this.setParam(5, value); + } + + public setAgi(value) { + this.setParam(6, value); + } + + public setLuk(value) { + this.setParam(7, value); + } + + public setParamPlus(id, value) { + this._paramPlus[id] = value; + this.refresh(); + } + + public setMaxHpPlus(value) { + this.setParamPlus(0, value); + } + + public setMaxMpPlus(value) { + this.setParamPlus(1, value); + } + + public setAtkPlus(value) { + this.setParamPlus(2, value); + } + + public setDefPlus(value) { + this.setParamPlus(3, value); + } + + public setMatPlus(value) { + this.setParamPlus(4, value); + } + + public setMdfPlus(value) { + this.setParamPlus(5, value); + } + + public setAgiPlus(value) { + this.setParamPlus(6, value); + } + + public setLukPlus(value) { + this.setParamPlus(7, value); + } + + public addMaxHp(value) { + this.addParam(0, value); + } + + public addMaxMp(value) { + this.addParam(1, value); + } + + public addAtk(value) { + this.addParam(2, value); + } + + public addDef(value) { + this.addParam(3, value); + } + + public addMat(value) { + this.addParam(4, value); + } + + public addMdf(value) { + this.addParam(5, value); + } + + public addAgi(value) { + this.addParam(6, value); + } + + public addLuk(value) { + this.addParam(7, value); + } + + public minusMaxHp(value) { + this.addParam(0, -value); + } + + public minusMaxMp(value) { + this.addParam(1, -value); + } + + public minusAtk(value) { + this.addParam(2, -value); + } + + public minusDef(value) { + this.addParam(3, -value); + } + + public minusMat(value) { + this.addParam(4, -value); + } + + public minusMdf(value) { + this.addParam(5, -value); + } + + public minusAgi(value) { + this.addParam(6, -value); + } + + public minusLuk(value) { + this.addParam(7, -value); + } + + public setCustomParamLimitMax(id, value) { + if (!this._paramLimitMax) this.clearCustomParamLimits(); + this._paramLimitMax[id] = value; + this.refresh(); + } + + public setCustomMaxHpMax(value) { + this.setCustomParamLimitMax(0, value); + } + + public setCustomMaxMpMax(value) { + this.setCustomParamLimitMax(1, value); + } + + public setCustomAtkMax(value) { + this.setCustomParamLimitMax(2, value); + } + + public setCustomDefMax(value) { + this.setCustomParamLimitMax(3, value); + } + + public setCustomMatMax(value) { + this.setCustomParamLimitMax(4, value); + } + + public setCustomMdfMax(value) { + this.setCustomParamLimitMax(5, value); + } + + public setCustomAgiMax(value) { + this.setCustomParamLimitMax(6, value); + } + + public setCustomLukMax(value) { + this.setCustomParamLimitMax(7, value); + } + + public setCustomParamLimitMin(id, value) { + if (!this._paramLimitMin) this.clearCustomParamLimits(); + this._paramLimitMin[id] = value; + this.refresh(); + } + + public setCustomMaxHpMin(value) { + this.setCustomParamLimitMin(0, value); + } + + public setCustomMaxMpMin(value) { + this.setCustomParamLimitMin(1, value); + } + + public setCustomAtkMin(value) { + this.setCustomParamLimitMin(2, value); + } + + public setCustomDefMin(value) { + this.setCustomParamLimitMin(3, value); + } + + public setCustomMatMin(value) { + this.setCustomParamLimitMin(4, value); + } + + public setCustomMdfMin(value) { + this.setCustomParamLimitMin(5, value); + } + + public setCustomAgiMin(value) { + this.setCustomParamLimitMin(6, value); + } + + public setCustomLukMin(value) { + this.setCustomParamLimitMin(7, value); + } + + public xparamPlus(id) { + if (this._xparamPlus === undefined) this.clearXParamPlus(); + return this._xparamPlus[id]; + } + + public xparamRate(id) { + return 1; + } + + public xparamFlat(id) { + return 0; + } + + public setXParam(id, value) { + if (this._xparamPlus === undefined) this.clearXParamPlus(); + this._xparam = {}; + this._xparamPlus[id] = 0; + this._xparamPlus[id] = value - this.xparam(id); + this.refresh(); + } + + public setHit(value) { + this.setXParam(0, value); + } + + public setEva(value) { + this.setXParam(1, value); + } + + public setCri(value) { + this.setXParam(2, value); + } + + public setCev(value) { + this.setXParam(3, value); + } + + public setMev(value) { + this.setXParam(4, value); + } + + public setMrf(value) { + this.setXParam(5, value); + } + + public setCnt(value) { + this.setXParam(6, value); + } + + public setHrg(value) { + this.setXParam(7, value); + } + + public setMrg(value) { + this.setXParam(8, value); + } + + public setTrg(value) { + this.setXParam(9, value); + } + + public setXParamPlus(id, value) { + if (this._xparamPlus === undefined) this.clearXParamPlus(); + this._xparamPlus[id] = value; + this.refresh(); + } + + public setHitPlus(value) { + this.setXParamPlus(0, value); + } + + public setEvaPlus(value) { + this.setXParamPlus(1, value); + } + + public setCriPlus(value) { + this.setXParamPlus(2, value); + } + + public setCevPlus(value) { + this.setXParamPlus(3, value); + } + + public setMevPlus(value) { + this.setXParamPlus(4, value); + } + + public setMrfPlus(value) { + this.setXParamPlus(5, value); + } + + public setCntPlus(value) { + this.setXParamPlus(6, value); + } + + public setHrgPlus(value) { + this.setXParamPlus(7, value); + } + + public setMrgPlus(value) { + this.setXParamPlus(8, value); + } + + public setTrgPlus(value) { + this.setXParamPlus(9, value); + } + + public addXParam(id, value) { + if (this._xparamPlus === undefined) this.clearXParamPlus(); + this._xparamPlus[id] += value; + this.refresh(); + } + + public addHit(value) { + this.addXParam(0, value); + } + + public addEva(value) { + this.addXParam(1, value); + } + + public addCri(value) { + this.addXParam(2, value); + } + + public addCev(value) { + this.addXParam(3, value); + } + + public addMev(value) { + this.addXParam(4, value); + } + + public addMrf(value) { + this.addXParam(5, value); + } + + public addCnt(value) { + this.addXParam(6, value); + } + + public addHrg(value) { + this.addXParam(7, value); + } + + public addMrg(value) { + this.addXParam(8, value); + } + + public addTrg(value) { + this.addXParam(9, value); + } + + public minusHit(value) { + this.addXParam(0, -value); + } + + public minusEva(value) { + this.addXParam(1, -value); + } + + public minusCri(value) { + this.addXParam(2, -value); + } + + public minusCev(value) { + this.addXParam(3, -value); + } + + public minusMev(value) { + this.addXParam(4, -value); + } + + public minusMrf(value) { + this.addXParam(5, -value); + } + + public minusCnt(value) { + this.addXParam(6, -value); + } + + public minusHrg(value) { + this.addXParam(7, -value); + } + + public minusMrg(value) { + this.addXParam(8, -value); + } + + public minusTrg(value) { + this.addXParam(9, -value); + } + + public requestStatusRefresh() { + this._statusRefreshRequested = true; + } + + public isStatusRefreshRequested() { + return this._statusRefreshRequested; + } + + public completetStatusRefreshRequest() { + this._statusRefreshRequested = false; + } + + public updateStateTicks() { + let needRefresh = false; + for (let i = 0; i < this._states.length; ++i) { + let stateId = this._states[i]; + let state = $dataStates[stateId]; + if (!state) continue; + if (state.autoRemovalTiming !== 2) continue; + if (!this._stateTurns[stateId]) continue; + let value = BattleManager.tickRate() / Yanfly.Param.BECTurnTime; + let shown1 = Math.ceil(this._stateTurns[stateId]); + this._stateTurns[stateId] -= value; + let shown2 = Math.ceil(this._stateTurns[stateId]); + if (shown1 !== shown2) needRefresh = true; + if (this._stateTurns[stateId] <= 0) this.removeState(stateId); + } + if (needRefresh) this.refresh(); + } + + public isBypassUpdateTurns() { + if ($gameTroop.isEventRunning()) return true; + return false; + } + + public updateStateTurns() { + this.updateStateTurnEnd(); + } + + public updateStateTurnTiming(timing) { + if (this.isBypassUpdateTurns()) return; + let statesRemoved = []; + this._freeStateTurn = this._freeStateTurn || []; + for (let i = 0; i < this._states.length; ++i) { + let stateId = this._states[i]; + let state = $dataStates[stateId]; + if (!state) continue; + if (state.autoRemovalTiming !== timing) continue; + if (!this._stateTurns[stateId]) continue; + if (this._freeStateTurn.includes(stateId)) { + let index = this._freeStateTurn.indexOf(stateId); + this._freeStateTurn.splice(index, 1); + } else { + this._stateTurns[stateId] -= 1; + } + if (this._stateTurns[stateId] <= 0) statesRemoved.push(stateId); + } + for (let i = 0; i < statesRemoved.length; ++i) { + let stateId = statesRemoved[i]; + this.removeState(stateId); + } + } + + public updateStateActionStart() { + this.updateStateTurnTiming(3); + } + + public updateStateActionEnd() { + this.updateStateTurnTiming(1); + } + + public updateStateTurnStart() { + this.updateStateTurnTiming(4); + } + + public updateStateTurnEnd() { + this.updateStateTurnTiming(2); + } + + public timedTick() { + return 1 * BattleManager.tickRate(); + } + + public paramFlat(paramId: number) { + let value = 0; + const length = this.states().length; + for (let i = 0; i < length; ++i) { + const obj = this.states()[i]; + if (obj && obj.flatParams) { + value += obj.flatParams[paramId]; + } + } + return value; + } + + public removeState(stateId) { + if (this.isStateAffected(stateId)) { + if (stateId === this.deathStateId()) { + this.revive(); + } + this.eraseState(stateId); + this.refresh(); + this._result.pushRemovedState(stateId); + } + } } diff --git a/ts/objects/Game_Character.ts b/ts/objects/Game_Character.ts index 9b6ecf7..89a516d 100644 --- a/ts/objects/Game_Character.ts +++ b/ts/objects/Game_Character.ts @@ -4,6 +4,8 @@ import { Game_CharacterBase, Game_CharacterBase_OnLoad } from "./Game_CharacterBase"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; +import { JsonEx } from "../core/JsonEx"; export interface Game_Character_OnLoad extends Game_CharacterBase_OnLoad { _moveRouteForcing: boolean; @@ -112,9 +114,14 @@ export class Game_Character extends Game_CharacterBase { } public setMoveRoute(moveRoute) { - this._moveRoute = moveRoute; - this._moveRouteIndex = 0; - this._moveRouteForcing = false; + moveRoute = JsonEx.makeDeepCopy(moveRoute); + if (!this.isMoveRouteForcing()) { + this._moveRoute = moveRoute; + this._moveRouteIndex = 0; + this._moveRouteForcing = false; + } else { + this.queueMoveRoute(moveRoute); + } } public forceMoveRoute(moveRoute) { @@ -291,31 +298,375 @@ export class Game_Character extends Game_CharacterBase { AudioManager.playSe(params[0]); break; case gc.ROUTE_SCRIPT: - try { - eval(params[0]); - } catch (error) { - if (this._callerEventInfo) { - for (var key in this._callerEventInfo) { - error[key] = this._callerEventInfo[key]; - } - error.line += this._moveRouteIndex + 1; - error.eventCommand = "set_route_script"; - error.content = command.parameters[0]; - } else { - error.eventType = "map_event"; - // error.mapId = this._mapId; - // error.mapEventId = this._eventId; - // error.page = this._pageIndex + 1; - error.line = this._moveRouteIndex + 1; - error.eventCommand = "auto_route_script"; - error.content = command.parameters[0]; - } - throw error; - } + $gameTemp.moveCommand = command; + this.processMoveRouteScriptCall(command.parameters[0]); break; } } + public checkCollisionKeywords(line) { + if (line.match(/(?:CRASH|COLLIDE|COLLISION|ENCOUNTER|TOUCH)/i)) { + return true; + } else if (line.match(/(?:AVOID|EVADE|DODGE)/i)) { + return false; + } else { + return false; + } + } + + public processMoveRouteEval(code) { + let a = this; + let b = this; + let player = $gamePlayer; + let s = $gameSwitches._data; + let v = $gameVariables._data; + try { + eval(code); + } catch (e) { + Yanfly.Util.displayError(e, code, "MOVE ROUTE SCRIPT ERROR"); + } + } + + public processMoveRouteScriptCall(line) { + // EVAL + if (line.match(/EVAL:[ ](.*)/i)) { + this.processMoveRouteEval(String(RegExp.$1)); + // ANIMATION + } else if (line.match(/(?:ANIMATION|REQUEST ANIMATION):[ ](\d+)/i)) { + const x = parseInt(RegExp.$1); + this.requestAnimation(x); + // ICON BALLOON + } else if ( + line.match(/(?:ICON BALLOON|REQUEST ICON BALLOON):[ ](.*)/i) + ) { + const str = String(RegExp.$1); + this.processMoveRouteIconBalloon(str); + // BALLOON + } else if (line.match(/(?:BALLOON|REQUEST BALLOON):[ ](.*)/i)) { + const str = String(RegExp.$1); + this.processMoveRouteBalloon(str); + // JUMP FORWARD + } else if (line.match(/(?:JUMP FORWARD|JUMP FORWARDS):[ ](\d+)/i)) { + const x = parseInt(RegExp.$1); + this.jumpForward(x); + // JUMP TO: POINT + } else if ( + line.match(/JUMP[ ](?:TO|TOWARD|TOWARDS):[ ](\d+),[ ](\d+)/i) + ) { + const x = parseInt(RegExp.$1); + const y = parseInt(RegExp.$2); + this.jumpToPoint(x, y); + // JUMP TO: EVENT + } else if ( + line.match(/JUMP[ ](?:TO|TOWARD|TOWARDS):[ ]EVENT[ ](\d+)/i) + ) { + const x = parseInt(RegExp.$1); + this.jumpToEvent(x); + // JUMP TO: PLAYER + } else if (line.match(/JUMP[ ](?:TO|TOWARD|TOWARDS):[ ]PLAYER/i)) { + this.jumpToEvent(0); + // MOVE TO: POINT + } else if ( + line.match(/MOVE[ ](?:TO|TOWARD|TOWARDS):[ ](\d+),[ ](\d+)/i) + ) { + const x = parseInt(RegExp.$1); + const y = parseInt(RegExp.$2); + const collision = this.checkCollisionKeywords(line); + this.moveToPoint(x, y, collision); + // MOVE TO: EVENT + } else if ( + line.match(/MOVE[ ](?:TO|TOWARD|TOWARDS):[ ]EVENT[ ](\d+)/i) + ) { + const x = parseInt(RegExp.$1); + const collision = this.checkCollisionKeywords(line); + this.moveToEvent(x, collision); + // MOVE TO: PLAYER + } else if (line.match(/MOVE[ ](?:TO|TOWARD|TOWARDS):[ ]PLAYER/i)) { + this.moveToEvent(0); + // PATTERN LOCK + } else if (line.match(/(?:PATTERN LOCK):[ ](\d+)/i)) { + const x = parseInt(RegExp.$1); + this.patternLock(x); + // PATTERN UNLOCK + } else if (line.match(/(?:PATTERN UNLOCK)/i)) { + this.patternUnlock(); + // SELF SWITCH: ON + } else if (line.match(/(?:SELF SWITCH)[ ](.*):[ ]ON/i)) { + const str = String(RegExp.$1); + this.processMoveRouteSelfSwitch(str, "on"); + // SELF SWITCH: OFF + } else if (line.match(/(?:SELF SWITCH)[ ](.*):[ ]OFF/i)) { + const str = String(RegExp.$1); + this.processMoveRouteSelfSwitch(str, "off"); + // SELF SWITCH: TOGGLE + } else if (line.match(/(?:SELF SWITCH)[ ](.*):[ ]TOGGLE/i)) { + const str = String(RegExp.$1); + this.processMoveRouteSelfSwitch(str, "toggle"); + // SELF VARIABLE + } else if (line.match(/(?:SELF VARIABLE)[ ](.*):[ ](.*)/i)) { + const str = String(RegExp.$1); + const code = String(RegExp.$2); + this.processMoveRouteSelfVariable(str, code); + // STEP AWAY FROM: POINT + } else if ( + line.match(/(?:STEP AWAY|STEP AWAY FROM):[ ](\d+),[ ](\d+)/i) + ) { + const x = parseInt(RegExp.$1); + const y = parseInt(RegExp.$2); + this.stepAwayFromPoint(x, y); + // STEP AWAY FROM: EVENT + } else if ( + line.match(/(?:STEP AWAY|STEP AWAY FROM):[ ]EVENT[ ](\d+)/i) + ) { + const x = parseInt(RegExp.$1); + this.stepAwayFromEvent(x); + // STEP AWAY FROM: PLAYER + } else if (line.match(/(?:STEP AWAY|STEP AWAY FROM):[ ]PLAYER/i)) { + this.stepAwayFromEvent(0); + // STEP TOWARD: POINT + } else if ( + line.match(/(?:STEP TOWARD|STEP TOWARDS):[ ](\d+),[ ](\d+)/i) + ) { + const x = parseInt(RegExp.$1); + const y = parseInt(RegExp.$2); + this.stepTowardPoint(x, y); + // STEP TOWARD: EVENT + } else if ( + line.match(/(?:STEP TOWARD|STEP TOWARDS):[ ]EVENT[ ](\d+)/i) + ) { + const x = parseInt(RegExp.$1); + this.stepTowardEvent(x); + // STEP TOWARD: PLAYER + } else if (line.match(/(?:STEP TOWARD|STEP TOWARDS):[ ]PLAYER/i)) { + this.stepTowardEvent(0); + // TELEPORT: POINT + } else if (line.match(/(?:TELEPORT|TELEPORT TO):[ ](\d+),[ ](\d+)/i)) { + const x = parseInt(RegExp.$1); + const y = parseInt(RegExp.$2); + this.teleportToPoint(x, y); + // TELEPORT: EVENT + } else if (line.match(/(?:TELEPORT):[ ]EVENT[ ](\d+)/i)) { + const x = parseInt(RegExp.$1); + this.teleportToEvent(x); + // TELEPORT: PLAYER + } else if (line.match(/(?:TELEPORT):[ ]PLAYER/i)) { + this.teleportToEvent(0); + // TURN AWAY FROM: POINT + } else if ( + line.match(/(?:TURN AWAY FROM|TURN AWAY):[ ](\d+),[ ](\d+)/i) + ) { + const x = parseInt(RegExp.$1); + const y = parseInt(RegExp.$2); + this.turnAwayFromPoint(x, y); + // TURN AWAY FROM: EVENT + } else if ( + line.match(/(?:TURN AWAY FROM|TURN AWAY):[ ]EVENT[ ](\d+)/i) + ) { + const x = parseInt(RegExp.$1); + this.turnAwayFromEvent(x); + // TURN AWAY FROM: PLAYER + } else if (line.match(/(?:TURN AWAY FROM|TURN AWAY):[ ]PLAYER/i)) { + this.turnAwayFromEvent(0); + // TURN TOWARD: POINT + } else if ( + line.match(/(?:TURN TOWARD|TURN TOWARDS):[ ](\d+),[ ](\d+)/i) + ) { + const x = parseInt(RegExp.$1); + const y = parseInt(RegExp.$2); + this.turnTowardPoint(x, y); + // TURN TOWARD: EVENT + } else if ( + line.match(/(?:TURN TOWARD|TURN TOWARDS):[ ]EVENT[ ](\d+)/i) + ) { + const x = parseInt(RegExp.$1); + this.turnTowardEvent(x); + // TURN TOWARD: PLAYER + } else if (line.match(/(?:TURN TOWARD|TURN TOWARDS):[ ]PLAYER/i)) { + this.turnTowardEvent(0); + // MOVE DIRECTION + } else if (line.match(/(?:MOVE LOWER LEFT|LOWER LEFT):[ ](\d+)/i)) { + const x = parseInt(RegExp.$1); + this.moveRepeat(1, x); + } else if (line.match(/(?:MOVE LOWER RIGHT|LOWER RIGHT):[ ](\d+)/i)) { + const x = parseInt(RegExp.$1); + this.moveRepeat(3, x); + } else if (line.match(/(?:MOVE UPPER LEFT|UPPER LEFT):[ ](\d+)/i)) { + const x = parseInt(RegExp.$1); + this.moveRepeat(7, x); + } else if (line.match(/(?:MOVE UPPER RIGHT|UPPER RIGHT):[ ](\d+)/i)) { + const x = parseInt(RegExp.$1); + this.moveRepeat(9, x); + } else if (line.match(/(?:MOVE UP|UP):[ ](\d+)/i)) { + const x = parseInt(RegExp.$1); + this.moveRepeat(8, x); + } else if (line.match(/(?:MOVE DOWN|DOWN):[ ](\d+)/i)) { + const x = parseInt(RegExp.$1); + this.moveRepeat(2, x); + } else if (line.match(/(?:MOVE LEFT|LEFT):[ ](\d+)/i)) { + const x = parseInt(RegExp.$1); + this.moveRepeat(4, x); + } else if (line.match(/(?:MOVE RIGHT|RIGHT):[ ](\d+)/i)) { + const x = parseInt(RegExp.$1); + this.moveRepeat(6, x); + // ELSE/EVAL + } else { + this.processMoveRouteEval(line); + } + } + + public processMoveRouteIconBalloon(str) { + console.log("Yanfly Balloon plugin isn't in the engine"); + // if (!Yanfly.IBalloon) return; + // if (str.match(/(\d+)[ ]TO[ ](\d+)/i)) { + // const iconIndex1 = parseInt(RegExp.$1); + // const iconIndex2 = parseInt(RegExp.$2); + // } else if (str.match(/(\d+)/i)) { + // const iconIndex1 = parseInt(RegExp.$1); + // const iconIndex2 = iconIndex1; + // } else { + // return; + // } + // this.setIconBalloon(iconIndex1, iconIndex2); + } + + public processMoveRouteBalloon(str) { + let id = 0; + if (str.match(/(?:EXCLAMATION|\!)/i)) { + id = 1; + } else if (str.match(/(?:QUESTION|\?)/i)) { + id = 2; + } else if (str.match(/(?:MUSIC NOTE|MUSIC|NOTE)/i)) { + id = 3; + } else if (str.match(/(?:HEART|LOVE)/i)) { + id = 4; + } else if (str.match(/(?:ANGER)/i)) { + id = 5; + } else if (str.match(/(?:SWEAT)/i)) { + id = 6; + } else if (str.match(/(?:COBWEB)/i)) { + id = 7; + } else if (str.match(/(?:SILENCE|\.\.\.)/i)) { + id = 8; + } else if (str.match(/(?:LIGHT BULB|LIGHT|BULB)/i)) { + id = 9; + } else if (str.match(/(?:ZZZ|ZZ|Z)/i)) { + id = 10; + } else if (str.match(/(?:USER|USER-DEFINED|USER DEFINED)[ ](\d+)/i)) { + id = 10 + parseInt(RegExp.$1); + } + this.requestBalloon(id); + } + + public processMoveRouteSelfSwitch(str, steting) {} + + public processMoveRouteSelfVariable(str, code) {} + + public jumpForward(distance) { + distance = Math.round(distance); + const direction = this.direction(); + let dx = 0; + let dy = 0; + switch (direction) { + case 1: + dx = -distance; + dy = distance; + break; + case 2: + dy = distance; + break; + case 3: + dx = distance; + dy = distance; + break; + case 4: + dx = -distance; + break; + case 6: + dx = distance; + break; + case 7: + dx = -distance; + dy = -distance; + break; + case 8: + dy = -distance; + break; + case 9: + dx = distance; + dy = -distance; + break; + } + this.jump(dx, dy); + } + + public jumpToPoint(x, y) { + x = Math.round(x); + y = Math.round(y); + const dx = (this.x - x) * -1; + const dy = (this.y - y) * -1; + this.jump(dx, dy); + } + + public jumpToEvent(eventId) { + if (eventId === 0) { + const x = $gamePlayer.x; + const y = $gamePlayer.y; + this.jumpToPoint(x, y); + } else { + const ev = $gameMap.event(eventId); + if (!ev) return; + const x = ev.x; + const y = ev.y; + this.jumpToPoint(x, y); + } + } + + public moveRepeat(direction, times) { + times = times || 0; + times = Math.round(times); + const command = { + code: 1, + indent: null, + parameters: [] + }; + const gc = Game_Character; + switch (direction) { + case 1: + command.code = gc.ROUTE_MOVE_LOWER_L; + break; + case 2: + command.code = gc.ROUTE_MOVE_DOWN; + break; + case 3: + command.code = gc.ROUTE_MOVE_LOWER_R; + break; + case 4: + command.code = gc.ROUTE_MOVE_LEFT; + break; + case 5: + return; + break; + case 6: + command.code = gc.ROUTE_MOVE_RIGHT; + break; + case 7: + command.code = gc.ROUTE_MOVE_UPPER_L; + break; + case 8: + command.code = gc.ROUTE_MOVE_UP; + break; + case 9: + command.code = gc.ROUTE_MOVE_UPPER_R; + break; + } + const index = this._moveRoute.list.indexOf($gameTemp.moveCommand); + this._moveRoute = JsonEx.makeDeepCopy(this._moveRoute); + this._moveRoute.list[index].parameters[0] = ""; + while (times--) { + this._moveRoute.list.splice(this._moveRouteIndex + 1, 0, command); + } + } + public deltaXFrom(x) { return $gameMap.deltaX(this.x, x); } @@ -331,6 +682,179 @@ export class Game_Character extends Game_CharacterBase { } } + public moveToPoint(x, y, collision) { + collision = collision || false; + x = Math.round(x); + y = Math.round(y); + if (collision) $gameTemp.moveAllowPlayerCollision = true; + const direction = this.findDirectionTo(x, y); + if (collision) $gameTemp.moveAllowPlayerCollision = false; + if (direction > 0) this.moveStraight(direction); + if (this.x !== x || this.y !== y) this._moveRouteIndex -= 1; + this.setMovementSuccess(true); + } + + public moveTowardPoint(x, y, collision) { + this.moveToPoint(x, y, collision); + } + + public moveToEvent(eventId: number, collision?: boolean) { + collision = collision || false; + if (eventId === 0) { + const x = $gamePlayer.x; + const y = $gamePlayer.y; + this.moveToPoint(x, y, collision); + } else { + const ev = $gameMap.event(eventId); + if (!ev) return; + const x = ev.x; + const y = ev.y; + this.moveToPoint(x, y, collision); + } + } + + public patternLock(index) { + index = Math.round(index); + this._patternMoveRouteLocked = true; + this.setPattern(index); + } + + public patternUnlock() { + this._patternMoveRouteLocked = false; + } + + public stepAwayFromEvent(eventId) { + if (eventId === 0) { + const x = $gamePlayer.x; + const y = $gamePlayer.y; + this.stepAwayFromPoint(x, y); + } else { + const ev = $gameMap.event(eventId); + if (!ev) return; + const x = ev.x; + const y = ev.y; + this.stepAwayFromPoint(x, y); + } + } + + public stepTowardEvent(eventId) { + if (eventId === 0) { + const x = $gamePlayer.x; + const y = $gamePlayer.y; + this.stepTowardPoint(x, y); + } else { + const ev = $gameMap.event(eventId); + if (!ev) return; + const x = ev.x; + const y = ev.y; + this.stepTowardPoint(x, y); + } + } + + public teleportToPoint(x, y) { + x = Math.round(x); + y = Math.round(y); + this.locate(x, y); + } + + public teleportToEvent(eventId) { + if (eventId === 0) { + var x = $gamePlayer.x; + var y = $gamePlayer.y; + this.teleportToPoint(x, y); + } else { + var ev = $gameMap.event(eventId); + if (!ev) return; + var x = ev.x; + var y = ev.y; + this.teleportToPoint(x, y); + } + } + + public turnAwayFromPoint(x, y) { + x = Math.round(x); + y = Math.round(y); + var sx = this.deltaXFrom(x); + var sy = this.deltaYFrom(y); + if (Math.abs(sx) > Math.abs(sy)) { + this.setDirection(sx > 0 ? 6 : 4); + } else if (sy !== 0) { + this.setDirection(sy > 0 ? 2 : 8); + } + } + + public turnAwayFromEvent(eventId) { + if (eventId === 0) { + var x = $gamePlayer.x; + var y = $gamePlayer.y; + this.turnAwayFromPoint(x, y); + } else { + var ev = $gameMap.event(eventId); + if (!ev) return; + var x = ev.x; + var y = ev.y; + this.turnAwayFromPoint(x, y); + } + } + + public turnTowardPoint(x, y) { + x = Math.round(x); + y = Math.round(y); + var sx = this.deltaXFrom(x); + var sy = this.deltaYFrom(y); + if (Math.abs(sx) > Math.abs(sy)) { + this.setDirection(sx > 0 ? 4 : 6); + } else if (sy !== 0) { + this.setDirection(sy > 0 ? 8 : 2); + } + } + + public turnTowardEvent(eventId) { + if (eventId === 0) { + var x = $gamePlayer.x; + var y = $gamePlayer.y; + this.turnTowardPoint(x, y); + } else { + var ev = $gameMap.event(eventId); + if (!ev) return; + var x = ev.x; + var y = ev.y; + this.turnTowardPoint(x, y); + } + } + + public stepTowardPoint(x, y) { + const sx = this.deltaXFrom(Math.round(x)); + const sy = this.deltaYFrom(Math.round(y)); + if (Math.abs(sx) > Math.abs(sy)) { + this.moveStraight(sx > 0 ? 4 : 6); + if (!this.isMovementSucceeded() && sy !== 0) { + this.moveStraight(sy > 0 ? 8 : 2); + } + } else if (sy !== 0) { + this.moveStraight(sy > 0 ? 8 : 2); + if (!this.isMovementSucceeded() && sx !== 0) { + this.moveStraight(sx > 0 ? 4 : 6); + } + } + } + + public stepAwayFromPoint(x, y) { + const sx = this.deltaXFrom(Math.round(x)); + const sy = this.deltaYFrom(Math.round(y)); + if (Math.abs(sx) > Math.abs(sy)) { + this.moveStraight(sx > 0 ? 6 : 4); + if (!this.isMovementSucceeded() && sy !== 0) { + this.moveStraight(sy > 0 ? 2 : 8); + } + } else if (sy !== 0) { + this.moveStraight(sy > 0 ? 2 : 8); + if (!this.isMovementSucceeded() && sx !== 0) { + this.moveStraight(sx > 0 ? 6 : 4); + } + } + } + public moveTowardCharacter(character) { const sx = this.deltaXFrom(character.x); const sy = this.deltaYFrom(character.y); @@ -607,4 +1131,9 @@ export class Game_Character extends Game_CharacterBase { public searchLimit() { return 12; } + + public queueMoveRoute(moveRoute) { + this._originalMoveRoute = moveRoute; + this._originalMoveRouteIndex = 0; + } } diff --git a/ts/objects/Game_CharacterBase.ts b/ts/objects/Game_CharacterBase.ts index a64de3f..9f04164 100644 --- a/ts/objects/Game_CharacterBase.ts +++ b/ts/objects/Game_CharacterBase.ts @@ -66,6 +66,8 @@ export class Game_CharacterBase { private _jumpCount: number; private _jumpPeak: number; private _movementSuccess: boolean; + protected _isAlwaysUpdateMovement: boolean; + protected _patternMoveRouteLocked: boolean; public constructor(gameLoadInput?: Game_CharacterBase_OnLoad) { this.initMembers(); @@ -353,6 +355,7 @@ export class Game_CharacterBase { } public isNearTheScreen() { + if (this._isAlwaysUpdateMovement) return true; const gw = ConfigManager.fieldResolution.widthPx; const gh = ConfigManager.fieldResolution.heightPx; const tw = $gameMap.tileWidth(); @@ -442,6 +445,7 @@ export class Game_CharacterBase { } public updatePattern() { + if (this._patternMoveRouteLocked) return; if (!this.hasStepAnime() && this._stopCount > 0) { this.resetPattern(); } else { @@ -656,6 +660,7 @@ export class Game_CharacterBase { } public requestAnimation(animationId) { + animationId = Math.round(animationId); this._animationId = animationId; } diff --git a/ts/objects/Game_Enemy.ts b/ts/objects/Game_Enemy.ts index 0f56746..154eb8c 100644 --- a/ts/objects/Game_Enemy.ts +++ b/ts/objects/Game_Enemy.ts @@ -59,7 +59,7 @@ export class Game_Enemy extends Game_Battler { } public traitObjects() { - return super.traitObjects().concat(this.enemy()); + return super.traitObjects().concat(this.enemy() as any); } public paramBase(paramId) { @@ -156,7 +156,9 @@ export class Game_Enemy extends Game_Battler { public performActionStart(action) { super.performActionStart(action); - this.requestEffect("whiten"); + if (!$gameSystem.isSideView() || !this.spriteCanMove()) { + this.requestEffect("whiten"); + } } public performAction(action) { @@ -168,9 +170,13 @@ export class Game_Enemy extends Game_Battler { } public performDamage() { - super.performDamage(); - SoundManager.playEnemyDamage(); - this.requestEffect("blink"); + if ($gameSystem.isSideView()) { + super.performDamage(); + SoundManager.playEnemyDamage(); + } else { + SoundManager.playEnemyDamage(); + this.requestEffect("blink"); + } } public performCollapse() { @@ -224,15 +230,6 @@ export class Game_Enemy extends Game_Battler { } } - public meetsTurnCondition(param1, param2) { - const n = $gameTroop.turnCount(); - if (param2 === 0) { - return n === param1; - } else { - return n > 0 && n >= param1 && n % param2 === param1 % param2; - } - } - public meetsHpCondition(param1, param2) { return this.hpRate() >= param1 && this.hpRate() <= param2; } @@ -308,4 +305,98 @@ export class Game_Enemy extends Game_Battler { } this.setActionState("waiting"); } + + public paramPlus(paramId) { + let value = super.paramPlus(paramId); + value += this.enemy().plusParams[paramId]; + return value; + } + + public paramRate(paramId) { + let rate = super.paramRate(paramId); + rate *= this.enemy().rateParams[paramId]; + return rate; + } + + public paramFlat(paramId) { + let value = super.paramFlat(paramId); + value += this.enemy().flatParams[paramId]; + return value; + } + + public customParamMax(paramId) { + let value = super.customParamMax(paramId); + if (this.enemy().maxParams[paramId]) { + value = Math.max(value, this.enemy().maxParams[paramId]); + } + return value; + } + + public customParamMin(paramId) { + let value = super.customParamMin(paramId); + if (this.enemy().minParams[paramId]) { + value = Math.max(value, this.enemy().minParams[paramId]); + } + return value; + } + + public xparamPlus(id) { + let value = super.xparamPlus(id); + value += this.enemy().plusXParams[id]; + return value; + } + + public xparamRate(id) { + let value = super.xparamRate(id); + value *= this.enemy().rateXParams[id]; + return value; + } + + public xparamFlat(id) { + let value = super.xparamFlat(id); + value += this.enemy().flatXParams[id]; + return value; + } + + public skills() { + let skills = []; + for (let i = 0; i < this.enemy().actions.length; ++i) { + let skill = $dataSkills[this.enemy().actions[i].skillId]; + if (skill) skills.push(skill); + } + return skills; + } + + public attackAnimationId() { + return this.enemy().attackAnimationId; + } + + public attackAnimationId1() { + return this.attackAnimationId(); + } + + public attackAnimationId2() { + return this.attackAnimationId(); + } + + public reflectAnimationId() { + if (this.enemy().reflectAnimationId > 0) { + return this.enemy().reflectAnimationId; + } + return super.reflectAnimationId(); + } + + public spriteCanMove() { + if (this.enemy().spriteCannotMove) return false; + return super.spriteCanMove(); + } + + public meetsTurnCondition(param1, param2) { + let n = this.turnCount(); + if (param2 === 0) { + return n === param1; + } else { + return n > 0 && n >= param1 && n % param2 === param1 % param2; + } + } } diff --git a/ts/objects/Game_Event.ts b/ts/objects/Game_Event.ts index 0e4522f..ba49751 100644 --- a/ts/objects/Game_Event.ts +++ b/ts/objects/Game_Event.ts @@ -1,6 +1,7 @@ import { Utils } from "../core/Utils"; import { Game_Character, Game_Character_OnLoad } from "./Game_Character"; import { Game_Interpreter, Game_Interpreter_OnLoad } from "./Game_Interpreter"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; export interface Game_Event_OnLoad extends Game_Character_OnLoad { _mapId: number; @@ -104,6 +105,7 @@ export class Game_Event extends Game_Character { } public isCollidedWithPlayerCharacters(x, y) { + if ($gameTemp.moveAllowPlayerCollision) return false; return this.isNormalPriority() && $gamePlayer.isCollided(x, y); } @@ -132,7 +134,16 @@ export class Game_Event extends Game_Character { } } + public checkUpdateSelfMove() { + var note = this.event().note; + this._isAlwaysUpdateMovement = !!note.match( + //i + ); + } + public updateSelfMovement() { + if (this._isAlwaysUpdateMovement === undefined) + this.checkUpdateSelfMove(); if ( !this._locked && this.isNearTheScreen() && @@ -390,4 +401,44 @@ export class Game_Event extends Game_Character { super.forceMoveRoute(moveRoute); this._prelockDirection = 0; } + + public processMoveRouteSelfVariable(str, code) { + let keyName: string; + let value; + // if (!Imported.YEP_SelfSwVar) return; + if (str.match(/(\d+)/i)) { + keyName = "SELF VARIABLE " + parseInt(RegExp.$1); + } else { + keyName = str.toUpperCase(); + } + const key = [$gameMap.mapId(), this.eventId(), keyName]; + try { + value = eval(code); + } catch (e) { + value = 0; + Yanfly.Util.displayError( + e, + code, + "MOVE ROUTE SELF VARIABLE SCRIPT ERROR" + ); + } + $gameSelfSwitches.setValue(key, value); + } + + public processMoveRouteSelfSwitch(str, setting) { + let keyName: string; + if (str.match(/(\d+)/i)) { + keyName = "SELF SWITCH " + parseInt(RegExp.$1); + } else { + keyName = str.toUpperCase(); + } + const key = [$gameMap.mapId(), this.eventId(), keyName]; + if (setting.toUpperCase() === "ON") { + $gameSelfSwitches.setValue(key, true); + } else if (setting.toUpperCase() === "OFF") { + $gameSelfSwitches.setValue(key, false); + } else if (setting.toUpperCase() === "TOGGLE") { + $gameSelfSwitches.setValue(key, !$gameSelfSwitches.value(key)); + } + } } diff --git a/ts/objects/Game_Interpreter.ts b/ts/objects/Game_Interpreter.ts index ea895e5..e68e956 100644 --- a/ts/objects/Game_Interpreter.ts +++ b/ts/objects/Game_Interpreter.ts @@ -14,6 +14,7 @@ import { Scene_Shop } from "../scenes/Scene_Shop"; import { Scene_Title } from "../scenes/Scene_Title"; import { Window_MenuCommand } from "../windows/Window_MenuCommand"; import { Game_Character } from "./Game_Character"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; export interface Game_Interpreter_OnLoad { _depth: any; @@ -631,9 +632,13 @@ export class Game_Interpreter { let result = false; switch (this._params[0]) { case 0: // Switch - result = - $gameSwitches.value(this._params[1]) === - (this._params[2] === 0); + if (this._params[2] === 0) { + result = $gameSwitches.value(this._params[1]); + } else { + result = !$gameSwitches.value(this._params[1]); + } + this._branch[this._indent] = result; + if (this._branch[this._indent] === false) this.skipBranch(); break; case 1: // Variable const value1 = $gameVariables.value(this._params[1]); @@ -667,10 +672,14 @@ export class Game_Interpreter { case 2: // Self Switch if (this._eventId > 0) { const key = [this._mapId, this._eventId, this._params[1]]; - result = - $gameSelfSwitches.value(key) === - (this._params[2] === 0); + if (this._params[2] === 0) { + result = $gameSelfSwitches.value(key); + } else { + result = !$gameSelfSwitches.value(key); + } } + this._branch[this._indent] = result; + if (this._branch[this._indent] === false) this.skipBranch(); break; case 3: // Timer if ($gameTimer.isWorking()) { @@ -761,7 +770,19 @@ export class Game_Interpreter { result = Input.isPressed(this._params[1]); break; case 12: // Script - result = !!eval(this._params[1]); + const code = this._params[1]; + try { + result = !!eval(code); + } catch (e) { + result = false; + Yanfly.Util.displayError( + e, + code, + "CONDITIONAL BRANCH SCRIPT ERROR" + ); + } + this._branch[this._indent] = result; + if (this._branch[this._indent] === false) this.skipBranch(); break; case 13: // Vehicle result = @@ -910,7 +931,20 @@ export class Game_Interpreter { ); break; case 4: // Script - value = eval(this._params[4]); + value = 0; + var code = this._params[4]; + try { + value = eval(code); + } catch (e) { + Yanfly.Util.displayError( + e, + code, + "CONTROL VARIABLE SCRIPT ERROR" + ); + } + for (var i = this._params[0]; i <= this._params[1]; i++) { + this.operateVariable(i, this._params[2], value); + } break; } for (let i = this._params[0]; i <= this._params[1]; i++) { @@ -2151,7 +2185,11 @@ export class Game_Interpreter { this._index++; script += this.currentCommand().parameters[0] + "\n"; } - eval(script); + try { + eval(script); + } catch (e) { + Yanfly.Util.displayError(e, script, "SCRIPT CALL ERROR"); + } return true; } @@ -2170,5 +2208,22 @@ export class Game_Interpreter { if (command === "LoseGold") { $gameParty.loseGold(parseInt(args[0])); } + if (command === "RefreshMap") { + if (!$gameParty.inBattle()) { + $gameMap.requestRefresh($gameMap.mapId()); + } + } + if (command === "RefreshTroop") { + if ($gameParty.inBattle()) { + $gameTroop.setupBattleEvent(); + } + } + if (command === "setBattleSys" && !$gameParty.inBattle()) { + this.setBattleSystem(args[0]); + } + } + + public setBattleSystem(value) { + $gameSystem.setBattleSystem(value); } } diff --git a/ts/objects/Game_Map.ts b/ts/objects/Game_Map.ts index a351454..012d3ff 100644 --- a/ts/objects/Game_Map.ts +++ b/ts/objects/Game_Map.ts @@ -181,11 +181,13 @@ export class Game_Map { } public displayX() { - return this._displayX; + return Math.floor(this._displayX * this.tileWidth()) / this.tileWidth(); } public displayY() { - return this._displayY; + return ( + Math.floor(this._displayY * this.tileHeight()) / this.tileHeight() + ); } public parallaxName() { @@ -200,7 +202,7 @@ export class Game_Map { return this._battleback2Name; } - public requestRefresh(mapId?: undefined) { + public requestRefresh(mapId?: number) { this._needsRefresh = true; } diff --git a/ts/objects/Game_Party.ts b/ts/objects/Game_Party.ts index 8d52e06..0a4544b 100644 --- a/ts/objects/Game_Party.ts +++ b/ts/objects/Game_Party.ts @@ -4,6 +4,7 @@ import { TextManager } from "../managers/TextManager"; import { Game_Item, Game_Item_OnLoad } from "./Game_Item"; import { Game_Unit, Game_Unit_OnLoad } from "./Game_Unit"; import { Item } from "../interfaces/Item"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; export interface Game_Party_Onload extends Game_Unit_OnLoad { _gold: number; @@ -239,7 +240,7 @@ export class Game_Party extends Game_Unit { } public maxGold() { - return 99999999; + return eval(Yanfly.Param.MaxGold); } public steps() { @@ -309,17 +310,17 @@ export class Game_Party extends Game_Unit { }); } - public loseItem(item, amount, includeEquip?) { + public loseItem(item: Item, amount: number, includeEquip?: boolean) { this.gainItem(item, -amount, includeEquip); } - public consumeItem(item) { + public consumeItem(item: Item) { if (DataManager.isItem(item) && item.consumable) { this.loseItem(item, 1); } } - public canUse(item) { + public canUse(item: Item) { return this.members().some(function(actor) { return actor.canUse(item); }); @@ -488,4 +489,11 @@ export class Game_Party extends Game_Unit { actor.requestMotionRefresh(); }); } + + public performEscapeSuccess() { + for (let i = 0; i < this.members().length; ++i) { + let member = this.members()[i]; + if (member) member.performEscapeSuccess(); + } + } } diff --git a/ts/objects/Game_Switches.ts b/ts/objects/Game_Switches.ts index f156089..6e37f87 100644 --- a/ts/objects/Game_Switches.ts +++ b/ts/objects/Game_Switches.ts @@ -1,9 +1,13 @@ +import { SceneManager } from "../managers/SceneManager"; +import { Scene_Debug } from "../scenes/Scene_Debug"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; + export interface Game_Switches_OnLoad { _data: boolean[]; } export class Game_Switches { - private _data: boolean[]; + public _data: boolean[]; public constructor(gameLoadInput?: Game_Switches_OnLoad) { this.clear(); @@ -18,6 +22,10 @@ export class Game_Switches { } public value(switchId) { + if (this.isAdvancedSwitch(switchId)) { + return this.runAdvancedSwitchCode(switchId); + } + return !!this._data[switchId]; } @@ -31,4 +39,35 @@ export class Game_Switches { public onChange() { $gameMap.requestRefresh(); } + + private isAdvancedSwitch(switchId: number) { + if ( + SceneManager.scene.debugActive || + SceneManager.scene instanceof Scene_Debug + ) { + return false; + } else if ($dataSystem.switches[switchId].match(/EVAL:[ ](.*)/i)) + return true; + return false; + } + + private runAdvancedSwitchCode(switchId: number) { + const value = false; + let code = ""; + if ($dataSystem.switches[switchId].match(/EVAL:[ ](.*)/i)) { + code = "value = " + String(RegExp.$1); + } else { + return false; + } + try { + eval(code); + } catch (e) { + Yanfly.Util.displayError( + e, + code, + "ADVANCED SWITCH " + switchId + " EVAL ERROR" + ); + } + return value; + } } diff --git a/ts/objects/Game_System.ts b/ts/objects/Game_System.ts index 854362a..39a76cc 100644 --- a/ts/objects/Game_System.ts +++ b/ts/objects/Game_System.ts @@ -1,4 +1,5 @@ import { AudioManager } from "../managers/AudioManager"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; interface Game_System_OnLoad { _saveEnabled: boolean; @@ -40,6 +41,7 @@ export class Game_System { private _defeatMe: any; private _savedBgm: any; private _walkingBgm: any; + _battleSystem: string; public constructor(gameLoadInput?: Game_System_OnLoad) { if (gameLoadInput) { @@ -81,6 +83,20 @@ export class Game_System { this._savedBgm = null; this._walkingBgm = null; } + this.initBattleSystem(); + } + + public initBattleSystem() { + this._battleSystem = Yanfly.Param.BECSystem.toLowerCase(); + } + + public getBattleSystem() { + if (this._battleSystem === undefined) this.initBattleSystem(); + return this._battleSystem; + } + + public setBattleSystem(type) { + this._battleSystem = type.toLowerCase(); } public isJapanese() { diff --git a/ts/objects/Game_Temp.ts b/ts/objects/Game_Temp.ts index 1979c3f..895e8fe 100644 --- a/ts/objects/Game_Temp.ts +++ b/ts/objects/Game_Temp.ts @@ -1,3 +1,4 @@ +import { JsonEx } from "../core/JsonEx"; import { Utils } from "../core/Utils"; export class Game_Temp { @@ -5,36 +6,72 @@ export class Game_Temp { private _commonEventId: number; private _destinationX: number; private _destinationY: number; + private _forceActionQueue: any; + private _disableMouseOverSelect: boolean; + private _moveCommand: any; + + public mouseOverSelectDisabled(): boolean { + return this._disableMouseOverSelect; + } + + public get moveCommand(): any { + return this._moveCommand; + } + public set moveCommand(value: any) { + this._moveCommand = value; + } + + private _moveAllowPlayerCollision: boolean; + + public get moveAllowPlayerCollision(): boolean { + return this._moveAllowPlayerCollision; + } + public set moveAllowPlayerCollision(value: boolean) { + this._moveAllowPlayerCollision = value; + } public isPlaytest() { return this._isPlaytest; } + public reserveCommonEvent(commonEventId) { this._commonEventId = commonEventId; } + public clearCommonEvent() { + this._forceActionQueue = undefined; this._commonEventId = 0; } + public isCommonEventReserved() { return this._commonEventId > 0; } + public reservedCommonEvent() { + if (this._forceActionQueue) { + return this._forceActionQueue; + } return $dataCommonEvents[this._commonEventId]; } + public setDestination(x, y) { this._destinationX = x; this._destinationY = y; } + public clearDestination() { this._destinationX = null; this._destinationY = null; } + public isDestinationValid() { return this._destinationX !== null; } + public destinationX() { return this._destinationX; } + public destinationY() { return this._destinationY; } @@ -45,4 +82,14 @@ export class Game_Temp { this._destinationX = null; this._destinationY = null; } + + public clearActionSequenceSettings() {} + + public forceActionQueue(command) { + if (!this._forceActionQueue) { + this._forceActionQueue = JsonEx.makeDeepCopy($dataCommonEvents[1]); + this._forceActionQueue.list = []; + } + this._forceActionQueue.list.push(command); + } } diff --git a/ts/objects/Game_Unit.ts b/ts/objects/Game_Unit.ts index dde9962..d37d840 100644 --- a/ts/objects/Game_Unit.ts +++ b/ts/objects/Game_Unit.ts @@ -146,4 +146,52 @@ export class Game_Unit { } } } + + public createActions() { + let max = this.members().length; + for (let i = 0; i < max; ++i) { + let member = this.members()[i]; + if (member) member.createActions(); + } + } + + public requestMotionRefresh() { + let max = this.members().length; + for (let i = 0; i < max; ++i) { + let member = this.members()[i]; + if (member) member.requestMotionRefresh(); + } + } + + public onTurnStart() { + let max = this.members().length; + for (let i = 0; i < max; ++i) { + let member = this.members()[i]; + if (member) { + member.onTurnStart(); + member.refresh(); + } + } + } + + public updateTick() { + let max = this.members().length; + for (let i = 0; i < max; ++i) { + let member = this.members()[i]; + if (member) member.updateTick(); + } + } + + public refreshMembers() { + const group = this.allMembers(); + const length = group.length; + for (let i = 0; i < length; ++i) { + const member = group[i]; + if (member) member.refresh(); + } + } + + public allMembers() { + return this.members(); + } } diff --git a/ts/objects/Game_Variables.ts b/ts/objects/Game_Variables.ts index 3e875be..db64953 100644 --- a/ts/objects/Game_Variables.ts +++ b/ts/objects/Game_Variables.ts @@ -1,3 +1,8 @@ +import { SceneManager } from "../managers/SceneManager"; + +import { Scene_Debug } from "../scenes/Scene_Debug"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; + export interface Game_Variables_OnLoad { _data: number | string[]; } @@ -18,6 +23,9 @@ export class Game_Variables { } public value(variableId) { + if (this.isAdvancedVariable(variableId)) { + return this.runAdvancedVariableCode(variableId); + } return this._data[variableId] || 0; } @@ -34,4 +42,39 @@ export class Game_Variables { public onChange() { $gameMap.requestRefresh(); } + + public isAdvancedVariable(variableId) { + if ( + SceneManager.scene.debugActive || + SceneManager.scene instanceof Scene_Debug + ) { + return false; + } + const name = $dataSystem.variables[variableId]; + if (name.match(/EVAL:[ ](.*)/i)) { + return true; + } + return false; + } + + public runAdvancedVariableCode(variableId) { + const value = 0; + const name = $dataSystem.variables[variableId]; + let code = ""; + if (name.match(/EVAL:[ ](.*)/i)) { + code = "value = " + String(RegExp.$1); + } else { + return false; + } + try { + eval(code); + } catch (e) { + Yanfly.Util.displayError( + e, + code, + "ADVANCED VARIABLE" + variableId + " EVAL ERROR" + ); + } + return value; + } } diff --git a/ts/plugins/Stronk_YEP_BaseParamControl.ts b/ts/plugins/Stronk_YEP_BaseParamControl.ts new file mode 100644 index 0000000..6a31594 --- /dev/null +++ b/ts/plugins/Stronk_YEP_BaseParamControl.ts @@ -0,0 +1,576 @@ +import { Yanfly } from "./Stronk_YEP_CoreEngine"; +import { PluginManager } from "../managers/PluginManager"; + +//============================================================================= +// Yanfly Engine Plugins - Base Parameter Control +// YEP_BaseParamControl.js +//============================================================================= + +declare module "./Stronk_YEP_CoreEngine" { + interface YEP { + BPC: { version: number }; + _loaded_YEP_BaseParamControl: boolean; + } + + interface YanflyParams { + BPCFormula: string[]; + BPCMaximum: string[]; + BPCMinimum: string[]; + BPCLukEffectRate: string; + } +} + +Yanfly.BPC = { version: 1.04 }; +Yanfly._loaded_YEP_BaseParamControl = false; + +/*: + * @plugindesc v1.04 Gain control over the method of calculation for base + * parameters: MaxHP, MaxMP, ATK, DEF, MAT, MDF, AGI, LUK. + * @author Yanfly Engine Plugins + * + * @param ---MaxHP--- + * @default + * + * @param MHP Formula + * @parent ---MaxHP--- + * @desc The formula used to determine MHP: MaxHP + * This is a formula. + * @default (base + plus) * paramRate * buffRate + flat + * + * @param MHP Maximum + * @parent ---MaxHP--- + * @desc This is the highest value for MHP. + * This is a formula. + * @default customMax || (user.isActor() ? 9999 : 999999) + * + * @param MHP Minimum + * @parent ---MaxHP--- + * @desc This is the lowest value for MHP. + * This is a formula. + * @default customMin || 1 + * + * @param ---MaxMP--- + * @default + * + * @param MMP Formula + * @parent ---MaxMP--- + * @desc The formula used to determine MMP: MaxMP + * This is a formula. + * @default (base + plus) * paramRate * buffRate + flat + * + * @param MMP Maximum + * @parent ---MaxMP--- + * @desc This is the highest value for MMP. + * This is a formula. + * @default customMax || (user.isActor() ? 9999 : 9999) + * + * @param MMP Minimum + * @parent ---MaxMP--- + * @desc This is the lowest value for MMP. + * This is a formula. + * @default customMin || 0 + * + * @param ---Attack--- + * @default + * + * @param ATK Formula + * @parent ---Attack--- + * @desc The formula used to determine ATK: Attack + * This is a formula. + * @default (base + plus) * paramRate * buffRate + flat + * + * @param ATK Maximum + * @parent ---Attack--- + * @desc This is the highest value for ATK. + * This is a formula. + * @default customMax || (user.isActor() ? 999 : 999) + * + * @param ATK Minimum + * @parent ---Attack--- + * @desc This is the lowest value for ATK. + * This is a formula. + * @default customMin || 1 + * + * @param ---Defense--- + * @default + * + * @param DEF Formula + * @parent ---Defense--- + * @desc The formula used to determine DEF: Defense + * This is a formula. + * @default (base + plus) * paramRate * buffRate + flat + * + * @param DEF Maximum + * @parent ---Defense--- + * @desc This is the highest value for DEF. + * This is a formula. + * @default customMax || (user.isActor() ? 999 : 999) + * + * @param DEF Minimum + * @parent ---Defense--- + * @desc This is the lowest value for DEF. + * This is a formula. + * @default customMin || 1 + * + * @param ---M.Attack--- + * @default + * + * @param MAT Formula + * @parent ---M.Attack--- + * @desc The formula used to determine MAT: M.Attack + * This is a formula. + * @default (base + plus) * paramRate * buffRate + flat + * + * @param MAT Maximum + * @parent ---M.Attack--- + * @desc This is the highest value for MAT. + * This is a formula. + * @default customMax || (user.isActor() ? 999 : 999) + * + * @param MAT Minimum + * @parent ---M.Attack--- + * @desc This is the lowest value for MAT. + * This is a formula. + * @default customMin || 1 + * + * @param ---M.Defense--- + * @default + * + * @param MDF Formula + * @parent ---M.Defense--- + * @desc The formula used to determine MDF: M.Defense + * This is a formula. + * @default (base + plus) * paramRate * buffRate + flat + * + * @param MDF Maximum + * @parent ---M.Defense--- + * @desc This is the highest value for MDF. + * This is a formula. + * @default customMax || (user.isActor() ? 999 : 999) + * + * @param MDF Minimum + * @parent ---M.Defense--- + * @desc This is the lowest value for MDF. + * This is a formula. + * @default customMin || 1 + * + * @param ---Agility--- + * @default + * + * @param AGI Formula + * @parent ---Agility--- + * @desc The formula used to determine AGI: Agility + * This is a formula. + * @default (base + plus) * paramRate * buffRate + flat + * + * @param AGI Maximum + * @parent ---Agility--- + * @desc This is the highest value for AGI. + * This is a formula. + * @default customMax || (user.isActor() ? 999 : 999) + * + * @param AGI Minimum + * @parent ---Agility--- + * @desc This is the lowest value for AGI. + * This is a formula. + * @default customMin || 1 + * + * @param ---Luck--- + * @default + * + * @param LUK Formula + * @parent ---Luck--- + * @desc The formula used to determine LUK: Luck + * This is a formula. + * @default (base + plus) * paramRate * buffRate + flat + * + * @param LUK Maximum + * @parent ---Luck--- + * @desc This is the highest value for LUK. + * This is a formula. + * @default customMax || (user.isActor() ? 999 : 999) + * + * @param LUK Minimum + * @parent ---Luck--- + * @desc This is the lowest value for LUK. + * This is a formula. + * @default customMin || 1 + * + * @param LUK Effect + * @parent ---Luck--- + * @desc The formula used to influence state success rates. + * This is a formula + * @default Math.max(1.0 + (user.luk - target.luk) * 0.001, 0.0) + * + * @help + * ============================================================================ + * Introduction + * ============================================================================ + * + * The base parameters, MaxHP, MaxMP, ATK, DEF, MAT, MDF, AGI, and LUK all play + * a very important part of battle, yet, so very little control is given to the + * developer in regards to these important stats. This plugin will give more + * control over how the stats are handled and more. + * + * Note: If you are using the Core Engine and have modified the settings there + * for higher parameter caps, this plugin will override those settings if this + * plugin is placed beneath the Core Engine (recommended). + * + * ============================================================================ + * Instructions - Base Parameter Explanation + * ============================================================================ + * + * For those who do not understand what the base parameters are used for in RPG + * Maker MV, this section will provide a brief summary of their most important + * roles of what the base parameters do. + * + * --- + * + * MHP - MaxHP + * - This is the maximum health points value. The amount of health points (HP) + * a battler has determines whether or not the battler is in a living state or + * a dead state. If the HP value is above 0, then the battler is living. If it + * is 0 or below, the battler is in a dead state unless the battler has a way + * to counteract death (usually through immortality). When the battler takes + * damage, it is usually dealt to the HP value and reduces it. If the battler + * is healed, then the HP value is increased. The MaxHP value determines what's + * the maximum amount the HP value can be held at, meaning the battler cannot + * be healed past that point. + * + * --- + * + * MMP - MaxMP + * - This is the maximum magic points value. Magic points (MP) are typically + * used for the cost of skills and spells in battle. If the battler has enough + * MP to fit the cost of the said skill, the battler is able to use the said + * skill provided that all of the skill's other conditions are met. If not, the + * battler is then unable to use the skill. Upon using a skill that costs MP, + * the battler's MP is reduced. However, the battler's MP can be recovered and + * results in a gain of MP. The MaxMP value determines what is the maximum + * amount the MP value can be held at, meaning the battler cannot recover MP + * past the MaxMP value. + * + * --- + * + * ATK - Attack + * - This is the attack value of the battler. By default, this stat is used for + * the purpose of damage calculations only, and is typically used to represent + * the battler's physical attack power. Given normal damage formulas, higher + * values mean higher damage output for physical attacks. + * + * --- + * + * DEF - Defense + * - This is the defense value of the battler. By default, this stat is used + * for the purpose of damage calculations only, and is typically used to + * represent the battler's physical defense. Given normal damage formulas, + * higher values mean less damage received from physical attacks. + * + * --- + * + * MAT - Magic Attack + * - This is the magic attack value of the battler. By default, this stat is + * used for the purpose of damage calculations only, and is typically used to + * represent the battler's magical attack power. Given normal damage formulas, + * higher values mean higher damage output for magical attacks. + * + * --- + * + * MDF - Magic Defense + * - This is the magic defense value of the battler. By default, this stat is + * used for the purpose of damage calculations only, and is typically used to + * represent the battler's magical defense. Given normal damage formulas, + * higher values mean less damage received from magical attacks. + * + * --- + * + * AGI - Agility + * - This is the agility value of the battler. By default, this stat is used to + * determine battler's position in the battle turn's order. Given a normal turn + * calculation formula, the higher the value, the faster the battler is, and + * the more likely the battler will have its turn earlier in a turn. + * + * --- + * + * LUK - Luck + * - This is the luck value of the battler. By default, this stat is used to + * affect the success rate of states, buffs, and debuffs applied by the battler + * and received by the battler. If the user has a higher LUK value, the state, + * buff, or debuff is more likely to succeed. If the target has a higher LUK + * value, then the state, buff, or debuff is less likely to succeed. + * + * --- + * + * ============================================================================ + * Instructions - Custom Formulas + * ============================================================================ + * + * The values calculated by the formulas in the plugin parameters are to come + * out as integer values. If the result is a float, it will be rounded up and + * then clamped based around the maximum and minimum values the parameter can + * be (also calculated by the plugin parameters). + * + * By default, the formula looks as such: + * + * --- + * + * (base + plus) * paramRate * buffRate + flat + * + * --- + * + * Below is an explanation of each of the parts of the formula. + * + * BASE + * - This value is determined in multiple ways. If the battler is an actor, the + * base value is the base parameter value calculated by the position based on + * the battler's level on the parameter curve for the battler's current class. + * If the battler is an enemy, the base parameter value, by default, is equal + * to the value inserted on the enemy's database entry for that parameter. + * + * PLUS + * - This value is determined in multiple ways. For both actors and enemies, + * this value is a flat value given to the battler through events or script + * calls that manually increase the battler's parameter value. If the battler + * is an actor, this value is also increased by any equipment the battler has + * equipped. This value can be influenced by notetags provided by this plugin. + * + * PARAMRATE + * - This value is determined the same way for both actors and enemies. This is + * a percentile rate that is calculated by the multiplicative product of all + * of the parameter spread across the battler's traits, independent of the + * battler's buff rate. This value can be influenced by notetags provided by + * this plugin. + * + * BUFFRATE + * - This value is determined by the number of buff stacks (or debuff stacks) + * on a battler, regardless of whether or not the battler is an actor or enemy. + * The percentile modifier is calculated relative to the number of stacks in + * regards to that particular parameter for the battler. This value is NOT + * influenced by notetags provided by this plugin. + * + * FLAT + * - This is a new variable added by this plugin. Its purpose is to provide a + * final additive modifier to the total value of the parameter. This additive + * value is determined by the various database objects through notetags and can + * only be affected by those notetags. + * + * --- + * + * The parameter Maximum and Minimum values also have formulas. They will work + * something along the lines of this by default: + * + * customMax || (user.isActor() ? 9999 : 999999) + * customMin || 1 + * + * For those wondering about the 'customMax' and 'customMin' values, they are + * new variables added by this plugin. + * + * CUSTOMMAX + * - This is the custom maximum limit provided by this plugin through either a + * script call or notetags. The custom max will look through the battler's + * individual noteboxes. If the battler is an actor, it will look through the + * actor, class, each of the noteboxes of the equipment worn by the actor, and + * the noteboxes of each of the states affecting the actor. If the battler is + * an enemy, it wil look through the enemy notebox and each of the noteboxes of + * the states affecting the enemy. The highest custom maximum value becomes the + * newest 'customMax' value for the battler and will take priority over the + * default maximum value. If there is no 'customMax' value, then the value + * becomes the default maximum value written in the formula. + * + * CUSTOMMIN + * - This is the custom minimum limit provided by this plugin through either a + * script call or notetags. The custom min will look through the battler's + * individual noteboxes. If the battler is an actor, it will look through the + * actor, class, each of the noteboxes of the equipment worn by the actor, and + * the noteboxes of each of the states affecting the actor. If the battler is + * an enemy, it wil look through the enemy notebox and each of the noteboxes of + * the states affecting the enemy. The highest custom minimum value becomes the + * newest 'customMin' value for the battler and will take priority over the + * default minimum value. If there is no 'customMin' value, then the value + * becomes the default minimum value written in the formula. + * + * ============================================================================ + * Notetags + * ============================================================================ + * + * You can use the following notetags to alter the various aspects that modify + * the base parameter values: + * + * Actor, Class, Enemy, Weapon, Armor, and State Notetags: + * + * + * + * Replace 'stat' with 'maxhp', 'maxmp', 'atk', 'def', 'mat', 'mdf', 'agi', + * or 'luk'. This is the value added to the base parameter before the rate + * and flat values contribute to the total parameter value assuming the + * plugin's default formula is utilized. + * + * + * + * Replace 'stat' with 'maxhp', 'maxmp', 'atk', 'def', 'mat', 'mdf', 'agi', + * or 'luk'. This is the value multiplied to the sum of the base and plus of + * the parameter before affected by the buffRate and flat value assuming the + * plugin's default formula is utilized. + * + * + * + * Replace 'stat' with 'maxhp', 'maxmp', 'atk', 'def', 'mat', 'mdf', 'agi', + * or 'luk'. This is the value added at the end after the sum of the base and + * plus parameters have been added and multiplied by the rate values assuming + * the plugin's default formula is utilized. + * + * + * + * Replace 'stat' with 'maxhp', 'maxmp', 'atk', 'def', 'mat', 'mdf', 'agi', + * or 'luk'. This sets the maximum or minimum cap of the the stat parameter + * to x. If a battler is affected by multiple of these notetags, then the + * value used will be the largest value of the notetag used. + * + * ============================================================================ + * Lunatic Mode - New JavaScript Functions + * ============================================================================ + * + * You can use the following JavaScript functions to alter the base parameter + * values of the battlers. In these listed functions, the 'battler' variable + * is to be referenced by an actor: + * + * ie. battler = $gameActors.actor(3); + * - or - + * battler = $gameTroop.members()[2]; + * + * Function: + * + * battler.clearParamPlus() + * - This will clear all 'plus' variable modifiers for all base parameters. + * + * battler.setMaxHp(x) + * battler.setMaxMp(x) + * battler.setAtk(x) + * battler.setDef(x) + * battler.setMat(x) + * battler.setMdf(x) + * battler.setAgi(x) + * battler.setLuk(x) + * - Sets the battler's respective base parameter value to x. This will alter + * the 'plus' variable to fit this setting as best as possible without taking + * into consideration the rates and flats. + * + * battler.setMaxHpPlus(x) + * battler.setMaxMpPlus(x) + * battler.setAtkPlus(x) + * battler.setDefPlus(x) + * battler.setMatPlus(x) + * battler.setMdfPlus(x) + * battler.setAgiPlus(x) + * battler.setLukPlus(x) + * - Sets the battler's respective base parameter plus value to x. + * + * battler.addMaxHp(x) + * battler.addMaxMp(x) + * battler.addAtk(x) + * battler.addDef(x) + * battler.addMat(x) + * battler.addMdf(x) + * battler.addAgi(x) + * battler.addLuk(x) + * - Adds x value to battler's respective base parameter plus value. + * + * battler.minusMaxHp(x) + * battler.minusMaxMp(x) + * battler.minusAtk(x) + * battler.minusDef(x) + * battler.minusMat(x) + * battler.minusMdf(x) + * battler.minusAgi(x) + * battler.minusLuk(x) + * - Subtracts x value to battler's respective base parameter plus value. + * + * battler.clearCustomParamLimits(); + * - Clears any custom parameter limits placed upon the battler through a + * script call. This does not remove the custom parameter limits applied to + * a battler through notetags. + * + * battler.setCustomMaxHpMax(x) + * battler.setCustomMaxMpMax(x) + * battler.setCustomAtkMax(x) + * battler.setCustomDefMax(x) + * battler.setCustomMatMax(x) + * battler.setCustomMdfMax(x) + * battler.setCustomAgiMax(x) + * battler.setCustomLukMax(x) + * - Sets the maximum parameter limit of the respective base parameter to x. + * This value is calculated against any notetags that the + * battler may have. If there are multiple max values, the larges value is + * used as the parameter maximum. + * + * battler.setCustomMaxHpMin(x) + * battler.setCustomMaxMpMin(x) + * battler.setCustomAtkMin(x) + * battler.setCustomDefMin(x) + * battler.setCustomMatMin(x) + * battler.setCustomMdfMin(x) + * battler.setCustomAgiMin(x) + * battler.setCustomLukMin(x) + * - Sets the minimum parameter limit of the respective base parameter to x. + * This value is calculated against any notetags that the + * battler may have. If there are multiple min values, the larges value is + * used as the parameter minimum. + * + * ============================================================================ + * Changelog + * ============================================================================ + * + * Version 1.04: + * - Bypass the isDevToolsOpen() error when bad code is inserted into a script + * call or custom Lunatic Mode code segment due to updating to MV 1.6.1. + * - Fixed a typo in the documentation for script calls regarding LUK. + * + * Version 1.03: + * - Updated for RPG Maker MV version 1.5.0. + * + * Version 1.02: + * - Lunatic Mode fail safes added. + * + * Version 1.01: + * - Fixed an issue with the battler.setParam functions that made them take the + * wrong value due caching issues. + */ + +//============================================================================= +// Parameter Variables +//============================================================================= + +Yanfly.Parameters = PluginManager.parameters("Stronk_YEP_BaseParamControl"); +Yanfly.Param = Yanfly.Param || {}; + +Yanfly.Param.BPCFormula = []; +Yanfly.Param.BPCFormula.push(String(Yanfly.Parameters["MHP Formula"])); +Yanfly.Param.BPCFormula.push(String(Yanfly.Parameters["MMP Formula"])); +Yanfly.Param.BPCFormula.push(String(Yanfly.Parameters["ATK Formula"])); +Yanfly.Param.BPCFormula.push(String(Yanfly.Parameters["DEF Formula"])); +Yanfly.Param.BPCFormula.push(String(Yanfly.Parameters["MAT Formula"])); +Yanfly.Param.BPCFormula.push(String(Yanfly.Parameters["MDF Formula"])); +Yanfly.Param.BPCFormula.push(String(Yanfly.Parameters["AGI Formula"])); +Yanfly.Param.BPCFormula.push(String(Yanfly.Parameters["LUK Formula"])); + +Yanfly.Param.BPCMaximum = []; +Yanfly.Param.BPCMaximum.push(String(Yanfly.Parameters["MHP Maximum"])); +Yanfly.Param.BPCMaximum.push(String(Yanfly.Parameters["MMP Maximum"])); +Yanfly.Param.BPCMaximum.push(String(Yanfly.Parameters["ATK Maximum"])); +Yanfly.Param.BPCMaximum.push(String(Yanfly.Parameters["DEF Maximum"])); +Yanfly.Param.BPCMaximum.push(String(Yanfly.Parameters["MAT Maximum"])); +Yanfly.Param.BPCMaximum.push(String(Yanfly.Parameters["MDF Maximum"])); +Yanfly.Param.BPCMaximum.push(String(Yanfly.Parameters["AGI Maximum"])); +Yanfly.Param.BPCMaximum.push(String(Yanfly.Parameters["LUK Maximum"])); + +Yanfly.Param.BPCMinimum = []; +Yanfly.Param.BPCMinimum.push(String(Yanfly.Parameters["MHP Minimum"])); +Yanfly.Param.BPCMinimum.push(String(Yanfly.Parameters["MMP Minimum"])); +Yanfly.Param.BPCMinimum.push(String(Yanfly.Parameters["ATK Minimum"])); +Yanfly.Param.BPCMinimum.push(String(Yanfly.Parameters["DEF Minimum"])); +Yanfly.Param.BPCMinimum.push(String(Yanfly.Parameters["MAT Minimum"])); +Yanfly.Param.BPCMinimum.push(String(Yanfly.Parameters["MDF Minimum"])); +Yanfly.Param.BPCMinimum.push(String(Yanfly.Parameters["AGI Minimum"])); +Yanfly.Param.BPCMinimum.push(String(Yanfly.Parameters["LUK Minimum"])); + +Yanfly.Param.BPCLukEffectRate = String(Yanfly.Parameters["LUK Effect"]); diff --git a/ts/plugins/Stronk_YEP_BattleEngineCore.ts b/ts/plugins/Stronk_YEP_BattleEngineCore.ts new file mode 100644 index 0000000..57f47cc --- /dev/null +++ b/ts/plugins/Stronk_YEP_BattleEngineCore.ts @@ -0,0 +1,1438 @@ +import { PluginManager } from "../managers/PluginManager"; +import { Yanfly } from "./Stronk_YEP_CoreEngine"; + +//============================================================================= +// Yanfly Engine Plugins - Battle Engine Core +// YEP_BattleEngineCore.js +//============================================================================= + +declare module "./Stronk_YEP_CoreEngine" { + interface YEP { + BEC: { + version: number; + DefaultActionSetup: any[]; + DefaultActionWhole: any[]; + DefaultActionTarget: any[]; + DefaultActionFollow: any[]; + DefaultActionFinish: any[]; + SeqType: string; + }; + _loaded_YEP_BattleEngineCore: boolean; + DisableWebGLMask: boolean; + } + + interface YanflyParams { + BECSystem: string; + BECEscRatio: string; + BECEscFail: string; + CastCertHit: number; + CastPhysical: number; + CastMagical: number; + EnemyAtkAni: number; + BECOptSpeed: any; + BECEmergeText: string; + BECPreEmpText: string; + BECSurpText: any; + BECPopupOverlap: any; + BECNewPopBottom: any; + BECStartActCmd: any; + BECCurMax: string; + BECSelectHelp: any; + BECHelpUserTx: string; + BECHelpAllyTx: string; + BECHelpAlliesTx: string; + BECHelpEnemyTx: string; + BECHelpEnemiesTx: string; + BECHelpAllTx: string; + BECHelpRandTx: string; + BECFrontPosX: string; + BECFrontPosY: string; + BECFrontSprite: any; + BECFrSpPrio: string; + BECHomePosX: string; + BECHomePosY: string; + BECSideSpPrio: string; + BECAnchorX: number; + BECAnchorY: number; + BECStepDist: number; + BECFlinchDist: number; + BECShowShadows: any; + BECPopupDur: number; + BECCritPopup: string; + BECCritDur: number; + BECActionSpeed: any; + BECReflectAni: number; + BECMotionWait: any; + BECTimeStates: any; + BECTimeBuffs: any; + BECTurnTime: number; + BECAISelfTurn: any; + BECLowerWindows: any; + BECSelectMouseOver: any; + BECEnemySelect: any; + BECActorSelect: any; + BECWindowRows: number; + BECEnemyFontSize: number; + BECShowEnemyName: any; + BECShowSelectBox: any; + BECEnemyAutoSel: any; + BECCommandAlign: CanvasTextAlign; + BECCommandRows: any; + BECAniBaseDel: number; + BECAniNextDel: number; + BECFullActText: any; + BECShowCntText: any; + BECShowRflText: any; + BECShowSubText: any; + BECShowFailText: any; + BECShowCritText: any; + BECShowMissText: any; + BECShowEvaText: any; + BECShowHpText: any; + BECShowMpText: any; + BECShowTpText: any; + BECShowStateText: any; + BECShowBuffText: any; + } + + interface YanflyUtils { + getRange(n, m): any[]; + onlyUnique(value, index, self): boolean; + } +} + +Yanfly.BEC = { + version: 1.5, + DefaultActionSetup: [], + DefaultActionWhole: [], + DefaultActionTarget: [], + DefaultActionFollow: [], + DefaultActionFinish: [], + SeqType: " " +}; + +Yanfly._loaded_YEP_BattleEngineCore = false; + +Yanfly.Util.getRange = function(n, m) { + let result = []; + for (let i = n; i <= m; ++i) result.push(i); + return result; +}; + +Yanfly.Util.onlyUnique = function(value, index, self) { + return self.indexOf(value) === index; +}; + +/*: + * @plugindesc v1.50 Have more control over the flow of the battle system + * with this plugin and alter various aspects to your liking. + * @author Yanfly Engine Plugins + * + * @param ---General--- + * @default + * + * @param Action Speed + * @parent ---General--- + * @desc This is the formula used for an action's base speed. + * Default: agi + Math.randomInt(Math.floor(5 + agi / 4)) + * @default agi + * + * @param Default System + * @parent ---General--- + * @type select + * @option Default Turn Battle + * @value dtb + * @option Active Turn Battle (plugin required) + * @value atb + * @option Charge Turn Battle (plugin required) + * @value ctb + * @option Standard Turn Battle (plugin required) + * @value stb + * @desc This is the default battle system your game uses. + * Default: dtb + * @default dtb + * + * @param ---Escape--- + * @default + * + * @param Escape Ratio + * @parent ---Escape--- + * @desc This is the formula used to determine escape success. + * Default: 0.5 * $gameParty.agility() / $gameTroop.agility() + * @default 0.5 * $gameParty.agility() / $gameTroop.agility() + * + * @param Fail Escape Boost + * @parent ---Escape--- + * @type number + * @decimals 2 + * @desc Each time the player fails escape, increase the success + * rate by this much. Default: 0.10 + * @default 0.10 + * + * @param ---Animation--- + * @default + * + * @param Animation Base Delay + * @parent ---Animation--- + * @type number + * @min 0 + * @desc This sets the base delay in between animations. + * Default: 8 + * @default 0 + * + * @param Animation Next Delay + * @parent ---Animation--- + * @type number + * @min 0 + * @desc This sets the sequential delay in between animations. + * Default: 12 + * @default 0 + * + * @param Certain Hit Animation + * @parent ---Animation--- + * @type number + * @min 0 + * @desc Default animation to play for certain hit skills. + * Use 0 if you wish for no animation. + * @default 0 + * + * @param Physical Animation + * @parent ---Animation--- + * @type number + * @min 0 + * @desc Default animation to play for physical skills. + * Use 0 if you wish for no animation. + * @default 52 + * + * @param Magical Animation + * @parent ---Animation--- + * @type number + * @min 0 + * @desc Default animation to play for magical skills. + * Use 0 if you wish for no animation. + * @default 51 + * + * @param Enemy Attack Animation + * @parent ---Animation--- + * @type number + * @min 0 + * @desc This is the default attack animation played by enemies. + * Default: 0 + * @default 39 + * + * @param Reflect Animation + * @parent ---Animation--- + * @type number + * @min 0 + * @desc The animation used when magic attacks are reflected. + * @default 42 + * + * @param Motion Waiting + * @parent ---Animation--- + * @type boolean + * @on After + * @off During + * @desc Play animations after performing an action or during? + * During - false After - true Default: false + * @default false + * + * @param ---Frontview--- + * @default + * + * @param Front Position X + * @parent ---Frontview--- + * @desc This formula determines the actor's home X position. + * Default: 0 + * @default Graphics.boxWidth / 8 + Graphics.boxWidth / 4 * index + * + * @param Front Position Y + * @parent ---Frontview--- + * @desc This formula determines the actor's home Y position. + * Default: 0 + * @default Graphics.boxHeight - 180 + * + * @param Front Actor Sprite + * @parent ---Frontview--- + * @type boolean + * @on YES + * @off NO + * @desc Show the actor battle sprite in frontview? + * NO - false YES - true Default - false + * @default false + * + * @param Front Sprite Priority + * @parent ---Frontview--- + * @type select + * @option Normal + * @value 0 + * @option Actors on Top + * @value 1 + * @option Enemies on Top + * @value 2 + * @desc Give actor sprites the priority of always being on top? + * 0 - Normal 1 - Actors on Top 2 - Enemies on Top + * @default 1 + * + * @param ---Sideview--- + * @default + * + * @param Home Position X + * @parent ---Sideview--- + * @desc This formula determines the actor's home X position. + * Default: 600 + index * 32 + * @default screenWidth - 16 - (maxSize + 2) * 32 + index * 32 + * + * @param Home Position Y + * @parent ---Sideview--- + * @desc This formula determines the actor's home Y position. + * Default: 280 + index * 48 + * @default screenHeight - statusHeight - maxSize * 48 + (index+1) * 48 - 32 + * + * @param Side Sprite Priority + * @parent ---Sideview--- + * @type select + * @option Normal + * @value 0 + * @option Actors on Top + * @value 1 + * @option Enemies on Top + * @value 2 + * @desc Give actor sprites the priority of always being on top? + * 0 - Normal 1 - Actors on Top 2 - Enemies on Top + * @default 1 + * + * @param ---Sprites--- + * @default + * + * @param Default X Anchor + * @parent ---Sprites--- + * @type number + * @decimals 2 + * @desc Default value used for your sprites's X Anchor. + * Default: 0.50 + * @default 0.50 + * + * @param Default Y Anchor + * @parent ---Sprites--- + * @type number + * @decimals 2 + * @desc Default value used for your sprites's Y Anchor. + * Default: 1.00 + * @default 1.00 + * + * @param Step Distance + * @parent ---Sprites--- + * @type number + * @desc This is the distance a unit steps forward for actions. + * Default: 48 + * @default 48 + * + * @param Flinch Distance + * @parent ---Sprites--- + * @type number + * @desc In sideview, when a unit takes damage or dodges, it will + * flinch a certain distance in pixels. + * @default 12 + * + * @param Show Shadows + * @parent ---Sprites--- + * @type boolean + * @on Show Shadows + * @off Hide Shadows + * @desc Do you wish to have shadows appear under actors? + * NO - false YES - true + * @default true + * + * @param ---Damage Popups--- + * @default + * + * @param Popup Duration + * @parent ---Damage Popups--- + * @type number + * @min 1 + * @desc Adjusts how many frames a popup will stay visible for. + * Default: 90 + * @default 128 + * + * @param Newest Popup Bottom + * @parent ---Damage Popups--- + * @type boolean + * @on Newest at bottom + * @off Newest at top + * @desc Places the newest popup at the bottom of a group. + * NO - false YES - true + * @default true + * + * @param Popup Overlap Rate + * @parent ---Damage Popups--- + * @type number + * @decimals 1 + * @desc When multiple damage popups appear, they cover each other. + * Use this to change the buffer rate amount for each sprite. + * @default 0.9 + * + * @param Critical Popup + * @parent ---Damage Popups--- + * @desc Adjusts the popup's flashing color for critical hits. + * Default: 255, 0, 0, 160 + * @default 255, 0, 0, 160 + * + * @param Critical Duration + * @parent ---Damage Popups--- + * @type number + * @min 1 + * @desc How many frames the flashing will remain for a critical. + * Default: 60 + * @default 60 + * + * @param ---Tick-Settings--- + * @default + * + * @param Timed States + * @parent ---Tick-Settings--- + * @type boolean + * @on Time-Based States + * @off Turn-Based States + * @desc If the battle system is Tick-based, use time instead of + * turns for states? NO - false YES - true + * @default false + * + * @param Timed Buffs + * @parent ---Tick-Settings--- + * @type boolean + * @on Time-Based Buffs + * @off Turn-Based Buffs + * @desc If the battle system is Tick-based, use time instead of + * turns for buffs? NO - false YES - true + * @default false + * + * @param Turn Time + * @parent ---Tick-Settings--- + * @type number + * @min 1 + * @desc How many ticks must past to equal 1 turn? + * @default 100 + * + * @param AI Self Turns + * @parent ---Tick-Settings--- + * @type boolean + * @on YES + * @off NO + * @desc Set AI to be based on their own individual turns? + * NO - false YES - true + * @default true + * + * @param ---Window Settings--- + * @default + * + * @param Lower Windows + * @parent ---Window Settings--- + * @type boolean + * @on Bottom Layout + * @off Default Layout + * @desc Places the skill and item windows at the screen's bottom. + * OFF - false ON - true + * @default true + * + * @param Window Rows + * @parent ---Window Settings--- + * @number + * @min 1 + * @desc For lower windows, how many rows of items do you wish for + * the windows to display? + * @default 4 + * + * @param Command Window Rows + * @parent ---Window Settings--- + * @type number + * @min 1 + * @desc Sets the number of rows for each command window to display. + * Default: 4 + * @default 4 + * + * @param Command Alignment + * @parent ---Window Settings--- + * @type combo + * @option left + * @option center + * @option right + * @desc Sets the text alignment for the Party/Actor Commands. + * Default: left + * @default center + * + * @param Start Actor Command + * @parent ---Window Settings--- + * @type boolean + * @on Actor Command Window + * @off Party Command Window + * @desc Starts turn with the Actor Command Window instead of Party. + * OFF - false ON - true + * @default true + * + * @param Current Max + * @parent ---Window Settings--- + * @type boolean + * @on Current / Max + * @off Just Current + * @desc Display the entire current / max value of HP/MP? + * NO - false YES - true Default: true + * @default false + * + * @param ---Selection Help--- + * @default + * + * @param Mouse Over + * @parent ---Selection Help--- + * @type boolean + * @on YES + * @off NO + * @desc Allows you to mouse over the enemies to auto-select them. + * OFF - false ON - true + * @default true + * + * @param Select Help Window + * @parent ---Selection Help--- + * @type boolean + * @on YES + * @off NO + * @desc When selecting actors and enemies, show the help window? + * NO - false YES - true + * @default true + * + * @param User Help Text + * @parent ---Selection Help--- + * @desc The singular form of 'User' used in a help window. + * @default User + * + * @param Ally Help Text + * @parent ---Selection Help--- + * @desc The singular form of 'Ally' used in a help window. + * @default Ally + * + * @param Allies Help Text + * @parent ---Selection Help--- + * @desc The plural form of 'Allies' used in a help window. + * @default Allies + * + * @param Enemy Help Text + * @parent ---Selection Help--- + * @desc The singular form of 'Enemy' used in a help window. + * @default Enemy + * + * @param Enemies Help Text + * @parent ---Selection Help--- + * @desc The plural form of 'Enemy' used in a help window. + * @default Enemies + * + * @param All Help Text + * @parent ---Selection Help--- + * @desc When selecting a entire group of targets. + * %1 - Target Group (Allies or Enemies) + * @default All %1 + * + * @param Random Help Text + * @parent ---Selection Help--- + * @desc When selecting a random selection of targets. + * %1 - Target Group (Allies or Enemies) %2 - Number + * @default %2 Random %1 + * + * @param ---Enemy Select--- + * @default + * + * @param Visual Enemy Select + * @parent ---Enemy Select--- + * @type boolean + * @on YES + * @off NO + * @desc Replaces the enemy selection screen with a more visual one. + * OFF - false ON - true + * @default true + * + * @param Show Enemy Name + * @parent ---Enemy Select--- + * @type boolean + * @on YES + * @off NO + * @desc Show enemy names with Visual Enemy Select. + * OFF - false ON - true + * @default true + * + * @param Show Select Box + * @parent ---Enemy Select--- + * @type boolean + * @on YES + * @off NO + * @desc Show a selection box when selecting enemies. + * OFF - false ON - true + * @default false + * + * @param Enemy Font Size + * @parent ---Enemy Select--- + * @type number + * @min 1 + * @desc Changes the font size used to display enemy names. + * Default: 28 + * @default 20 + * + * @param Enemy Auto Select + * @parent ---Enemy Select--- + * @desc Changes what enemy is automatically selected at first. + * LEFT - 0 RIGHT - this.furthestRight() + * @default this.furthestRight() + * + * @param ---Actor Select--- + * @default + * + * @param Visual Actor Select + * @parent ---Actor Select--- + * @type boolean + * @on YES + * @off NO + * @desc Allows you to click the actor on screen to select it. + * OFF - false ON - true + * @default true + * + * @param ---Battle Log--- + * @default + * + * @param Show Emerge Text + * @parent ---Battle Log--- + * @type boolean + * @on YES + * @off NO + * @desc Shows the battle start text for enemies appearing. + * OFF - false ON - true + * @default false + * + * @param Show Pre-Emptive Text + * @parent ---Battle Log--- + * @type boolean + * @on YES + * @off NO + * @desc Shows the text for getting a pre-emptive attack. + * OFF - false ON - true + * @default true + * + * @param Show Surprise Text + * @parent ---Battle Log--- + * @type boolean + * @on YES + * @off NO + * @desc Shows the text for getting a surprise attack. + * OFF - false ON - true + * @default true + * + * @param Optimize Speed + * @parent ---Battle Log--- + * @type boolean + * @on YES + * @off NO + * @desc Cuts log base line process to optimize the battle speed. + * OFF - false ON - true + * @default true + * + * @param Show Action Text + * @parent ---Battle Log--- + * @type boolean + * @on Full + * @off Simple + * @desc Displays full action text or a simplified version of it. + * SIMPLE - false FULL - true + * @default false + * + * @param Show State Text + * @parent ---Battle Log--- + * @type boolean + * @on YES + * @off NO + * @desc Shows all text regarding states. + * OFF - false ON - true + * @default false + * + * @param Show Buff Text + * @parent ---Battle Log--- + * @type boolean + * @on YES + * @off NO + * @desc Shows all text regarding buffs. + * OFF - false ON - true + * @default false + * + * @param Show Counter Text + * @parent ---Battle Log--- + * @type boolean + * @on YES + * @off NO + * @desc Shows text regarding counter attacks. + * OFF - false ON - true + * @default true + * + * @param Show Reflect Text + * @parent ---Battle Log--- + * @type boolean + * @on YES + * @off NO + * @desc Shows text regarding reflected spells. + * OFF - false ON - true + * @default true + * + * @param Show Substitute Text + * @parent ---Battle Log--- + * @type boolean + * @on YES + * @off NO + * @desc Shows text regarding substituted damage. + * OFF - false ON - true + * @default true + * + * @param Show Fail Text + * @parent ---Battle Log--- + * @type boolean + * @on YES + * @off NO + * @desc Shows text regarding failed attacks. + * OFF - false ON - true + * @default false + * + * @param Show Critical Text + * @parent ---Battle Log--- + * @type boolean + * @on YES + * @off NO + * @desc Shows text regarding critical hits. + * OFF - false ON - true + * @default false + * + * @param Show Miss Text + * @parent ---Battle Log--- + * @type boolean + * @on YES + * @off NO + * @desc Shows text regarding missed attacks. + * OFF - false ON - true + * @default false + * + * @param Show Evasion Text + * @parent ---Battle Log--- + * @type boolean + * @on YES + * @off NO + * @desc Shows text regarding evaded attacks. + * OFF - false ON - true + * @default false + * + * @param Show HP Text + * @parent ---Battle Log--- + * @type boolean + * @on YES + * @off NO + * @desc Shows text regarding HP damage or heals. + * OFF - false ON - true + * @default false + * + * @param Show MP Text + * @parent ---Battle Log--- + * @type boolean + * @on YES + * @off NO + * @desc Shows text regarding MP damage or heals. + * OFF - false ON - true + * @default false + * + * @param Show TP Text + * @parent ---Battle Log--- + * @type boolean + * @on YES + * @off NO + * @desc Shows text regarding TP damage or heals. + * OFF - false ON - true + * @default false + * + * @help + * ============================================================================ + * Introduction + * ============================================================================ + * + * This plugin alters the various aspects of the default battle system, + * allowing it to be more streamlined like most modern RPG's and less clunky + * like older RPG's. This ranges from choosing what text will appear in the + * battle log window at the top and how it will be displayed. + * + * ============================================================================ + * Battle Messages + * ============================================================================ + * + * When changing "Terms" and the "Messages" that appear in battle, inserting + * the following tag anywhere in the message will cause the message to center + * itself in the battle log. + * + *
+ * This tag must be all caps in order for the battle log window to recognize + * it as an instruction to center the displayed battle text message. + * + * There are a couple of notetags you can use to change the way certain skills + * and items will show up incase you don't want a name like 'Harold's Attack' + * to appear in the name. + * + * Skill and Item Notetags: + * + * + * This will change the text displayed to x. + * + * + * This will change the icon displayed to x. + * + * ============================================================================ + * Battle Windows + * ============================================================================ + * + * There's various options to adjust the window settings found in the battle + * system to make navigating the battle system more intuitive. Such options + * include starting the turns with the Actor Command Window instead of the + * Party Command Window (the Fight/Escape Window). The Party Command Window is + * still accessible but only by pressing cancel on the first actor's window. + * + * ============================================================================ + * Battle Order + * ============================================================================ + * + * The battle turn order is also fixed, too. This way, any battlers that Have + * their AGI value changed over the course of battle will reflect those changes + * during the current turn rather than the following turn. The action speed + * calculation can also be adjusted and finetuned to have the random factor of + * its speed calculation formula removed, too, making AGI actually worthwhile + * as a tactical parameter. + * + * Skill and Item Notetag: + * + * + * This lets you break past the editor's limit of -2000 and 2000 allowing you + * to set the speed of your actions with more control. + * + * ============================================================================ + * Multiple Hits + * ============================================================================ + * + * Multi-hit action will no longer end prematurely if the target dies midway + * through the action. This is done through toggling immortal states. To make + * use of feature, make sure your database has an Immortal State somewhere. If + * you do not wish to use this feature, set the Parameter for Immortal State ID + * to 0 instead. + * + * ============================================================================ + * Popup Revamp + * ============================================================================ + * + * Although the damage popups may still look the same as the default ones from + * MV, the process in which they're created is now different to streamline the + * damage popup process. Before, popups would only appear one a time with a + * frame's different at minimum in order for them to show. Now, any actions + * that occur at the same frame will now all show popups at the same frame, + * making for smoother and less clunky damage popups. + * + * ============================================================================ + * Common Events + * ============================================================================ + * + * Common Events will now occur at the end of each action regardless of whether + * or not the enemy party is still alive. With proper placing of the action + * sequence tags, you can make the skill's common event occur in the middle of + * an action, too. However, keep in mind if you force an action in the middle + * of another action, the remainder of the former action's sequence list will + * become null and void in favor of the new forced action. + * + * ============================================================================ + * Casting Animations + * ============================================================================ + * + * Casting Animations help provide visual hints for players either by letting + * them know which battler is going to perform an action or what type of skill + * that action will be. This plugin enables skills to have casting animations + * that can be modified universally or customized for each individual skill. + * + * Skill Notetag: + * + * Sets the skill's cast animation to animation ID x. Setting x to zero will + * cause the skill to not have any animaton at all. + * + * ============================================================================ + * Changing Battle Systems + * ============================================================================ + * + * While the player is not in battle, you can change the battle system using a + * Plugin Command. With only this plugin, there is only one battle system + * included: the default battle system. + * + * Plugin Command: + * setBattleSys DTB Sets battle system to Default Turn Battle. + * + * Other future plugins may include other battle systems that may utilize the + * Battle Engine Core. + * + * ============================================================================ + * Sideview Actions + * ============================================================================ + * + * In RPG Maker MV's default battle system, both the sideview and the frontview + * settings do not display counterattacks, reflected magic attacks, nor any + * case of substituting for battle members. The Battle Engine Core provides + * games that are using the sideview settings small amounts of animations to + * relay information to the player in a more visual sense. + * + * Magic Reflection will also display a reflection animation to indicate the + * battler has reflection properties. This animation can be changed in the + * parameters, but certain actors, classes, enemies, weapons, armors, and + * states can display a unique kind of animation for reflection if desired. + * + * Actor, Class, Enemy, Weapon, Armor, and State Notetag: + * + * Changes the user's reflect animation to x. This will take priority in the + * following order: Actor, Class, Enemy, Weapon, Armor, State, Default. + * + * Sometimes, you don't want your enemies to be able to move. Or you don't want + * certain actors to be able to move. They're just stationary for whatever + * reason. To accomplish that, you can use this notetag to forbid the battler + * from moving. + * + * Actor, Class, Enemy, Weapon, Armor, and State Notetag: + * + * Prevents the battler's sprite from moving. This will take priority in the + * following order: Actor, Class, Enemy, Weapon, Armor, and State. If an + * enemy is unable to move when it performs an action, it will flash white as + * if it normally does in front view. + * + * ============================================================================ + * Custom Sideview Battler Anchor + * ============================================================================ + * + * Sideview battlers are generally centered horizontally, and grounded at their + * feet. However, not all sideview battler spritesheets work this way. In the + * event you have a sideview battler that doesn't conform to those standards, + * you can 'anchor' them a different way. + * + * Actor, Class, Weapon, Armor, State Notetags: + * + * + * This sets the anchor location for the actor's sideview battler at y.z. + * By default, the X anchor is 0.5 while the Y anchor is 1.0. If you want + * the X anchor to be a bit more to the left, make it less than 0.5. Make it + * more than 0.5 to make the X anchor more towards the right. To raise the + * Y anchor, set the number value to less than 1.0. Keep adjusting until you + * find that perfect anchor setting. + * + * If an anchor has multiple traits that yield different anchors, it will be + * used in a priority list akin to this order: + * + * States + * Weapons + * Armors + * Class + * Actor + * Default + * + * The higher it is on the priority list, the higher its priority. + * + * ============================================================================ + * Enemy Attack Animation + * ============================================================================ + * + * To give your enemies unique attack animations, you can use this notetag: + * + * Enemy Notetag: + * + * Replace x with the ID of the battle animation you wish to set as the + * enemy's default attack animation. + * + * ============================================================================ + * Automatic State Removal Conditions + * ============================================================================ + * + * By default, RPG Maker MV's battle system has automatic state removal under + * three different conditions: none, action end, turn end. + * + * None and Turn End are working as intended. However, Action End, however, had + * the states removed at the start of the battler's action rather than the end. + * This is changed and updated to occur only at the end of a battler's action. + * + * Two more automatic conditions are now added: Action Start and Turn Start. + * These can be added and implemented using the following notetags: + * + * State Notetags: + * + * + * This will cause this state to update its turns remaining at the start of + * an action. x is the number of turns it will last. If you use x to y, upon + * applying the state, the state will be removed a random number of turns + * from x to y. + * + * + * + * This will cause the state to update its turns remaining at the start of a + * battle turn. x is the number of turns it will last. If you use x to y, + * upon applying the state, the state will be removed a random number of + * turns from x to y. + * + * States with Action End have a unique trait to them where if the caster of + * the state is the current active battler (subject) and if the state is then + * applied on the user itself, they will gain a 'free turn'. The 'free turn' is + * to mitigate the user from losing 1 duration of the turn since with an Action + * End timing, they would lose the benefit of being under the state for that + * turn's timing. + * + * ============================================================================ + * Action Sequences + * ============================================================================ + * + * The Yanfly Engine Plugins - Battle Engine Core includes the capability of + * using custom action sequences. Action sequences are basic instructions for + * the game to creating a customized skill both visually and mechanically. + * The Battle Engine Core, however, will only include the most basic of action + * sequences so the instructions on how to create a custom action sequence will + * be included in the Help file on future extension plugins for this plugin. + * + * ============================================================================ + * Changelog + * ============================================================================ + * + * Version 1.50: + * - Action sequences allow for unlimited arguments now. + * + * Version 1.49: + * - Added failsafe for 'furthestRight()' errors. + * + * Version 1.48: + * - Optimization update. + * + * Version 1.47: + * - Bypass the isDevToolsOpen() error when bad code is inserted into a script + * call or custom Lunatic Mode code segment due to updating to MV 1.6.1. + * + * Version 1.46: + * - Updated for RPG Maker MV version 1.6.1. + * + * Version 1.45: + * - Updated for RPG Maker MV version 1.5.0. + * + * Version 1.44: + * - Fixed a bug where the enemy name windows disappear if you change scenes + * mid-way through battle and return to it. + * + * Version 1.43b: + * - Bug fixed to prevent crash if non-existent actions are used. + * - Optimization update. + * + * Version 1.42: + * - Optimization update. + * + * Version 1.41: + * - Fixed a bug that allowed certain sprites to remain in the active pool + * while party members were removed midway through battle. + * + * Version 1.40: + * - Updated for RPG Maker MV version 1.3.2. + * + * Version 1.39c: + * - Fixed a bug that caused dead actors to not be a part of action sequence + * targeting for "Not Focus". + * - Optimization update. + * - Updated "queueForceAction" to utilize both numbers and actual targets. + * + * Version 1.38a: + * - Optimization update. + * - Compatibility update for Selection Control v1.08. + * - Bug fixed for mirrored animations on enemies. + * + * Version 1.37: + * - Fixed a bug where if the enemy's size is too small, the enemy's name + * during selection will be cut off. + * + * Version 1.36d: + * - Made an update for the battle background image snaps when there is no + * battleback being used. This will prevent the player party and enemy troop + * from appearing in the background snapshot when entering menus mid-battle. + * - 'Death Break' action sequence now only triggers upon dead status and not + * an 'or 0 HP' condition. + * - Updated Forced Action sequencing for more efficiency. + * - 'Action Times+' traits now work properly for DTB again. + * - Optimized message displaying for battle log. + * - Optimized z sorting algorithm for sprites. + * + * Verison 1.35d: + * - Scopes that target a dead ally will automatically target the first dead + * ally now. Scopes that target all dead allies will lock onto the first dead + * ally. This will hopefully provide less confusion amongst playing. + * - Added anti-crash measure for sprite bitmaps. + * - Added anti-crash measure for faux actions. + * - Added anti-crash measure to prevent non-existant animations from playing. + * - Added a check that prevents hidden battlers from appearing when using + * certain action sequences. + * + * Version 1.34a: + * - Fixed a bug where 'NOT FOCUS' targets were not including dead members. + * - Fixed a bug where using NOT FOCUS would cause dead targets to be visible. + * + * Version 1.33: + * - Updated for RPG Maker MV version 1.1.0. + * + * Version 1.32d: + * - Fixed a bug that caused a crash when an actor died. + * - Added a motion engine to be used for future plugins. + * - Preparation for a future plugin. + * - and notetags for actors are now extended + * to actors, classes, weapons, armors, and states. + * - Added and notetags for skills and + * items. These notetags will alter the display name shown and icon shown + * respectively while performing a skill. + * - Switched Magic Reflect checking order with Counterattack checking order. + * This is to give priority to reflected actions over countered actions. + * + * Version 1.31b: + * - States with Action End now have a unique trait to them where if the caster + * of the state is the current active battler (subject) and if the state is + * then applied on the user itself, they will gain a 'free turn'. The 'free + * turn' is to mitigate the user from losing 1 duration of the turn since with + * an Action End timing, they would lose the benefit of being under the state + * for that turn's timing. + * - Added failsafes for Free Turns in case other plugins have overwritten the + * on battle start functions. + * - Added a compatibility update to Animated SV Enemies for dead motion. + * + * Version 1.30: + * - Optimization update. + * - Fixed a bug that prevented added state effects be unable to apply if they + * are an added Death state. + * - Battlelog lines are now able to display text codes. + * + * Version 1.29: + * - Fixed a bug with the 'else if' action sequences not working in the right + * order of sequence conditions. + * + * Version 1.28d: + * - Fixed a bug if instant casting a skill that would make an opponent battler + * to force an action to end incorrectly. Thanks to DoubleX for the fix. + * - Fixed a bug with mouse over not working properly. + * - Fixed a bug regarding forced actions that will cause the battle to freeze + * if the forced action causes the main active subject to leave the battle. + * - Fixed a bug with timed states not updating their turns properly. + * - Changed priority of IF action sequences to higher to no longer interfere + * other action sequences. + * + * Version 1.27: + * - Mechanic change. This will only affect those using turn-based state timing + * mechanics. Turn End state updates are now shifted from Turn End to occur at + * Regeneration timing to have a more synchronized aspect. The timings are very + * close so there's next to no notice in difference. Buff turn updates are also + * moved to the regeneration timing, too. + * + * Version 1.26: + * - Added 'Mouse Over' parameter to Selection Help. This parameter enables + * mouse users to simply hover over the enemy to select them rather than having + * to click an enemy twice to select them. + * + * Version 1.25f: + * - Added failsafes for Forced Action queues. + * - Added 'Show Select Box' parameter when selecting enemies. + * - Fixed a bug that caused End Turn events to not function properly. + * - Battle animations, by default, are positioned relative to the base bitmap + * for its target sprite. However, actor sprites do not have a base bitmap and + * therefore, battle animations, regardless of position, will always target the + * actor sprite's feet. This update now gives actor sprites a base bitmap. + * - Readjusted sprite width and sprite height calculations. + * - Added a failsafe for when no sideview actor graphics are used. + * + * Version 1.24: + * - Implemented a Forced Action queue list. This means if a Forced Action + * takes place in the middle of an action, the action will resume after the + * forced action finishes rather than cancels it out like MV does. + * + * Version 1.23: + * - Fixed a bug that didn't regenerate HP/MP/TP properly for tick-based. + * + * Version 1.22: + * - Fixed a bug within MV that caused Forced Actions at Turn End to prompt and + * trigger all turn-end related activities (such as regeneration and state turn + * updating). + * - Made a mechanic change so that Action Start and Action End state turns do + * not update their turns through forced actions. + * + * Version 1.21: + * - Fixed a bug where states Action End weren't going down properly with DTB. + * + * Version 1.20: + * - Fixed a bug where revived actors using instant cast aren't properly set to + * use actions immediately. + * + * Version 1.19: + * - Added notetag for enemies. + * - Added 'AI Self Turns' for Tick-Based Battles. Enemies can now have their + * A.I. revolve around their own individual turns rather than the battle's. + * - Mechanic change for states. Following suit with the change to Action End + * removal, there are now two more conditions added: Action Start, Turn Start. + * - Added , , , and + * notetags for automatic state removal. + * + * Version 1.18: + * - Fixed a bug with irregular targeting scopes. + * - Fixed an MV-related bug with Recover All event not refreshing battlers. + * + * Version 1.17b: + * - Fixed a bug with action end states to remove multiple at once. + * - Fixed a visual error with flinching sprites. + * - Added 'Current Max' parameter to change HP current/max display in battle. + * - Mechanic change for states that update on Action End to end at the end of + * a battler's turn instead of at the start. + * - Began preparations for another battle system. + * + * Version 1.16: + * - Fixed an issue with mirrored enemies having mirrored state icons. + * + * Version 1.15a: + * - Fixed a bug revolving the status window not updating. + * - Updated default home position formula to better fit other party sizes. + * New Home Position X: + * screenWidth - 16 - (maxSize + 2) * 32 + index * 32 + * New Home Position Y: + * screenHeight - statusHeight - maxSize * 48 + (index+1) * 48 - 16 + * + * Version 1.14: + * - Fixed a bug with Forced Actions locking out the battle. + * - New mechanic: For tick-based battle systems, states with action-end will + * go down in turns based on how many actions took place for the actor instead. + * Previously, they were indistinguishable from states with Turn End removal. + * - New mechanic: Using Instant Skills/Items from YEP_InstantCast.js will also + * cause states with action-end to go down in turns upon using actions. + * + * Version 1.13a: + * - Fixed a bug that made battlebacks disappear. + * - Reworked visual enemy selection. + * - Victory phase doesn't immediately display level up changes in battle + * status window. + * - Fixed a bug with the visual enemy select showing dead enemy names. + * + * Version 1.12b: + * - If the Battle HUD has been hidden for whatever reason during the victory + * sequence, it will be returned. + * - Added and notetags to break past editor limits. + * - Added new conditions where the battle won't end until all action sequences + * have been fulfilled. + * + * Version 1.11: + * - Fixed a bug that didn't show HP/MP Regeneration. + * + * Version 1.10: + * - Removed immortal state dependancy. Immortality is now its own setting. + * - Added more abbreviated variables for action speed calculation. + * - Fixed a bug where all-scope attacks would reveal Appear-Halfway enemies. + * - Fixed a bug where the battle wouldn't end if the final enemy was killed + * by state damage. + * + * Version 1.09: + * - Fixed a undefined actor bug for refreshing the status window. + * - Added 'Show Shadows' parameter to the plugin settings. + * - Reworked the default action sequences so that forced actions do not appear + * on top of each other and party-heal animations occur simultaneously. + * + * Version 1.08: + * - Fixed a bug where battlers gaining HP/MP in the damage formula for + * themselves wouldn't trigger popups. + * - Fixed a bug where if the party failed to escape from battle, states that + * would be removed by battle still get removed. *Fixed by Emjenoeg* + * - Fixed a bug where instant death skills didn't work. + * - Changed Sprite Priority settings to decide whether actors, enemies, or + * neither would always be on top. + * + * Version 1.07: + * - Optimized status window to refresh at a minimum. + * - Set up frame work for future plugins: + * - Added 'Escape Ratio' and 'Fail Escape Boost' to parameters to allow users + * to set the escape ratio they want. + * - Added 'Front Sprite Priority' and 'Side Sprite Priority' to parameters to + * dictate if actor sprites are always on top. + * - Added 'Tick-Settings' category for tick-based battle systems. + * + * Version 1.06: + * - Fixed a bug that causes dead actors at the start of battle to not spawn. + * - Fixed a bug where the help window on an empty slot would show the + * previous skill's message. + * + * Version 1.05: + * - Added new target typing: Character X, which allows you to select + * specifically the actor with an actor ID of X if he/she/it is in the party. + * - Fixed a bug that prevented Miss and Evade popups from showing. + * + * Version 1.04: + * - Fixed a bug where popups didn't show under certain animation types. + * - Fixed certain battler motions from not refreshing correctly. + * - Actions with no scope will not trigger the confirmation selection window. + * + * Version 1.03: + * - Added 'Wait for Effect' action sequence. + * - Actions now wait for effects (such as collapsing) to be done before + * continuing on with battle or to end battle. + * + * Version 1.02: + * - Fixed a bug where the help window would retain descriptions on no skills. + * - Synched up weapons with actor sprites so they would occur simultaneously. + * - Fixed an issue where requesting certain motions from enemies that don't + * exist would cause them to crash. + * + * Version 1.01: + * - Skills and items that affect both HP and MP will now show popups for both. + * + * Version 1.00: + * - Finished plugin! + */ + +//============================================================================= +// Parameter Variables +//============================================================================= + +Yanfly.Parameters = PluginManager.parameters("Stronk_YEP_BattleEngineCore"); +Yanfly.Param = Yanfly.Param || {}; + +Yanfly.Param.BECSystem = String(Yanfly.Parameters["Default System"]); +Yanfly.Param.BECEscRatio = String(Yanfly.Parameters["Escape Ratio"]); +Yanfly.Param.BECEscFail = String(Yanfly.Parameters["Fail Escape Boost"]); +Yanfly.Param.CastCertHit = Number(Yanfly.Parameters["Certain Hit Animation"]); +Yanfly.Param.CastPhysical = Number(Yanfly.Parameters["Physical Animation"]); +Yanfly.Param.CastMagical = Number(Yanfly.Parameters["Magical Animation"]); +Yanfly.Param.EnemyAtkAni = Number(Yanfly.Parameters["Enemy Attack Animation"]); +Yanfly.Param.BECOptSpeed = String(Yanfly.Parameters["Optimize Speed"]); +Yanfly.Param.BECOptSpeed = eval(Yanfly.Param.BECOptSpeed); +Yanfly.Param.BECEmergeText = String(Yanfly.Parameters["Show Emerge Text"]); +Yanfly.Param.BECEmergeText = eval(Yanfly.Param.BECEmergeText); +Yanfly.Param.BECPreEmpText = String(Yanfly.Parameters["Show Pre-Emptive Text"]); +Yanfly.Param.BECPreEmpText = eval(Yanfly.Param.BECPreEmpText); +Yanfly.Param.BECSurpText = String(Yanfly.Parameters["Show Surprise Text"]); +Yanfly.Param.BECSurpText = eval(Yanfly.Param.BECSurpText); +Yanfly.Param.BECPopupOverlap = String(Yanfly.Parameters["Popup Overlap Rate"]); +Yanfly.Param.BECPopupOverlap = eval(Yanfly.Param.BECPopupOverlap); +Yanfly.Param.BECNewPopBottom = String(Yanfly.Parameters["Newest Popup Bottom"]); +Yanfly.Param.BECNewPopBottom = eval(Yanfly.Param.BECNewPopBottom); +Yanfly.Param.BECStartActCmd = String(Yanfly.Parameters["Start Actor Command"]); +Yanfly.Param.BECStartActCmd = eval(Yanfly.Param.BECStartActCmd); +Yanfly.Param.BECCurMax = eval(String(Yanfly.Parameters["Current Max"])); +Yanfly.Param.BECSelectHelp = String(Yanfly.Parameters["Select Help Window"]); +Yanfly.Param.BECSelectHelp = eval(Yanfly.Param.BECSelectHelp); +Yanfly.Param.BECHelpUserTx = String(Yanfly.Parameters["User Help Text"]); +Yanfly.Param.BECHelpAllyTx = String(Yanfly.Parameters["Ally Help Text"]); +Yanfly.Param.BECHelpAlliesTx = String(Yanfly.Parameters["Allies Help Text"]); +Yanfly.Param.BECHelpEnemyTx = String(Yanfly.Parameters["Enemy Help Text"]); +Yanfly.Param.BECHelpEnemiesTx = String(Yanfly.Parameters["Enemies Help Text"]); +Yanfly.Param.BECHelpAllTx = String(Yanfly.Parameters["All Help Text"]); +Yanfly.Param.BECHelpRandTx = String(Yanfly.Parameters["Random Help Text"]); +Yanfly.Param.BECFrontPosX = String(Yanfly.Parameters["Front Position X"]); +Yanfly.Param.BECFrontPosY = String(Yanfly.Parameters["Front Position Y"]); +Yanfly.Param.BECFrontSprite = String(Yanfly.Parameters["Front Actor Sprite"]); +Yanfly.Param.BECFrontSprite = eval(Yanfly.Param.BECFrontSprite); +Yanfly.Param.BECFrSpPrio = String(Yanfly.Parameters["Front Sprite Priority"]); +Yanfly.Param.BECHomePosX = String(Yanfly.Parameters["Home Position X"]); +Yanfly.Param.BECHomePosY = String(Yanfly.Parameters["Home Position Y"]); +Yanfly.Param.BECSideSpPrio = String(Yanfly.Parameters["Side Sprite Priority"]); +Yanfly.Param.BECSideSpPrio = eval(Yanfly.Param.BECSideSpPrio); +Yanfly.Param.BECAnchorX = Number(Yanfly.Parameters["Default X Anchor"]); +Yanfly.Param.BECAnchorY = Number(Yanfly.Parameters["Default Y Anchor"]); +Yanfly.Param.BECStepDist = Number(Yanfly.Parameters["Step Distance"]); +Yanfly.Param.BECFlinchDist = Number(Yanfly.Parameters["Flinch Distance"]); +Yanfly.Param.BECShowShadows = String(Yanfly.Parameters["Show Shadows"]); +Yanfly.Param.BECShowShadows = eval(Yanfly.Param.BECShowShadows); +Yanfly.Param.BECPopupDur = Number(Yanfly.Parameters["Popup Duration"]); +Yanfly.Param.BECCritPopup = String(Yanfly.Parameters["Critical Popup"]); +Yanfly.Param.BECCritDur = Number(Yanfly.Parameters["Critical Duration"]); +Yanfly.Param.BECActionSpeed = String(Yanfly.Parameters["Action Speed"]); +Yanfly.Param.BECReflectAni = Number(Yanfly.Parameters["Reflect Animation"]); +Yanfly.Param.BECMotionWait = String(Yanfly.Parameters["Motion Waiting"]); +Yanfly.Param.BECMotionWait = eval(Yanfly.Param.BECMotionWait); +Yanfly.Param.BECTimeStates = String(Yanfly.Parameters["Timed States"]); +Yanfly.Param.BECTimeStates = eval(Yanfly.Param.BECTimeStates); +Yanfly.Param.BECTimeBuffs = String(Yanfly.Parameters["Timed Buffs"]); +Yanfly.Param.BECTimeBuffs = eval(Yanfly.Param.BECTimeBuffs); +Yanfly.Param.BECTurnTime = Number(Yanfly.Parameters["Turn Time"]); +Yanfly.Param.BECAISelfTurn = eval(String(Yanfly.Parameters["AI Self Turns"])); +Yanfly.Param.BECLowerWindows = String(Yanfly.Parameters["Lower Windows"]); +Yanfly.Param.BECLowerWindows = eval(Yanfly.Param.BECLowerWindows); +Yanfly.Param.BECSelectMouseOver = eval(String(Yanfly.Parameters["Mouse Over"])); +Yanfly.Param.BECEnemySelect = String(Yanfly.Parameters["Visual Enemy Select"]); +Yanfly.Param.BECEnemySelect = eval(Yanfly.Param.BECEnemySelect); +Yanfly.Param.BECActorSelect = String(Yanfly.Parameters["Visual Actor Select"]); +Yanfly.Param.BECActorSelect = eval(Yanfly.Param.BECActorSelect); +Yanfly.Param.BECWindowRows = Number(Yanfly.Parameters["Window Rows"]); +Yanfly.Param.BECEnemyFontSize = Number(Yanfly.Parameters["Enemy Font Size"]); +Yanfly.Param.BECShowEnemyName = String(Yanfly.Parameters["Show Enemy Name"]); +Yanfly.Param.BECShowEnemyName = eval(Yanfly.Param.BECShowEnemyName); +Yanfly.Param.BECShowSelectBox = String(Yanfly.Parameters["Show Select Box"]); +Yanfly.Param.BECShowSelectBox = eval(Yanfly.Param.BECShowSelectBox); +Yanfly.Param.BECEnemyAutoSel = String(Yanfly.Parameters["Enemy Auto Select"]); +Yanfly.Param.BECEnemyAutoSel = Yanfly.Param.BECEnemyAutoSel; +Yanfly.Param.BECCommandAlign = String( + Yanfly.Parameters["Command Alignment"] +) as CanvasTextAlign; +Yanfly.Param.BECCommandRows = Number(Yanfly.Parameters["Command Window Rows"]); +Yanfly.Param.BECAniBaseDel = Number(Yanfly.Parameters["Animation Base Delay"]); +Yanfly.Param.BECAniNextDel = Number(Yanfly.Parameters["Animation Next Delay"]); + +Yanfly.Param.BECFullActText = String(Yanfly.Parameters["Show Action Text"]); +Yanfly.Param.BECFullActText = eval(Yanfly.Param.BECFullActText); +Yanfly.Param.BECShowCntText = String(Yanfly.Parameters["Show Counter Text"]); +Yanfly.Param.BECShowCntText = eval(Yanfly.Param.BECShowCntText); +Yanfly.Param.BECShowRflText = String(Yanfly.Parameters["Show Reflect Text"]); +Yanfly.Param.BECShowRflText = eval(Yanfly.Param.BECShowRflText); +Yanfly.Param.BECShowSubText = String(Yanfly.Parameters["Show Substitute Text"]); +Yanfly.Param.BECShowSubText = eval(Yanfly.Param.BECShowSubText); +Yanfly.Param.BECShowFailText = String(Yanfly.Parameters["Show Fail Text"]); +Yanfly.Param.BECShowFailText = eval(Yanfly.Param.BECShowFailText); +Yanfly.Param.BECShowCritText = String(Yanfly.Parameters["Show Critical Text"]); +Yanfly.Param.BECShowCritText = eval(Yanfly.Param.BECShowCritText); +Yanfly.Param.BECShowMissText = String(Yanfly.Parameters["Show Miss Text"]); +Yanfly.Param.BECShowMissText = eval(Yanfly.Param.BECShowMissText); +Yanfly.Param.BECShowEvaText = String(Yanfly.Parameters["Show Evasion Text"]); +Yanfly.Param.BECShowEvaText = eval(Yanfly.Param.BECShowEvaText); +Yanfly.Param.BECShowHpText = String(Yanfly.Parameters["Show HP Text"]); +Yanfly.Param.BECShowHpText = eval(Yanfly.Param.BECShowHpText); +Yanfly.Param.BECShowMpText = String(Yanfly.Parameters["Show MP Text"]); +Yanfly.Param.BECShowMpText = eval(Yanfly.Param.BECShowMpText); +Yanfly.Param.BECShowTpText = String(Yanfly.Parameters["Show TP Text"]); +Yanfly.Param.BECShowTpText = eval(Yanfly.Param.BECShowTpText); +Yanfly.Param.BECShowStateText = String(Yanfly.Parameters["Show State Text"]); +Yanfly.Param.BECShowStateText = eval(Yanfly.Param.BECShowStateText); +Yanfly.Param.BECShowBuffText = String(Yanfly.Parameters["Show Buff Text"]); +Yanfly.Param.BECShowBuffText = eval(Yanfly.Param.BECShowBuffText); + +//============================================================================= +// DataManager +//============================================================================= + +Yanfly.BEC.DefaultActionSetup = [ + ["CLEAR BATTLE LOG"], + ["DISPLAY ACTION"], + ["IMMORTAL", ["TARGETS", "TRUE"]], + ["PERFORM START"], + ["WAIT FOR MOVEMENT"], + ["CAST ANIMATION"], + ["WAIT FOR ANIMATION"] +]; +Yanfly.BEC.DefaultActionWhole = [["PERFORM ACTION"]]; +Yanfly.BEC.DefaultActionTarget = [["PERFORM ACTION"]]; +if (Yanfly.Param.BECMotionWait) { + Yanfly.BEC.DefaultActionWhole.push(["MOTION WAIT", ["USER"]]); + Yanfly.BEC.DefaultActionTarget.push(["MOTION WAIT", ["USER"]]); +} else { + Yanfly.BEC.DefaultActionWhole.push(["WAIT", [10]]); + Yanfly.BEC.DefaultActionTarget.push(["WAIT", [10]]); +} +Yanfly.BEC.DefaultActionWhole.push(["ACTION ANIMATION"]); +Yanfly.BEC.DefaultActionWhole.push(["WAIT FOR ANIMATION"]); +Yanfly.BEC.DefaultActionTarget.push(["ACTION ANIMATION"]); +Yanfly.BEC.DefaultActionTarget.push(["WAIT FOR ANIMATION"]); +Yanfly.BEC.DefaultActionFollow = []; +Yanfly.BEC.DefaultActionFinish = [ + ["IMMORTAL", ["TARGETS", "FALSE"]], + ["WAIT FOR NEW LINE"], + ["CLEAR BATTLE LOG"], + ["PERFORM FINISH"], + ["WAIT FOR MOVEMENT"], + ["WAIT FOR EFFECT"], + ["ACTION COMMON EVENT"] +]; + +Yanfly.DisableWebGLMask = false; diff --git a/ts/plugins/Stronk_YEP_CoreEngine.ts b/ts/plugins/Stronk_YEP_CoreEngine.ts new file mode 100644 index 0000000..1f57230 --- /dev/null +++ b/ts/plugins/Stronk_YEP_CoreEngine.ts @@ -0,0 +1,1027 @@ +//= ============================================================================ +// Stronk! Modified: Yanfly Engine Plugins - Core Engine +// YEP_CoreEngine.js +//= ============================================================================ + +/*: + * @plugindesc v1.31 Needed for the majority of Yanfly Engine Scripts. Also + * contains bug fixes found inherently in RPG Maker. + * @author Yanfly Engine Plugins + * + * @param Open Console + * @parent ---Screen--- + * @type boolean + * @on Open + * @off Don't Open + * @desc For testing and debug purposes, this opens up the console. + * Don't Open - false Open - true + * @default false + * + * @param Collection Clear + * @parent ---Screen--- + * @type boolean + * @on YES + * @off NO + * @desc Clears stored objects within major scenes upon switching + * scenes to free up memory. NO - false YES - true + * @default true + * + * @param ---Gold--- + * @desc + * + * @param Gold Max + * @parent ---Gold--- + * @type number + * @min 1 + * @desc The maximum amount of gold the player can have. + * Default: 99999999 + * @default 99999999 + * + * @param Gold Font Size + * @parent ---Gold--- + * @type number + * @min 1 + * @desc The font size used to display gold. + * Default: 28 + * @default 20 + * + * @param Gold Icon + * @parent ---Gold--- + * @type number + * @min 0 + * @desc This will be the icon used to represent gold in the gold + * window. If left at 0, no icon will be displayed. + * @default 313 + * + * @param Gold Overlap + * @parent ---Gold--- + * @desc This will be what's displayed when the gold number + * exceeds the allocated area's content size. + * @default A lotta + * + * @param ---Items--- + * @desc + * + * @param Default Max + * @parent ---Items--- + * @type number + * @min 1 + * @desc This is the maximum number of items a player can hold. + * Default: 99 + * @default 99 + * + * @param Quantity Text Size + * @parent ---Items--- + * @type number + * @min 1 + * @desc This is the text's font size used for the item quantity. + * Default: 28 + * @default 20 + * + * @param ---Parameters--- + * @default + * + * @param Max Level + * @parent ---Parameters--- + * @type number + * @min 1 + * @desc Adjusts the maximum level limit for actors. + * Default: 99 + * @default 99 + * + * @param Actor MaxHP + * @parent ---Parameters--- + * @type number + * @min 1 + * @desc Adjusts the maximum HP limit for actors. + * Default: 9999 + * @default 9999 + * + * @param Actor MaxMP + * @parent ---Parameters--- + * @type number + * @min 0 + * @desc Adjusts the maximum MP limit for actors. + * Default: 9999 + * @default 9999 + * + * @param Actor Parameter + * @parent ---Parameters--- + * @type number + * @min 1 + * @desc Adjusts the maximum parameter limit for actors. + * Default: 999 + * @default 999 + * + * @param Enemy MaxHP + * @parent ---Parameters--- + * @type number + * @min 1 + * @desc Adjusts the maximum HP limit for enemies. + * Default: 999999 + * @default 999999 + * + * @param Enemy MaxMP + * @parent ---Parameters--- + * @type number + * @min 0 + * @desc Adjusts the maximum MP limit for enemies. + * Default: 9999 + * @default 9999 + * + * @param Enemy Parameter + * @parent ---Parameters--- + * @type number + * @min 1 + * @desc Adjusts the maximum parameter limit for enemies. + * Default: 999 + * @default 999 + * + * @param ---Battle--- + * @desc + * + * @param Animation Rate + * @parent ---Battle--- + * @type number + * @min 1 + * @desc Adjusts the rate of battle animations. Lower for faster. + * Default: 4 + * @default 4 + * + * @param Flash Target + * @parent ---Battle--- + * @type boolean + * @on YES + * @off NO + * @desc If an enemy is targeted, it flashes or it can whiten. + * OFF - false ON - true + * @default false + * + * @param Show Events Transition + * @parent ---Battle--- + * @type boolean + * @on Show + * @off Hide + * @desc Show events during the battle transition? + * SHOW - true HIDE - false Default: false + * @default true + * + * @param Show Events Snapshot + * @parent ---Battle--- + * @type boolean + * @on Show + * @off Hide + * @desc Show events for the battle background snapshot? + * SHOW - true HIDE - false Default: false + * @default true + * + * @param ---Map Optimization--- + * @desc + * + * @param Refresh Update HP + * @parent ---Map Optimization--- + * @type boolean + * @on Show + * @off Hide + * @desc Do a full actor refresh when updating HP on map? + * YES - true NO - false Default: true + * @default true + * + * @param Refresh Update MP + * @parent ---Map Optimization--- + * @type boolean + * @on Show + * @off Hide + * @desc Do a full actor refresh when updating MP on map? + * YES - true NO - false Default: true + * @default true + * + * @param Refresh Update TP + * @parent ---Map Optimization--- + * @type boolean + * @on Show + * @off Hide + * @desc Do a full actor refresh when updating TP on map? + * YES - true NO - false Default: true + * @default false + * + * @param ---Font--- + * @desc + * + * @param Chinese Font + * @parent ---Font--- + * @desc Default font(s) used for a Chinese RPG. + * Default: SimHei, Heiti TC, sans-serif + * @default SimHei, Heiti TC, sans-serif + * + * @param Korean Font + * @parent ---Font--- + * @desc Default font(s) used for a Korean RPG. + * Default: Dotum, AppleGothic, sans-serif + * @default Dotum, AppleGothic, sans-serif + * + * @param Default Font + * @parent ---Font--- + * @desc Default font(s) used for everything else. + * Default: GameFont + * @default GameFont, Verdana, Arial, Courier New + * + * @param Font Size + * @parent ---Font--- + * @type number + * @min 1 + * @desc Default font size used for windows. + * Default: 28 + * @default 28 + * + * @param Text Align + * @parent ---Font--- + * @type combo + * @option left + * @option center + * @option right + * @desc How to align the text for command windows. + * left center right + * @default left + * + * @param ---Windows--- + * @default + * + * @param Digit Grouping + * @parent ---Windows--- + * @type boolean + * @on YES + * @off NO + * @desc Groups together digits with a comma. + * false - OFF true - ON + * @default true + * + * @param Line Height + * @parent ---Windows--- + * @type number + * @min 0 + * @desc Adjusts universal line height used in Windows. + * Default: 36 + * @default 36 + * + * @param Icon Width + * @parent ---Windows--- + * @type number + * @min 0 + * @desc Adjusts the width of your icons. + * Default: 32 + * @default 32 + * + * @param Icon Height + * @parent ---Windows--- + * @type number + * @min 0 + * @desc Adjusts the height of your icons. + * Default: 32 + * @default 32 + * + * @param Face Width + * @parent ---Windows--- + * @type number + * @min 0 + * @desc Adjusts the width of actors' faces. + * Default: 144 + * @default 144 + * + * @param Face Height + * @parent ---Windows--- + * @type number + * @min 0 + * @desc Adjusts the height of actors' faces. + * Default: 144 + * @default 144 + * + * @param Window Padding + * @parent ---Windows--- + * @type number + * @min 0 + * @desc Adjusts the padding for all standard windows. + * Default: 18 + * @default 18 + * + * @param Text Padding + * @parent ---Windows--- + * @type number + * @min 0 + * @desc Adjusts the padding for text inside of windows. + * Default: 6 + * @default 6 + * + * @param Window Opacity + * @parent ---Windows--- + * @type number + * @min 0 + * @desc Adjusts the background opacity for windows. + * Default: 192 + * @default 192 + * + * @param Gauge Outline + * @parent ---Windows--- + * @type boolean + * @on YES + * @off NO + * @desc Enable outlines for gauges. + * false - OFF true - ON + * @default true + * + * @param Gauge Height + * @parent ---Windows--- + * @type number + * @min 0 + * @desc Sets the height for gauges. + * Default: 6 + * @default 18 + * + * @param Menu TP Bar + * @parent ---Windows--- + * @type boolean + * @on YES + * @off NO + * @desc Draws a TP bar in the menu status for actors. + * false - OFF true - ON + * @default true + * + * @param ---Window Colors--- + * @default + * + * @param Color: Normal + * @parent ---Window Colors--- + * @type number + * @min 0 + * @max 31 + * @desc Changes the text color for Windows. + * Default: 0 + * @default 0 + * + * @param Color: System + * @parent ---Window Colors--- + * @type number + * @min 0 + * @max 31 + * @desc Changes the text color for Windows. + * Default: 16 + * @default 16 + * + * @param Color: Crisis + * @parent ---Window Colors--- + * @type number + * @min 0 + * @max 31 + * @desc Changes the text color for Windows. + * Default: 17 + * @default 17 + * + * @param Color: Death + * @parent ---Window Colors--- + * @type number + * @min 0 + * @max 31 + * @desc Changes the text color for Windows. + * Default: 18 + * @default 18 + * + * @param Color: Gauge Back + * @parent ---Window Colors--- + * @type number + * @min 0 + * @max 31 + * @desc Changes the text color for Windows. + * Default: 19 + * @default 19 + * + * @param Color: HP Gauge 1 + * @parent ---Window Colors--- + * @type number + * @min 0 + * @max 31 + * @desc Changes the text color for Windows. + * Default: 20 + * @default 20 + * + * @param Color: HP Gauge 2 + * @parent ---Window Colors--- + * @type number + * @min 0 + * @max 31 + * @desc Changes the text color for Windows. + * Default: 21 + * @default 21 + * + * @param Color: MP Gauge 1 + * @parent ---Window Colors--- + * @type number + * @min 0 + * @max 31 + * @desc Changes the text color for Windows. + * Default: 22 + * @default 22 + * + * @param Color: MP Gauge 2 + * @parent ---Window Colors--- + * @type number + * @min 0 + * @max 31 + * @desc Changes the text color for Windows. + * Default: 23 + * @default 23 + * + * @param Color: MP Cost + * @parent ---Window Colors--- + * @type number + * @min 0 + * @max 31 + * @desc Changes the text color for Windows. + * Default: 23 + * @default 23 + * + * @param Color: Power Up + * @parent ---Window Colors--- + * @type number + * @min 0 + * @max 31 + * @desc Changes the text color for Windows. + * Default: 24 + * @default 24 + * + * @param Color: Power Down + * @parent ---Window Colors--- + * @type number + * @min 0 + * @max 31 + * @desc Changes the text color for Windows. + * Default: 25 + * @default 25 + * + * @param Color: TP Gauge 1 + * @parent ---Window Colors--- + * @type number + * @min 0 + * @max 31 + * @desc Changes the text color for Windows. + * Default: 28 + * @default 28 + * + * @param Color: TP Gauge 2 + * @parent ---Window Colors--- + * @type number + * @min 0 + * @max 31 + * @desc Changes the text color for Windows. + * Default: 29 + * @default 29 + * + * @param Color: TP Cost Color + * @parent ---Window Colors--- + * @type number + * @min 0 + * @max 31 + * @desc Changes the text color for Windows. + * Default: 29 + * @default 29 + * + * @help + * ============================================================================ + * Introduction and Instructions + * ============================================================================ + * + * Yanfly Engine Plugins - Core Engine is made for RPG Maker MV. This plugin + * functions primarily to fix bugs and to allow the user more control over RPG + * Maker MV's various features, such as the screen resolution, font, window + * colors, and more. + * + * Just place this on top of all the other Yanfly Engine Plugins. + * Adjust any parameters as you see fit. + * + * This plugin has been reduced to its paramemeter imports, with the code + * changes incorporated into Stronk!. + * + * ============================================================================ + * Bug Fixes + * ============================================================================ + * + * This plugin fixes a few bugs found present within RPG Maker MV. Of them are + * the following: + * + * Animation Overlay + * When a skill/item that targets multiple enemies at once using a fullscreen + * animation, it will overlay multiple times causing the image to look + * distorted by a series of overlayed effects. The plugin fixes this issue by + * having only one animation played over the group instead of every one. + * + * Audio Volume Stacking + * Sometimes when multiple sound effects are played in the same frame with + * the exact settings (usually due to animaitons), the volume stacks upon + * each other, causing them to not play the intended volume for the effect. + * This plugin fixes this issue by preventing sound effects of the same exact + settings from playing during the same frame, allowing only the first to + go through without stacking the volume higher. + * + * Event Movement Speed + * The movement speed of events are slightly slower than what they should be + * due a small error in the source code. The plugin fixes this issue and they + * move at the properly speed. + * + * Event Movement Queue + * If an event were to move through an event command, changing a condition + * that would set the event to change to a different page would cause that + * event's move route to halt in its tracks. The plugin fixes this issue and + * the event's move route will finish. + * + * Event Colliding + * Events cannot move over other events with a Below Player setting. This + * makes it difficult for certain types of puzzles or events to exist. This + * plugin fixes this issue by making the collision check only apply to events + * of "Same as Characters" priority. Any event that's above or below the + * characters will no longer collide with other events. + * + * Screen Tearing + * When moving slowly, the tiles on the screen tear. While it's not + * noticeable on all systems, slower computers will definitely show it. The + * plugin will fix this issue and synch the tiles to keep up to pace with + * the screen's camera movement properly. + * + * Sprite Distortion + * Because of JavaScript's strange mathematical behavior, sometimes values + * with decimal places cause spritesheets to end up looking distorted. The + * plugin will get rid of the decimal places and have sprite sheets take out + * frames properly by using integer values only. + * + * ============================================================================ + * Gold + * ============================================================================ + * + * You can use the plugin commands to add or remove gold more than the + * editor's 9,999,999 limit. You can also place notetags into items, weapons, + * and armors to over the 999,999 cost limit. + * + * Plugin Command: + * GainGold 1234567890 # Party gains 1234567890 gold. + * LoseGold 9876543210 # Party loses 9876543210 gold. + * + * Item, Weapon, Armor Notetags + * + * Changes the price of the item to x. This notetag allows you to bypass the + * editor's 999,999 gold cost limit. + * + * Enemy Notetag + * + * Changes the gold drop value of enemies to x. This notetag allows you to + * bypass the editor's 9,999,999 gold drop limit. + * + * ============================================================================ + * Items + * ============================================================================ + * + * Change the parameters to reflect the maximum number of items a player can + * hold per item. If you wish to make individual items have different max + * values, use the following notetag: + * + * Item, Weapon, Armor Notetag: + * + * This changes the maximum amount of the item to x. + * + * ============================================================================ + * Stats + * ============================================================================ + * + * Even with the parameter limits raised, the editor is still confined to RPG + * Maker MV's default limits. To break past them, use the following notetags + * to allow further control over the individual aspects for the parameters. + * + * Actor Notetag + * + * Changes the actor's initial level to x. This allows you to bypass the + * editor's level 99 limit. + * + * + * Changes the actor's max level to x. This allows you to bypass the editor's + * level 99 limit. + * + * Class Skill Learn Notetag + * + * When placed inside a class's "Skills to Learn" notetag, this will cause + * the class to learn the skill at level x. + * + * Weapon and Armor Notetags + * + * + * Allows the piece of weapon or armor to gain or lose x amount of stat. + * Replace "stat" with "hp", "mp", "atk", "def", "mat", "mdf", "agi", or + * "luk" to alter that specific stat. This allows the piece of equipment + * to go past the editor's default limitation so long as the maximum value + * allows for it. + * + * Enemy Notetags + * + * This changes the enemy's stat to x amount. Replace "stat" with "hp", + * "mp", "atk", "def", "mat", "mdf", "agi", or "luk" to alter that + * specific stat. This allows the piece of equipment to go past the + * editor's default limitation. + * + * + * This changes the enemy's exp given out to x amount. This allows the + * enemy give out more exp than the editor's default 9,999,999 limit. + * + * ============================================================================ + * Script Call Fail Safe + * ============================================================================ + * + * Irregular code in damage formulas, script calls, conditional branches, and + * variable events will no longer crash the game. Instead, they will force open + * the console window to display the error only during test play. + * + * If the player is not in test play, the game will continue as normal without + * the error being shown. If the game is being played in a browser, opening up + * the console window will still display the error. + * + * ============================================================================ + * Changelog + * ============================================================================ + * + * Version Stronk.1 + * - Incorporated the plugin into Stronk!. This plugin is a dependency for Stronk! + * MV projects. + * + * Version 1.32: + * - Reversed the disable for the screen jitter fix from version 1.24. Somehow + * it came back and I don't know when, but now it needs to go. + * + * Version 1.31: + * - Added Fallen Angel Olivia's full error message display to the Core Engine + * (with her permission of course). + * - Bug fixed regarding blend modes and bush depth making sprites not blend + * properly in-game. + * - Tab key no longer requires you to press it twice before triggering Tab-key + * related inputs. + * + * Version 1.30: + * - Bug fixed for audio Sound Effect stacking. + * - Optimization update. + * + * Version 1.29: + * - Bypass the isDevToolsOpen() error when bad code is inserted into a script + * call or custom Lunatic Mode code segment due to updating to MV 1.6.1. + * + * Version 1.28: + * - Upon pressing F5 to reload your game, this will close the DevTools Debug + * Console if it is opened before reloading. This is because reloading with it + * closed ends up reloading the game faster. + * - New plugin parameters added: Refresh Update HP, MP, and TP + * - Option to choose to do a full actor refresh upon changing HP, MP, or TP + * - This is to reduce overall map lagging. + * + * Version 1.27: + * - Updated for RPG Maker MV version 1.6.0: + * - Fixing script call checks made with switches and self switches under + * conditional branches due to how ES6 handles === differently. + * + * Version 1.26: + * - Updated for RPG Maker MV version 1.6.0: + * - Removal of the destructive code in Scene_Item.update function. + * - Open Console parameter now occurs after the map's been loaded or after + * the battle has started. This is because after the 1.6.0 changes, loading + * the console before anything else will lock up other aspects of RPG Maker + * from loading properly. + * + * Version 1.25: + * - Updated for RPG Maker MV version 1.5.0. + * - Updated Scale Title and Scale GameOver to work with 1.5.0. + * + * Version 1.24: + * - Screen jittering prevention is now prevented for RPG Maker MV 1.3.4 and + * above since Pixi4 handles that now. + * + * Version 1.23: + * - For RPG Maker MV version 1.3.2 and above, the 'Scale Battlebacks' plugin + * parameter will now recreate the battleback sprites in a different format. + * This is because battleback scaling with Tiling Sprites is just too volatile. + * Battleback sprites are now just regular sprites instead of tiling sprites. + * This may or may not cause plugin incompatibilities with other plugins that + * alter battlebacks. + * - For RPG Maker MV version 1.3.4, Game_Actor.meetsUsableItemConditions is + * now updated to return a check back to the original Game_BattlerBase version + * to maintain compatibility with other plugins. + * + * Version 1.22: + * - Added 'Show Events Transition' plugin parameter. Enabling this will make + * events on the map no longer hide themselves while entering battle during the + * transition. + * - Added 'Show Events Snapshot' plugin parameter. Enabling this will keep + * events shown as a part of the battle snapshot when entering battle. + * - Irregular code in damage formulas, script calls, conditional branches, and + * variable events will no longer crash the game. Instead, it will force open + * the console window to display the error only during Test Play. + * + * Version 1.21: + * - Fixed a bug with scaling battlebacks not working properly for Front View. + * - Optimization update to keep garbage collection across all scenes. + * + * Version 1.20: + * - Altered increasing resolution function. + * - Added 'Update Real Scale' plugin parameter. This is best left alone for + * now and to be used if a later update meshes with rendered scaling. + * - Added memory clear functionality for versions under 1.3.2 to free up more + * memory upon leaving the map scene. + * - Added 'Collection Clear' plugin parameter. This option, if left on, will + * clear the attached children to Scene_Map and Scene_Battle upon switching to + * a different scene. This will potentially free up memory from various objects + * added to those scenes from other plugins (depending on how they're added) + * and serve as a means of reducing memory bloat. + * + * Version 1.19: + * - Updated for RPG Maker MV version 1.3.2. + * - Fixed 'LearnSkill' function for actors to not be bypassed if a piece of + * equipment has temporarily added a skill. + * + * Version 1.18: + * - Fixed a bug with scaling battlebacks not working properly for Front View. + * + * Version 1.17: + * - Updated for RPG Maker MV version 1.3.0. + * + * Version 1.16: + * - Fixed a bug with RPG Maker MV's inherent 'drawTextEx' function. By default + * it calculates the text height and then resets the font settings before + * drawing the text, which makes the text height inconsistent if it were to + * match the calculated height settings. + * + * Version 1.15: + * - Window's are now set to have only widths and heights of whole numbers. No + * longer is it possible for them to have decimal values. This is to reduce any + * and all clipping issues caused by non-whole numbers. + * + * Version 1.14: + * - Optimization update for RPG Maker MV itself by replacing more memory + * intensive loops in commonly used functions with more efficient loops. + * + * Version 1.13: + * - Updated for RPG Maker MV version 1.1.0. + * + * Version 1.12: + * - Fixed a bug with a notetag: . Now, the notetag works + * with both and + * + * Version 1.11: + * - Made fixes to the MV Source Code where FaceWidth was using a hard-coded + * 144 value regardless of what was changed for the Face Width parameter. + * - Fixed a notetag that wasn't working with the enemy EXP values. + * - Updated battler repositioning to no longer clash when entering-exiting the + * scene with Row Formation. + * + * Version 1.10: + * - Removed an MV bugfix that was applied through MV's newes tupdate. + * + * Version 1.09: + * - Changed minimum display width for status drawing to accomodate Party + * Formation defaults. + * + * Version 1.08: + * - Fixed a bug within the MV Source with changing classes and maintaining + * levels, even though the feature to maintain the levels has been removed. + * + * Version 1.07: + * - Fixed an issue with the gauges drawing outlines thicker than normal at odd + * intervals when windows are scaled irregularly. + * + * Version 1.06: + * - Removed event frequency bug fix since it's now included in the source. + * + * Version 1.05: + * - Added 'Scale Game Over' parameter to plugin settings. + * + * Version 1.04: + * - Reworked math for calculating scaled battleback locations. + * - Fixed a bug where if the party failed to escape from battle, states that + * would be removed by battle still get removed. *Fixed by Emjenoeg* + * + * Version 1.03: + * - Fixed a strange bug that made scaled battlebacks shift after one battle. + * + * Version 1.02: + * - Fixed a bug that made screen fading on mobile devices work incorrectly. + * - Added 'Scale Battlebacks' and 'Scale Title' parameters. + * + * Version 1.01: + * - Fixed a bug that where if button sprites had different anchors, they would + * not be properly clickable. *Fixed by Zalerinian* + * + * Version 1.00: + * - Finished plugin! + */ + +import * as gui from "nw"; +import { Utils } from "../core/Utils"; +import { PluginManager } from "../managers/PluginManager"; + +export interface YanflyCore {} + +export interface YanflyParams { + OpenConsole: string; + ReposBattlers: string; + GameFontTimer: number; + CollectionClear: string; + MaxGold: string; + GoldFontSize: number; + GoldOverlap: string; + MaxItem: number; + ItemQuantitySize: number; + MaxLevel: number; + EnemyMaxHp: number; + EnemyMaxMp: number; + EnemyParam: number; + ActorMaxHp: number; + ActorMaxMp: number; + ActorParam: number; + AnimationRate: number; + FlashTarget: any; + ShowEvTrans: string; + ShowEvSnap: string; + RefreshUpdateHp: string; + RefreshUpdateMp: string; + RefreshUpdateTp: string; + ChineseFont: string; + KoreanFont: string; + DefaultFont: string; + FontSize: number; + TextAlign: CanvasTextAlign; + DigitGroup: any; + LineHeight: number; + IconWidth: number; + IconHeight: number; + FaceWidth: number; + FaceHeight: number; + WindowPadding: number; + TextPadding: number; + WindowOpacity: number; + GaugeOutline: any; + GaugeHeight: number; + MenuTpGauge: any; + ColorNormal: number; + ColorSystem: number; + ColorCrisis: number; + ColorDeath: number; + ColorGaugeBack: number; + ColorHpGauge1: number; + ColorHpGauge2: number; + ColorMpGauge1: number; + ColorMpGauge2: number; + ColorMpCost: number; + ColorPowerUp: number; + ColorPowerDown: number; + ColorTpGauge1: number; + ColorTpGauge2: number; + ColorTpCost: number; +} + +export interface YanflyIcons { + Gold: number; +} + +export interface YanflyUtils { + toGroup(inVal: any): string; + displayError(e: Error, code: string, message: string): void; +} + +export interface YEP { + _openedConsole: boolean; + _loaded_YEP_CoreEngine: boolean; + version: string; + Core: Partial; + Parameters: any; + Param: Partial; + Icon: Partial; + Util: Partial; + openConsole(): void; + focusWindow(win: any): void; +} + +const Yanfly: Partial = { + _loaded_YEP_CoreEngine: false, + _openedConsole: false, + version: "Stronk.1", + Core: {} as Partial, + Parameters: PluginManager.parameters("Stronk_YEP_CoreEngine"), + Param: {} as Partial, + Icon: {} as Partial, + Util: { + toGroup(inVal) { + if (typeof inVal === "string") return inVal; + if (!Yanfly.Param.DigitGroup) return inVal; + return inVal.toLocaleString("en"); + // return inVal.replace(/(^|[^\w.])(\d{4,})/g, function($0, $1, $2) { + // return $1 + $2.replace(/\d(?=(?:\d\d\d)+(?!\d))/g, "$&,"); + // }); + }, + + displayError(e, code, message) { + console.log(message); + console.log(code || "NON-EXISTENT"); + console.error(e); + if (Utils.RPGMAKER_VERSION && Utils.RPGMAKER_VERSION >= "1.6.0") + return; + if (Utils.isNwjs() && Utils.isOptionValid("test")) { + if (!gui.Window.get().isDevToolsOpen()) { + gui.Window.get().showDevTools(); + } + } + } + } as Partial, + openConsole() { + Yanfly._openedConsole = true; + if (!Yanfly.Param.OpenConsole) return; + if (Utils.isNwjs() && Utils.isOptionValid("test")) { + const win = gui.Window.get(); + win.showDevTools(); + setTimeout(this.focusWindow.bind(this, win), 500); + } + }, + focusWindow(win) { + win.focus(); + } +}; + +//= ======= ===================================================================== +// Parameter Variables +//= ======= ===================================================================== + +Yanfly.Param.OpenConsole = String(Yanfly.Parameters["Open Console"]); +Yanfly.Param.OpenConsole = eval(Yanfly.Param.OpenConsole); +Yanfly.Param.ReposBattlers = String(Yanfly.Parameters["Reposition Battlers"]); +Yanfly.Param.ReposBattlers = eval(Yanfly.Param.ReposBattlers); +Yanfly.Param.GameFontTimer = Number(Yanfly.Parameters["GameFont Load Timer"]); +Yanfly.Param.CollectionClear = String(Yanfly.Parameters["Collection Clear"]); +Yanfly.Param.CollectionClear = eval(Yanfly.Param.CollectionClear); + +Yanfly.Param.MaxGold = String(Yanfly.Parameters["Gold Max"]); +Yanfly.Param.GoldFontSize = Number(Yanfly.Parameters["Gold Font Size"]); +Yanfly.Icon.Gold = Number(Yanfly.Parameters["Gold Icon"]); +Yanfly.Param.GoldOverlap = String(Yanfly.Parameters["Gold Overlap"]); + +Yanfly.Param.MaxItem = Number(Yanfly.Parameters["Default Max"]); +Yanfly.Param.ItemQuantitySize = Number(Yanfly.Parameters["Quantity Text Size"]); + +Yanfly.Param.MaxLevel = Number(Yanfly.Parameters["Max Level"]); +Yanfly.Param.EnemyMaxHp = Number(Yanfly.Parameters["Enemy MaxHP"]); +Yanfly.Param.EnemyMaxMp = Number(Yanfly.Parameters["Enemy MaxMP"]); +Yanfly.Param.EnemyParam = Number(Yanfly.Parameters["Enemy Parameter"]); +Yanfly.Param.ActorMaxHp = Number(Yanfly.Parameters["Actor MaxHP"]); +Yanfly.Param.ActorMaxMp = Number(Yanfly.Parameters["Actor MaxMP"]); +Yanfly.Param.ActorParam = Number(Yanfly.Parameters["Actor Parameter"]); + +Yanfly.Param.AnimationRate = Number(Yanfly.Parameters["Animation Rate"]); +Yanfly.Param.FlashTarget = eval(String(Yanfly.Parameters["Flash Target"])); +Yanfly.Param.ShowEvTrans = String(Yanfly.Parameters["Show Events Transition"]); +Yanfly.Param.ShowEvTrans = eval(Yanfly.Param.ShowEvTrans); +Yanfly.Param.ShowEvSnap = String(Yanfly.Parameters["Show Events Snapshot"]); +Yanfly.Param.ShowEvSnap = eval(Yanfly.Param.ShowEvSnap); + +Yanfly.Param.RefreshUpdateHp = String(Yanfly.Parameters["Refresh Update HP"]); +Yanfly.Param.RefreshUpdateHp = eval(Yanfly.Param.RefreshUpdateHp); +Yanfly.Param.RefreshUpdateMp = String(Yanfly.Parameters["Refresh Update MP"]); +Yanfly.Param.RefreshUpdateMp = eval(Yanfly.Param.RefreshUpdateMp); +Yanfly.Param.RefreshUpdateTp = String(Yanfly.Parameters["Refresh Update TP"]); +Yanfly.Param.RefreshUpdateTp = eval(Yanfly.Param.RefreshUpdateTp); + +Yanfly.Param.ChineseFont = String(Yanfly.Parameters["Chinese Font"]); +Yanfly.Param.KoreanFont = String(Yanfly.Parameters["Korean Font"]); +Yanfly.Param.DefaultFont = String(Yanfly.Parameters["Default Font"]); +Yanfly.Param.FontSize = Number(Yanfly.Parameters["Font Size"]); +Yanfly.Param.TextAlign = String( + Yanfly.Parameters["Text Align"] +) as CanvasTextAlign; + +Yanfly.Param.DigitGroup = eval(String(Yanfly.Parameters["Digit Grouping"])); +Yanfly.Param.LineHeight = Number(Yanfly.Parameters["Line Height"]); +Yanfly.Param.IconWidth = Number(Yanfly.Parameters["Icon Width"] || 32); +Yanfly.Param.IconHeight = Number(Yanfly.Parameters["Icon Height"] || 32); +Yanfly.Param.FaceWidth = Number(Yanfly.Parameters["Face Width"] || 144); +Yanfly.Param.FaceHeight = Number(Yanfly.Parameters["Face Height"] || 144); +Yanfly.Param.WindowPadding = Number(Yanfly.Parameters["Window Padding"]); +Yanfly.Param.TextPadding = Number(Yanfly.Parameters["Text Padding"]); +Yanfly.Param.WindowOpacity = Number(Yanfly.Parameters["Window Opacity"]); +Yanfly.Param.GaugeOutline = eval(String(Yanfly.Parameters["Gauge Outline"])); +Yanfly.Param.GaugeHeight = Number(Yanfly.Parameters["Gauge Height"]); +Yanfly.Param.MenuTpGauge = eval(String(Yanfly.Parameters["Menu TP Bar"])); + +Yanfly.Param.ColorNormal = Number(Yanfly.Parameters["Color: Normal"]); +Yanfly.Param.ColorSystem = Number(Yanfly.Parameters["Color: System"]); +Yanfly.Param.ColorCrisis = Number(Yanfly.Parameters["Color: Crisis"]); +Yanfly.Param.ColorDeath = Number(Yanfly.Parameters["Color: Death"]); +Yanfly.Param.ColorGaugeBack = Number(Yanfly.Parameters["Color: Gauge Back"]); +Yanfly.Param.ColorHpGauge1 = Number(Yanfly.Parameters["Color: HP Gauge 1"]); +Yanfly.Param.ColorHpGauge2 = Number(Yanfly.Parameters["Color: HP Gauge 2"]); +Yanfly.Param.ColorMpGauge1 = Number(Yanfly.Parameters["Color: MP Gauge 1"]); +Yanfly.Param.ColorMpGauge2 = Number(Yanfly.Parameters["Color: MP Gauge 2"]); +Yanfly.Param.ColorMpCost = Number(Yanfly.Parameters["Color: MP Cost"]); +Yanfly.Param.ColorPowerUp = Number(Yanfly.Parameters["Color: Power Up"]); +Yanfly.Param.ColorPowerDown = Number(Yanfly.Parameters["Color: Power Down"]); +Yanfly.Param.ColorTpGauge1 = Number(Yanfly.Parameters["Color: TP Gauge 1"]); +Yanfly.Param.ColorTpGauge2 = Number(Yanfly.Parameters["Color: TP Gauge 2"]); +Yanfly.Param.ColorTpCost = Number(Yanfly.Parameters["Color: TP Cost Color"]); + +export { Yanfly }; diff --git a/ts/plugins/Stronk_YEP_ExtraParamFormula.ts b/ts/plugins/Stronk_YEP_ExtraParamFormula.ts new file mode 100644 index 0000000..607bfd8 --- /dev/null +++ b/ts/plugins/Stronk_YEP_ExtraParamFormula.ts @@ -0,0 +1,412 @@ +import { PluginManager } from "../managers/PluginManager"; +import { DataManager } from "../managers/DataManager"; +import { Game_BattlerBase } from "../objects/Game_BattlerBase"; +import { Game_Battler } from "../objects/Game_Battler"; +import { Game_Actor } from "../objects/Game_Actor"; +import { Game_Enemy } from "../objects/Game_Enemy"; +import { Utils } from "../core/Utils"; +import { Yanfly } from "./Stronk_YEP_CoreEngine"; + +//============================================================================= +// Yanfly Engine Plugins - Extra Parameter Formula +// YEP_ExtraParamFormula.js +//============================================================================= + +declare module "./Stronk_YEP_CoreEngine" { + interface YEP { + XParam: { version: number }; + _loaded_YEP_ExtraParamFormula: boolean; + } + + interface YanflyParams { + XParamFormula: string[]; + } +} + +Yanfly.XParam = { version: 1.04 }; +Yanfly._loaded_YEP_ExtraParamFormula = false; + +/*: + * @plugindesc v1.04 Control the formulas of the extra parameters for + * HIT, EVA, CRI, CEV, MEV, MRF, CNT, HRG, MRG, and TRG. + * @author Yanfly Engine Plugins + * + * @param HIT Formula + * @desc The formula used to determine HIT: Hit% + * This is a formula. + * @default (base + plus) * rate + flat + * + * @param EVA Formula + * @desc The formula used to determine EVA: Evasion% + * This is a formula. + * @default (base + plus) * rate + flat + * + * @param CRI Formula + * @desc The formula used to determine CRI: Critical Hit% + * This is a formula. + * @default (base + plus) * rate + flat + * + * @param CEV Formula + * @desc The formula used to determine CEV: Critical Evasion% + * This is a formula. + * @default (base + plus) * rate + flat + * + * @param MEV Formula + * @desc The formula used to determine MEV: Magic Evasion% + * This is a formula. + * @default (base + plus) * rate + flat + * + * @param MRF Formula + * @desc The formula used to determine MRF: Magic Reflect% + * This is a formula. + * @default (base + plus) * rate + flat + * + * @param CNT Formula + * @desc The formula used to determine CNT: Counter Attack% + * This is a formula. + * @default (base + plus) * rate + flat + * + * @param HRG Formula + * @desc The formula used to determine HRG: HP% Regen + * This is a formula. + * @default (base + plus) * rate + flat + * + * @param MRG Formula + * @desc The formula used to determine MRG: MP% Regen + * This is a formula. + * @default (base + plus) * rate + flat + * + * @param TRG Formula + * @desc The formula used to determine TRG: Target Rate + * This is a formula. + * @default (base + plus) * rate + flat + * + * @help + * ============================================================================ + * Introduction + * ============================================================================ + * + * The values for the Extra Parameters: HIT, EVA, CRI, CEV, MEV, MRF, CNT, HRG, + * MRG, and TRG, in RPG Maker MV are only able to be ever modified by traits by + * the various database objects. While it is flexible, RPG Maker MV does not + * enable you to utilize custom formulas to make things such as ATK and AGI + * influence HIT rate or LUK influence CRItical hits. With this plugin, now you + * can along with a few more goodies! + * + * ============================================================================ + * Instructions - Extra Parameter Explanation + * ============================================================================ + * + * For those who aren't familiar with what the Extra Parameters (xparams) do, + * this is a list that will explain their standard functions in an RPG Maker MV + * project. + * + * --- + * + * HIT - Hit Rate% + * - This determines the physical hit success rate of the any physical action. + * All physical attacks make a check through the HIT rate to see if the attack + * will connect. If the HIT value passes the randomizer check, the attack will + * connect. If the HIT value fails to pass the randomizer check, the attack + * will be considered a MISS. + * + * --- + * + * EVA - Evasion Rate% + * - This determines the physical evasion rate against any incoming physical + * actions. If the HIT value passes, the action is then passed to the EVA check + * through a randomizer check. If the randomizer check passes, the physical + * attack is evaded and will fail to connect. If the randomizer check passes, + * the attempt to evade the action will fail and the action connects. + * + * --- + * + * CRI - Critical Hit Rate% + * - Any actions that enable Critical Hits will make a randomizer check with + * this number. If the randomizer check passes, extra damage will be carried + * out by the initiated action. If the randomizer check fails, no extra damage + * will be added upon the action. + * + * --- + * + * CEV - Critical Evasion Rate% + * - This value is put against the Critical Hit Rate% in a multiplicative rate. + * If the Critical Hit Rate is 90% and the Critical Evasion Rate is + * 20%, then the randomizer check will make a check against 72% as the values + * are calculated by the source code as CRI * (1 - CEV), therefore, with values + * as 0.90 * (1 - 0.20) === 0.72. + * + * --- + * + * MEV - Magic Evasion Rate% + * - Where EVA is the evasion rate against physical actions, MEV is the evasion + * rate against magical actions. As there is not magical version of HIT, the + * MEV value will always be bit against when a magical action is initiated. If + * the randomizer check passes for MEV, the magical action will not connect. If + * the randomizer check fails for MEV, the magical action will connect. + * + * --- + * + * MRF - Magic Reflect Rate% + * - If a magical action connects and passes, there is a chance the magical + * action can be bounced back to the caster. That chance is the Magic Reflect + * Rate. If the randomizer check for the Magic Reflect Rate passes, then the + * magical action is bounced back to the caster, ignoring the caster's Magic + * Evasion Rate. If the randomizer check for the Magic Reflect Rate fails, then + * the magical action will connect with its target. + * + * --- + * + * CNT - Counter Attack Rate% + * - If a physical action connects and passes, there is a chance the physical + * action can be avoided and a counter attack made by the user will land on the + * attacking unit. This is the Counter Attack Rate. If the randomizer check for + * the Counter Attack Rate passes, the physical action is evaded and the target + * will counter attack the user. If the randomizer check fails, the physical + * action will connect to the target. + * + * --- + * + * HRG - HP% Regeneration + * - During a battler's regeneration phase, the battler will regenerate this + * percentage of its MaxHP as gained HP with a 100% success rate. + * + * --- + * + * MRG - MP% Regeneration + * - During a battler's regeneration phase, the battler will regenerate this + * percentage of its MaxMP as gained MP with a 100% success rate. + * + * --- + * + * TRG - TP% Regeneration + * - During a battler's regeneration phase, the battler will regenerate this + * percentage of its MaxTP as gained TP with a 100% success rate. + * + * --- + * + * ============================================================================ + * Instructions - Custom Formulas + * ============================================================================ + * + * The values calculated by the formulas in the plugin parameters are to come + * out as float values. If the result value comes out as 0.1 for CRI, it will + * be 10% CRI. Here is an example: + * + * (base + plus) * rate + flat + user.luk / 1000 + * + * The 'user.luk / 1000' is inserted at the end. Assuming everything else comes + * out to be 10% and the user's LUK parameter is at 500, it will be 0.1 + 0.5 + * which means the total comes out to 0.6, hence a 60% CRItical hit rate. + * + * ============================================================================ + * Instructions - Understanding Formula Variables + * ============================================================================ + * + * So, what does the 'base', 'plus', 'rate', and 'flat' mean in the formulas? + * This section will answer that in detail. + * + * Default plugin formula: (base + plus) * rate + flat + * + * BASE + * - This value is determined by the default way RPG Maker MV determines the + * value for that stat, and the way RPG Maker MV determines it is by adding up + * the total trait values of that stat. If a battler would have a mixture of + * +95%, -10%, and +5% HIT traits, then the base stat value would be +90%. + * + * PLUS + * - This is a new variable added by this plugin. Its purpose is to function as + * an addition to the base value. This addition can be done independently of + * database items as you can do a user.addXParam to alter the base value of the + * extra parameter. If using the default formula, this value is added to the + * base before any rates are multiplied by it and any flats added to the total. + * + * RATE + * - This is a new variable added by this plugin. Its purpose is to function as + * a multiplicative modifier for the extra parameter value. This multiplicative + * value is determined by various database objects through notetags. If using + * the default formula, this value is multipled to the sum of the base and plus + * values of the extra parameter before the flat is added to the total. + * + * FLAT + * - This is a new variable added by this plugin. Its purpose is to function as + * an additive modifier for the extra parameter value. This additive value is + * determined by various database objects through notetags. If using the plugin + * default formula, this value is added after the sum of the base and plus + * values of the extra parameter stat are multiplied by the rate value. + * + * ============================================================================ + * Examples - Sample Formulas + * ============================================================================ + * + * The following are some sample formulas you can use to make extra parameters + * a bit more dynamic: + * + * --- HIT --- + * (base + plus) * rate + flat + ((user.atk + user.agi) / 2000) + * - This will cause the HIT rate to gain bonus accuracy from ATK and AGI. + * + * --- EVA --- + * (base + plus) * rate + flat + ((user.def + user.agi) / 2000) + * - This will cause the EVA rate to gain bonus evasion from DEF and AGI. + * + * --- CRI --- + * (base + plus) * rate + flat + (user.luk / 1000) + * - This will cause the CRI rate to gain bonus success from LUK. + * + * --- CEV --- + * (base + plus) * rate + flat + ((user.agi + user.luk) / 2000) + * - This will cause the CEV rate to gain more critical evade from LUK and AGI. + * + * --- MEV --- + * (base + plus) * rate + flat + ((user.mdf + user.agi) / 2000) + * - This will cause the MEV rate to gain extra magic evasion from MDF and AGI. + * + * The above are some examples on how you can make your extra parameters to be + * affected by the other stats from the user. + * + * ============================================================================ + * Notetags + * ============================================================================ + * + * You can use the following notetags to alter the various aspects that modify + * the extra parameter values: + * + * Actor, Class, Enemy, Weapon, Armor, and State Notetags: + * + * + * + * + * + * Replace 'stat' with 'hit', 'eva', 'cri', 'cev', 'mev', 'mrf', 'cnt', + * 'hrg', 'mrg', or 'trg'. This is the value added to the base parameter + * before the rate and flat values contribute to the total parameter value + * assuming the plugin's default formula is utilized. + * + * + * + * Replace 'stat' with 'hit', 'eva', 'cri', 'cev', 'mev', 'mrf', 'cnt', + * 'hrg', 'mrg', or 'trg'. This is the value multipled to the sum of the base + * and plus values of the parameter before added by the flat value assuming + * the plugin's default formula is utilized. + * + * + * + * + * + * Replace 'stat' with 'hit', 'eva', 'cri', 'cev', 'mev', 'mrf', 'cnt', + * 'hrg', 'mrg', or 'trg'. This is the value added finally to the sum of the + * base and plus values after being multiplied by the rate value assuming the + * plugin's default formula is utilized. + * + * ============================================================================ + * Lunatic Mode - New JavaScript Functions + * ============================================================================ + * + * You can use the following JavaScript functions to alter the extra parameter + * values of actors. In these listed functions, the 'actor' variable is to be + * referenced by an actor: + * + * ie. actor = $gameActors.actor(3)); + * + * Function: + * + * actor.clearXParamPlus() + * - Clears all of the actor's extra parameter plus bonuses. + * + * actor.setHit(x) + * actor.setEva(x) + * actor.setCri(x) + * actor.setCev(x) + * actor.setMev(x) + * actor.setMrf(x) + * actor.setCnt(x) + * actor.setHrg(x) + * actor.setMrg(x) + * actor.setTrg(x) + * - Sets the actor's respective extra parameter value to x. Keep in mind + * that 1 is equal to 100% and 0.1 would be equal to 10%. Negative values + * will apply here, too. + * + * actor.setHitPlus(x) + * actor.setEvaPlus(x) + * actor.setCriPlus(x) + * actor.setCevPlus(x) + * actor.setMevPlus(x) + * actor.setMrfPlus(x) + * actor.setCntPlus(x) + * actor.setHrgPlus(x) + * actor.setMrgPlus(x) + * actor.setTrgPlus(x) + * - Sets the actor's respective extra parameter plus value to x. Keep in + * mind that 1 is equal to 100% and 0.1 would be equal to 10%. Negative + * values will apply here, too. + * + * actor.addHit(x) + * actor.addEva(x) + * actor.addCri(x) + * actor.addCev(x) + * actor.addMev(x) + * actor.addMrf(x) + * actor.addCnt(x) + * actor.addHrg(x) + * actor.addMrg(x) + * actor.addTrg(x) + * - Adds x to the actor's respective extra parameter value. Keep in mind + * that 1 is equal to 100% and 0.1 would be equal to 10%. Negative values + * will decrease the extra parameter. + * + * actor.minusHit(x) + * actor.minusEva(x) + * actor.minusCri(x) + * actor.minusCev(x) + * actor.minusMev(x) + * actor.minusMrf(x) + * actor.minusCnt(x) + * actor.minusHrg(x) + * actor.minusMrg(x) + * actor.minusTrg(x) + * - Subtracts x from the actor's respective extra parameter value. Keep in + * mind that 1 is equal to 100% and 0.1 would be equal to 10%. Negative + * values will add to the extra parameter. + * + * ============================================================================ + * Changelog + * ============================================================================ + * + * Version 1.04: + * - Updated for RPG Maker MV version 1.5.0. + * + * Version 1.03a: + * - Lunatic Mode fail safe added. + * - Documentation update to fix typos. + * + * Version 1.02: + * - Fixed an issue with the battler.setXParam functions that made them take + * the wrong value due caching issues. + * + * Version 1.01: + * - Updated for RPG Maker MV version 1.1.0. + * + * Version 1.00: + * - Finished Plugin! + */ + +//============================================================================= +// Parameter Variables +//============================================================================= + +Yanfly.Parameters = PluginManager.parameters("Stronk_YEP_ExtraParamFormula"); +Yanfly.Param = Yanfly.Param || {}; + +Yanfly.Param.XParamFormula = []; +Yanfly.Param.XParamFormula.push(String(Yanfly.Parameters["HIT Formula"])); +Yanfly.Param.XParamFormula.push(String(Yanfly.Parameters["EVA Formula"])); +Yanfly.Param.XParamFormula.push(String(Yanfly.Parameters["CRI Formula"])); +Yanfly.Param.XParamFormula.push(String(Yanfly.Parameters["CEV Formula"])); +Yanfly.Param.XParamFormula.push(String(Yanfly.Parameters["MEV Formula"])); +Yanfly.Param.XParamFormula.push(String(Yanfly.Parameters["MRF Formula"])); +Yanfly.Param.XParamFormula.push(String(Yanfly.Parameters["CNT Formula"])); +Yanfly.Param.XParamFormula.push(String(Yanfly.Parameters["HRG Formula"])); +Yanfly.Param.XParamFormula.push(String(Yanfly.Parameters["MRG Formula"])); +Yanfly.Param.XParamFormula.push(String(Yanfly.Parameters["TRG Formula"])); diff --git a/ts/plugins/Stronk_YEP_LoadCustomFonts.ts b/ts/plugins/Stronk_YEP_LoadCustomFonts.ts new file mode 100644 index 0000000..c5ac018 --- /dev/null +++ b/ts/plugins/Stronk_YEP_LoadCustomFonts.ts @@ -0,0 +1,117 @@ +import { Yanfly } from "./Stronk_YEP_CoreEngine"; +import { PluginManager } from "../managers/PluginManager"; +import { Graphics } from "../core/Graphics"; + +//============================================================================= +// Yanfly Engine Plugins - Load Custom Fonts +// YEP_LoadCustomFonts.js +//============================================================================= + +declare module "./Stronk_YEP_CoreEngine" { + interface YEP { + LCF: { version: number }; + _loaded_YEP_ExtraParamFormula: boolean; + } + + interface YanflyParams { + LCFFontFilenames: string; + LCFFontFamilies: string; + } + + interface YanflyUtils { + loadCustomFonts(): void; + } +} + +Yanfly.LCF = { version: 1.01 }; + +/*: + * @plugindesc v1.01 Load custom fonts from the /fonts/ folder. This will + * allow you to use custom fonts without installing them. + * @author Yanfly Engine Plugins + * + * @param Font Filenames + * @desc These are full filenames of the fonts to be loaded from the + * /fonts/ folder of your project. Separate each with , + * @default cc-wild-words.ttf, ds-pixel-cyr.ttf + * + * @param Font Families + * @desc The font family names of the fonts. Keep them in the same + * order as the parameter above. Separate each with , + * @default CC Wild Words, DS Pixel Cyr + * + * @help + * ============================================================================ + * Introduction & Instructions + * ============================================================================ + * + * For those using custom fonts, you may have noticed that not all fonts from + * the /fonts/ directory are loaded at the time the game is loaded. This plugin + * let's you place the fonts into the /fonts/ directory and then load them as + * the game starts. + * + * To use this plugin, follow these instructions: + * + * The plugin parameters 'Font Filenames' and 'Font Families' have to be filled + * out in correspondence to each other. The order of each font entry must match + * each other's. For example: + * + * Font Filenames: cc-wild-words.ttf, ds-pixel-cyr.ttf + * + * Font Families: CC Wild Words, DS Pixel Cyr + * + * In the above example, 'cc-wild-words.ttf' will use 'CC Wild Words' as its + * font family and 'ds-pixel-cyr.ttf' will use 'DS Pixel Cyr'. For the plugins + * that use font names such as YEP's Message Core, you will be using the Font + * Family name instead of the filename. + * + * ============================================================================ + * Changelog + * ============================================================================ + * + * Version 1.01: + * - Updated for RPG Maker MV version 1.5.0. + * + * Version 1.00: + * - Finished Plugin! + */ + +//============================================================================= +// Parameter Variables +//============================================================================= + +Yanfly.Parameters = PluginManager.parameters("Stronk_YEP_LoadCustomFonts"); +Yanfly.Param = Yanfly.Param || {}; + +Yanfly.Param.LCFFontFilenames = String(Yanfly.Parameters["Font Filenames"]); +Yanfly.Param.LCFFontFamilies = String(Yanfly.Parameters["Font Families"]); + +Yanfly.Util.loadCustomFonts = function() { + var filenames = Yanfly.Param.LCFFontFilenames.split(","); + var fontfamilies = Yanfly.Param.LCFFontFamilies.split(","); + if (filenames.length !== fontfamilies.length) { + if (filenames.length > fontfamilies.length) { + console.log( + "You are missing fonts in the Font Families parameter." + ); + } + if (filenames.length < fontfamilies.length) { + console.log( + "You are missing fonts in the Font Filenames parameter." + ); + } + console.log("Loading custom fonts aborted."); + return; + } + var projectDirectory = window.location.pathname.substring( + 0, + window.location.pathname.lastIndexOf("/") + ); + var length = filenames.length; + for (var i = 0; i < length; ++i) { + var filename = filenames[i].trim(); + var fontfamily = fontfamilies[i].trim(); + Graphics.loadFont(fontfamily, projectDirectory + "/fonts/" + filename); + } +}; +Yanfly.Util.loadCustomFonts(); diff --git a/ts/scenes/Scene_Base.ts b/ts/scenes/Scene_Base.ts index ec216ec..38c2e36 100644 --- a/ts/scenes/Scene_Base.ts +++ b/ts/scenes/Scene_Base.ts @@ -10,13 +10,15 @@ import { Scene_Gameover } from "./Scene_Gameover"; export class Scene_Base extends Stage { protected _fadeSprite: any; - protected _windowLayer: WindowLayer; + public _windowLayer: WindowLayer; protected _active: boolean; protected _fadeSign: number; protected _fadeDuration: number; protected _imageReservationId: number; protected importantBitmapsAreLoaded: boolean; protected _bypassFirstClear: boolean; + protected _debugActive: boolean; + public _logWindow: any; public constructor() { super(); @@ -26,6 +28,15 @@ export class Scene_Base extends Stage { this._fadeSprite = null; this._imageReservationId = Utils.generateRuntimeId(); this.importantBitmapsAreLoaded = false; + this._debugActive = false; + } + + public get debugActive(): boolean { + return this._debugActive; + } + + public set debugActive(value: boolean) { + this._debugActive = value; } /** diff --git a/ts/scenes/Scene_Battle.ts b/ts/scenes/Scene_Battle.ts index 11b9870..8af78b3 100644 --- a/ts/scenes/Scene_Battle.ts +++ b/ts/scenes/Scene_Battle.ts @@ -19,14 +19,17 @@ import { Scene_Base } from "./Scene_Base"; import { Scene_Gameover } from "./Scene_Gameover"; import { Scene_Title } from "./Scene_Title"; import { Window_ItemList } from "../windows/Window_ItemList"; -import { Window_SkillList } from "../windows/Window_SkillList"; import { ConfigManager } from "../managers/ConfigManager"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; +import { Game_CommonEvent } from "../objects/Game_CommonEvent"; +import { CommonEvent } from "../interfaces/CommonEvent"; +import { Window_Base } from "../windows/Window_Base"; export class Scene_Battle extends Scene_Base { private _partyCommandWindow: Window_PartyCommand; private _actorCommandWindow: Window_ActorCommand; - private _skillWindow: Window_SkillList; - private _itemWindow: Window_ItemList; + private _skillWindow: Window_BattleSkill; + private _itemWindow: Window_BattleItem; private _actorWindow: Window_BattleActor; private _enemyWindow: Window_BattleEnemy; private _statusWindow: Window_BattleStatus; @@ -34,11 +37,15 @@ export class Scene_Battle extends Scene_Base { private _helpWindow: Window_Help; private _scrollTextWindow: Window_ScrollText; private _spriteset: Spriteset_Battle; - private _logWindow: Window_BattleLog; + public _logWindow: Window_BattleLog; + _isStartActorCommand: any; + + private commonEvents: Game_CommonEvent[]; public create() { super.create(); this.createDisplayObjects(); + this.commonEvents = []; } public start() { @@ -46,6 +53,11 @@ export class Scene_Battle extends Scene_Base { this.startFadeIn(this.fadeSpeed(), false); BattleManager.playBattleBgm(); BattleManager.startBattle(); + for (const event of $dataCommonEvents) { + if (event) { + this.commonEvents.push(new Game_CommonEvent(event.id)); + } + } } public update() { @@ -58,6 +70,18 @@ export class Scene_Battle extends Scene_Base { this.updateBattleProcess(); } super.update(); + if (!Yanfly._openedConsole) Yanfly.openConsole(); + this.updateStatusWindowRequests(); + for (const event of this.commonEvents) { + event.refresh(); + event.update(); + } + } + + public updateStatusWindowRequests() { + if (!this._statusWindow) return; + if (this._statusWindow.isClosed()) return; + this._statusWindow.updateStatusRequests(); } public updateBattleProcess() { @@ -262,6 +286,9 @@ export class Scene_Battle extends Scene_Base { this._skillWindow.setHandler("ok", this.onSkillOk.bind(this)); this._skillWindow.setHandler("cancel", this.onSkillCancel.bind(this)); this.addWindow(this._skillWindow); + if (Yanfly.Param.BECLowerWindows) { + this.adjustWindow(this._skillWindow); + } } public createItemWindow() { @@ -272,6 +299,9 @@ export class Scene_Battle extends Scene_Base { this._itemWindow.setHandler("ok", this.onItemOk.bind(this)); this._itemWindow.setHandler("cancel", this.onItemCancel.bind(this)); this.addWindow(this._itemWindow); + if (Yanfly.Param.BECLowerWindows) { + this.adjustWindow(this._itemWindow); + } } public createActorWindow() { @@ -279,6 +309,11 @@ export class Scene_Battle extends Scene_Base { this._actorWindow.setHandler("ok", this.onActorOk.bind(this)); this._actorWindow.setHandler("cancel", this.onActorCancel.bind(this)); this.addWindow(this._actorWindow); + this._actorWindow.x = + ConfigManager.currentResolution.widthPx - this._actorWindow.width; + if (Yanfly.Param.BECSelectHelp) { + this._actorWindow.setHelpWindow(this._helpWindow); + } } public createEnemyWindow() { @@ -291,6 +326,14 @@ export class Scene_Battle extends Scene_Base { this._enemyWindow.setHandler("ok", this.onEnemyOk.bind(this)); this._enemyWindow.setHandler("cancel", this.onEnemyCancel.bind(this)); this.addWindow(this._enemyWindow); + if (Yanfly.Param.BECSelectHelp) { + this._enemyWindow.setHelpWindow(this._helpWindow); + } + } + + private adjustWindow(win: Window_Base) { + win.height = win.fittingHeight(Yanfly.Param.BECWindowRows); + win.y = Graphics.boxHeight - win.height; } public createMessageWindow() { @@ -311,11 +354,22 @@ export class Scene_Battle extends Scene_Base { } public startPartyCommandSelection() { - this.refreshStatus(); - this._statusWindow.deselect(); - this._statusWindow.open(); - this._actorCommandWindow.close(); - this._partyCommandWindow.setup(); + if (this.isStartActorCommand()) { + this.selectNextCommand(); + } else { + this.refreshStatus(); + this._statusWindow.deselect(); + this._statusWindow.open(); + this._actorCommandWindow.close(); + this._partyCommandWindow.setup(); + } + } + + public isStartActorCommand() { + if (this._isStartActorCommand === undefined) { + this._isStartActorCommand = Yanfly.Param.BECStartActCmd; + } + return this._isStartActorCommand; } public commandFight() { @@ -328,9 +382,11 @@ export class Scene_Battle extends Scene_Base { } public startActorCommandSelection() { + BattleManager.createActions(); this._statusWindow.select(BattleManager.actor().index()); this._partyCommandWindow.close(); this._actorCommandWindow.setup(BattleManager.actor()); + this._statusWindow.refresh(); } public commandAttack() { @@ -339,6 +395,7 @@ export class Scene_Battle extends Scene_Base { } public commandSkill() { + this._helpWindow.clear(); this._skillWindow.setActor(BattleManager.actor()); this._skillWindow.setStypeId(this._actorCommandWindow.currentExt()); this._skillWindow.refresh(); @@ -352,7 +409,9 @@ export class Scene_Battle extends Scene_Base { } public commandItem() { + this._helpWindow.clear(); this._itemWindow.refresh(); + this._itemWindow.actor = BattleManager.actor(); this._itemWindow.show(); this._itemWindow.activate(); } @@ -360,17 +419,32 @@ export class Scene_Battle extends Scene_Base { public selectNextCommand() { BattleManager.selectNextCommand(); this.changeInputWindow(); + this._helpWindow.clear(); + BattleManager.stopAllSelection(); } public selectPreviousCommand() { - BattleManager.selectPreviousCommand(); - this.changeInputWindow(); + if (this.isStartActorCommand()) { + BattleManager.selectPreviousCommand(); + if (BattleManager.isInputting() && BattleManager.actor()) { + this.startActorCommandSelection(); + } else { + BattleManager.selectPreviousCommand(); + this.changeInputWindow(); + } + } else { + BattleManager.selectPreviousCommand(); + this.changeInputWindow(); + } } public selectActorSelection() { + if (Yanfly.Param.BECSelectHelp) this._helpWindow.show(); + this._helpWindow.clear(); this._actorWindow.refresh(); this._actorWindow.show(); this._actorWindow.activate(); + this._actorWindow.autoSelect(); } public onActorOk() { @@ -383,6 +457,8 @@ export class Scene_Battle extends Scene_Base { } public onActorCancel() { + if (Yanfly.Param.BECSelectHelp) this._helpWindow.hide(); + this._helpWindow.clear(); this._actorWindow.hide(); switch (this._actorCommandWindow.currentSymbol()) { case "skill": @@ -390,17 +466,23 @@ export class Scene_Battle extends Scene_Base { this._skillWindow.activate(); break; case "item": + this._itemWindow.actor = BattleManager.actor(); this._itemWindow.show(); this._itemWindow.activate(); break; } + BattleManager.stopAllSelection(); + BattleManager.clearInputtingAction(); } public selectEnemySelection() { + if (Yanfly.Param.BECSelectHelp) this._helpWindow.show(); + this._helpWindow.clear(); this._enemyWindow.refresh(); this._enemyWindow.show(); this._enemyWindow.select(0); this._enemyWindow.activate(); + this._enemyWindow.autoSelect(); } public onEnemyOk() { @@ -413,6 +495,8 @@ export class Scene_Battle extends Scene_Base { } public onEnemyCancel() { + if (Yanfly.Param.BECSelectHelp) this._helpWindow.hide(); + this._helpWindow.clear(); this._enemyWindow.hide(); switch (this._actorCommandWindow.currentSymbol()) { case "attack": @@ -423,13 +507,17 @@ export class Scene_Battle extends Scene_Base { this._skillWindow.activate(); break; case "item": + this._itemWindow.actor = BattleManager.actor(); this._itemWindow.show(); this._itemWindow.activate(); break; } + BattleManager.stopAllSelection(); + BattleManager.clearInputtingAction(); } public onSkillOk() { + this._helpWindow.clear(); const skill = this._skillWindow.item(); const action = BattleManager.inputtingAction(); action.setSkill(skill.id); @@ -438,11 +526,13 @@ export class Scene_Battle extends Scene_Base { } public onSkillCancel() { + this._helpWindow.clear(); this._skillWindow.hide(); this._actorCommandWindow.activate(); } public onItemOk() { + this._helpWindow.clear(); const item = this._itemWindow.item(); const action = BattleManager.inputtingAction(); action.setItem(item.id); @@ -451,11 +541,14 @@ export class Scene_Battle extends Scene_Base { } public onItemCancel() { + this._helpWindow.clear(); this._itemWindow.hide(); this._actorCommandWindow.activate(); } public onSelectAction() { + if (Yanfly.Param.BECSelectHelp) BattleManager.forceSelection(); + this._helpWindow.clear(); const action = BattleManager.inputtingAction(); this._skillWindow.hide(); this._itemWindow.hide(); @@ -466,6 +559,7 @@ export class Scene_Battle extends Scene_Base { } else { this.selectActorSelection(); } + if (Yanfly.Param.BECSelectHelp) BattleManager.resetSelection(); } public endCommandSelection() { @@ -473,4 +567,16 @@ export class Scene_Battle extends Scene_Base { this._actorCommandWindow.close(); this._statusWindow.deselect(); } + + public get statusWindow() { + return this._statusWindow; + } + + public get enemyWindow() { + return this._enemyWindow; + } + + public getParallelCommonEvents(): CommonEvent[] { + return $dataCommonEvents.filter(event => event.trigger === 2); + } } diff --git a/ts/scenes/Scene_Boot.ts b/ts/scenes/Scene_Boot.ts index 50ed761..78175da 100644 --- a/ts/scenes/Scene_Boot.ts +++ b/ts/scenes/Scene_Boot.ts @@ -9,6 +9,7 @@ import { Scene_Base } from "./Scene_Base"; import { Scene_Battle } from "./Scene_Battle"; import { Scene_Map } from "./Scene_Map"; import { Scene_Title } from "./Scene_Title"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; export class Scene_Boot extends Scene_Base { public static loadSystemImages() { @@ -53,10 +54,14 @@ export class Scene_Boot extends Scene_Base { public isGameFontLoaded() { if (Graphics.isFontLoaded("GameFont")) { return true; - } else if (!Graphics.canUseCssFontLoading()) { + } else if (Yanfly.Param.GameFontTimer <= 0) { + return false; + } else { const elapsed = Date.now() - this._startDate; - if (elapsed >= 60000) { + if (elapsed >= Yanfly.Param.GameFontTimer) { throw new Error("Failed to load GameFont"); + } else { + return false; } } } diff --git a/ts/scenes/Scene_Gameover.ts b/ts/scenes/Scene_Gameover.ts index 51c3ea6..76e79d5 100644 --- a/ts/scenes/Scene_Gameover.ts +++ b/ts/scenes/Scene_Gameover.ts @@ -6,6 +6,7 @@ import { ImageManager } from "../managers/ImageManager"; import { SceneManager } from "../managers/SceneManager"; import { Scene_Base } from "./Scene_Base"; import { Scene_Title } from "./Scene_Title"; +import { ConfigManager } from "../managers/ConfigManager"; export class Scene_Gameover extends Scene_Base { private _backSprite: Sprite; @@ -59,4 +60,28 @@ export class Scene_Gameover extends Scene_Base { public gotoTitle() { SceneManager.goto(Scene_Title); } + + public rescaleBackground() { + this.rescaleImageSprite(this._backSprite); + } + + public rescaleImageSprite(sprite) { + if (sprite.bitmap.width <= 0 || sprite.bitmap <= 0) { + return setTimeout(this.rescaleImageSprite.bind(this, sprite), 5); + } + const width = ConfigManager.currentResolution.widthPx; + const height = ConfigManager.currentResolution.heightPx; + const ratioX = width / sprite.bitmap.width; + const ratioY = height / sprite.bitmap.height; + if (ratioX > 1.0) sprite.scale.x = ratioX; + if (ratioY > 1.0) sprite.scale.y = ratioY; + this.centerSprite(sprite); + } + + public centerSprite(sprite) { + sprite.x = ConfigManager.currentResolution.widthPx / 2; + sprite.y = ConfigManager.currentResolution.heightPx / 2; + sprite.anchor.x = 0.5; + sprite.anchor.y = 0.5; + } } diff --git a/ts/scenes/Scene_Map.ts b/ts/scenes/Scene_Map.ts index d28c5f9..71cf439 100644 --- a/ts/scenes/Scene_Map.ts +++ b/ts/scenes/Scene_Map.ts @@ -19,6 +19,7 @@ import { Scene_Load } from "./Scene_Load"; import { Scene_Menu } from "./Scene_Menu"; import { Scene_Title } from "./Scene_Title"; import { ConfigManager } from "../managers/ConfigManager"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; export class Scene_Map extends Scene_Base { public menuCalling: boolean; @@ -98,6 +99,7 @@ export class Scene_Map extends Scene_Base { } this.updateWaitCount(); super.update(); + if (!Yanfly._openedConsole) Yanfly.openConsole(); } public updateMainMultiply() { @@ -399,9 +401,13 @@ export class Scene_Map extends Scene_Base { } public snapForBattleBackground() { - this._windowLayer.visible = false; - SceneManager.snapForBackground(); - this._windowLayer.visible = true; + if (!Yanfly.Param.ShowEvSnap) { + this._spriteset.hideCharacters(); + this._windowLayer.visible = false; + SceneManager.snapForBackground(); + this._windowLayer.visible = true; + } + if (Yanfly.Param.ShowEvTrans) this._spriteset.showCharacters(); } public startFlashForEncounter(duration) { diff --git a/ts/sprites/Sprite_Actor.ts b/ts/sprites/Sprite_Actor.ts index 5d0723d..0c890fc 100644 --- a/ts/sprites/Sprite_Actor.ts +++ b/ts/sprites/Sprite_Actor.ts @@ -1,14 +1,16 @@ +import { Bitmap } from "../core/Bitmap"; import { Sprite } from "../core/Sprite"; import { BattleManager } from "../managers/BattleManager"; +import { ConfigManager } from "../managers/ConfigManager"; import { ImageManager } from "../managers/ImageManager"; +import { Game_Actor } from "../objects/Game_Actor"; +import { Game_Enemy } from "../objects/Game_Enemy"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; +import { Window_Base } from "../windows/Window_Base"; import { Sprite_Base } from "./Sprite_Base"; import { Sprite_Battler } from "./Sprite_Battler"; import { Sprite_StateOverlay } from "./Sprite_StateOverlay"; import { Sprite_Weapon } from "./Sprite_Weapon"; -import { ConfigManager } from "../managers/ConfigManager"; -import { Graphics } from "../core/Graphics"; -import { Game_Enemy } from "../objects/Game_Enemy"; -import { Game_Actor } from "../objects/Game_Actor"; interface Motion { index: number; @@ -67,11 +69,12 @@ export class Sprite_Actor extends Sprite_Battler { private _motion: any; private _motionCount: number; private _pattern: number; - private _mainSprite: Sprite_Base; private _shadowSprite: Sprite; private _weaponSprite: Sprite_Weapon; private _stateSprite: Sprite_StateOverlay; private _actor: any; + _checkAliveStatus: boolean; + _hideShadows: any; public constructor(battler?: undefined) { super(battler); @@ -131,11 +134,75 @@ export class Sprite_Actor extends Sprite_Battler { } public moveToStartPosition() { - this.startMove(300, 0, 0); + if (BattleManager.bypassMoveToStartLocation) return; + if ($gameSystem.isSideView() && this._checkAliveStatus) { + this.startMove(300, 0, 0); + } } public setActorHome(index: number) { - this.setHome(800 + index * 32, 280 + index * 48); + const screenWidth = ConfigManager.fieldResolution.widthPx; + const screenHeight = ConfigManager.fieldResolution.heightPx; + const maxSize = $gameParty.maxBattleMembers(); + const partySize = $gameParty.battleMembers().length; + let statusHeight = eval(Yanfly.Param.BECCommandRows); + statusHeight *= Window_Base.prototype.lineHeight.call(this); + statusHeight += Window_Base.prototype.standardPadding.call(this) * 2; + let homeX = 0; + let homeY = 0; + if ($gameSystem.isSideView()) { + let code = Yanfly.Param.BECHomePosX; + try { + homeX = eval(code); + } catch (e) { + Yanfly.Util.displayError( + e, + code, + "SIDE VIEW HOME X FORMULA ERROR" + ); + } + code = Yanfly.Param.BECHomePosY; + try { + homeY = eval(code); + } catch (e) { + homeY = 0; + Yanfly.Util.displayError( + e, + code, + "SIDE VIEW HOME Y FORMULA ERROR" + ); + } + } else { + let code = Yanfly.Param.BECFrontPosX; + try { + homeX = eval(code); + } catch (e) { + homeX = 0; + Yanfly.Util.displayError( + e, + code, + "FRONT VIEW HOME X FORMULA ERROR" + ); + } + code = Yanfly.Param.BECFrontPosY; + try { + homeY = eval(code); + } catch (e) { + homeY = 0; + Yanfly.Util.displayError( + e, + code, + "FRONT VIEW HOME Y FORMULA ERROR" + ); + } + } + this._checkAliveStatus = false; + if ($gameParty.battleMembers()[index]) { + var actor = $gameParty.battleMembers()[index]; + if (actor.isAlive()) this._checkAliveStatus = true; + } + this.setHome(homeX, homeY); + this.moveToStartPosition(); } public update() { @@ -147,6 +214,12 @@ export class Sprite_Actor extends Sprite_Battler { } public updateShadow() { + if (this._hideShadows === undefined) { + this._hideShadows = Yanfly.Param.BECShowShadows; + } + if (!this._hideShadows) { + return (this._shadowSprite.visible = false); + } this._shadowSprite.visible = !!this._actor; } @@ -157,12 +230,7 @@ export class Sprite_Actor extends Sprite_Battler { } } - public setupMotion() { - if (this._actor.isMotionRequested()) { - this.startMotion(this._actor.motionType()); - this._actor.clearMotion(); - } - } + public setupMotion() {} public setupWeaponAnimation() { if (this._actor.isWeaponAnimationRequested()) { @@ -180,23 +248,16 @@ export class Sprite_Actor extends Sprite_Battler { } } - public updateTargetPosition() { - if (this._actor.isInputting() || this._actor.isActing()) { - this.stepForward(); - } else if (this._actor.canMove() && BattleManager.isEscaped()) { - this.retreat(); - } else if (!this.inHomePosition()) { - this.stepBack(); - } - } - public updateBitmap() { + let name = this._actor.battlerName(); + let needUpdate = false; + if (this._battlerName !== name) needUpdate = true; super.updateBitmap(); - const name = this._actor.battlerName(); if (this._battlerName !== name) { this._battlerName = name; this._mainSprite.bitmap = ImageManager.loadSvActor(name); } + if (needUpdate) this.adjustAnchor(); } public updateFrame() { @@ -211,6 +272,14 @@ export class Sprite_Actor extends Sprite_Battler { const cy = motionIndex % 6; this._mainSprite.setFrame(cx * cw, cy * ch, cw, ch); } + + if (!this._mainSprite) return; + if (!this._mainSprite.bitmap) return; + if (this._mainSprite.bitmap.width > 0 && !this.bitmap) { + var sw = this._mainSprite.bitmap.width / 9; + var sh = this._mainSprite.bitmap.height / 6; + this.bitmap = new Bitmap(sw, sh); + } } public updateMove() { @@ -220,16 +289,6 @@ export class Sprite_Actor extends Sprite_Battler { } } - public updateMotion() { - this.setupMotion(); - this.setupWeaponAnimation(); - if (this._actor.isMotionRefreshRequested()) { - this.refreshMotion(); - this._actor.clearMotion(); - } - this.updateMotionCount(); - } - public updateMotionCount() { if (this._motion && ++this._motionCount >= this.motionSpeed()) { if (this._motion.loop) { @@ -249,31 +308,29 @@ export class Sprite_Actor extends Sprite_Battler { public refreshMotion() { const actor = this._actor; + if (!actor) return; const motionGuard = Sprite_Actor.MOTIONS["guard"]; - if (actor) { - if (this._motion === motionGuard && !BattleManager.isInputting()) { - return; - } - const stateMotion = actor.stateMotionIndex(); - if (actor.isInputting() || actor.isActing()) { - this.startMotion("walk"); - } else if (stateMotion === 3) { - this.startMotion("dead"); - } else if (stateMotion === 2) { - this.startMotion("sleep"); - } else if (actor.isChanting()) { - this.startMotion("chant"); - } else if (actor.isGuard() || actor.isGuardWaiting()) { - this.startMotion("guard"); - } else if (stateMotion === 1) { - this.startMotion("abnormal"); - } else if (actor.isDying()) { - this.startMotion("dying"); - } else if (actor.isUndecided()) { - this.startMotion("walk"); - } else { - this.startMotion("wait"); - } + if (this._motion === motionGuard && !BattleManager.isInputting()) + return; + const stateMotion = actor.stateMotionIndex(); + if (actor.isInputting() || actor.isActing()) { + this.startMotion(actor.idleMotion()); + } else if (stateMotion === 3) { + this.startMotion(actor.deadMotion()); + } else if (stateMotion === 2) { + this.startMotion(actor.sleepMotion()); + } else if (actor.isChanting()) { + this.startMotion(actor.chantMotion()); + } else if (actor.isGuard() || actor.isGuardWaiting()) { + this.startMotion(actor.guardMotion()); + } else if (stateMotion === 1) { + this.startMotion(actor.abnormalMotion()); + } else if (actor.isDying()) { + this.startMotion(actor.dyingMotion()); + } else if (actor.isUndecided()) { + this.startMotion(actor.idleMotion()); + } else { + this.startMotion(actor.waitMotion()); } } @@ -287,23 +344,12 @@ export class Sprite_Actor extends Sprite_Battler { } } - public stepForward() { - this.startMove(-48, 0, 12); - } - public stepBack() { this.startMove(0, 0, 12); } public retreat() { - this.startMove(300, 0, 30); - } - - public onMoveEnd() { - super.onMoveEnd(); - if (!BattleManager.isBattleEnd()) { - this.refreshMotion(); - } + this.startMove(1200, 0, 120); } public damageOffsetX() { @@ -313,4 +359,44 @@ export class Sprite_Actor extends Sprite_Battler { public damageOffsetY() { return 0; } + + public forceMotion(motionType) { + const newMotion = Sprite_Actor.MOTIONS[motionType]; + this._motion = newMotion; + this._motionCount = 0; + this._pattern = 0; + } + + public updateTargetPosition() {} + + public updateMotion() { + this.updateMotionCount(); + } + + public onMoveEnd() { + Sprite_Battler.prototype.onMoveEnd.call(this); + } + + public stepForward() { + this.startMove(-Yanfly.Param.BECStepDist, 0, 12); + } + + public stepFlinch() { + var flinchX = this.x - this._homeX + Yanfly.Param.BECFlinchDist; + var flinchY = this.y - this._homeY; + this.startMove(flinchX, flinchY, 6); + } + + public stepSubBack() { + var backX = this._mainSprite.width / 2; + this.startMove(backX, 0, 6); + } + + public adjustAnchor() { + if (!this._mainSprite) { + return; + } + this._mainSprite.anchor.x = this._actor.anchorX(); + this._mainSprite.anchor.y = this._actor.anchorY(); + } } diff --git a/ts/sprites/Sprite_Animation.ts b/ts/sprites/Sprite_Animation.ts index 5a7f2c3..a547b5b 100644 --- a/ts/sprites/Sprite_Animation.ts +++ b/ts/sprites/Sprite_Animation.ts @@ -3,6 +3,7 @@ import { Sprite } from "../core/Sprite"; import { Utils } from "../core/Utils"; import { AudioManager } from "../managers/AudioManager"; import { ImageManager } from "../managers/ImageManager"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; // ----------------------------------------------------------------------------- // Sprite_Animation @@ -77,7 +78,7 @@ export class Sprite_Animation extends Sprite { } public setupRate() { - this._rate = 4; + this._rate = Yanfly.Param.AnimationRate; } public setupDuration() { diff --git a/ts/sprites/Sprite_Battleback.ts b/ts/sprites/Sprite_Battleback.ts new file mode 100644 index 0000000..f5f4e1d --- /dev/null +++ b/ts/sprites/Sprite_Battleback.ts @@ -0,0 +1,57 @@ +import { Sprite } from "../core/Sprite"; +import { Bitmap } from "../core/Bitmap"; +import { ImageManager } from "../managers/ImageManager"; +import { ConfigManager } from "../managers/ConfigManager"; + +/** + * YEP class imported from YEP_CoreEngine + */ +export class Sprite_Battleback extends Sprite { + private _bitmapName: string; + private _battlebackType: number; + + public constructor(bitmapName: string, type: number) { + super(); + this._bitmapName = bitmapName; + this._battlebackType = type; + this.createBitmap(); + } + + public createBitmap() { + if (this._bitmapName === "") { + this.bitmap = new Bitmap( + ConfigManager.currentResolution.widthPx, + ConfigManager.currentResolution.heightPx + ); + } else { + if (this._battlebackType === 1) { + this.bitmap = ImageManager.loadBattleback1(this._bitmapName); + } else { + this.bitmap = ImageManager.loadBattleback2(this._bitmapName); + } + this.scaleSprite(); + } + } + + public scaleSprite() { + if (this.bitmap.width <= 0) + return setTimeout(this.scaleSprite.bind(this), 5); + const width = ConfigManager.currentResolution.widthPx; + const height = ConfigManager.currentResolution.heightPx; + if (this.bitmap.width < width) { + this.scale.x = width / this.bitmap.width; + } + if (this.bitmap.height < height) { + this.scale.y = height / this.bitmap.height; + } + this.anchor.x = 0.5; + this.x = width / 2; + if ($gameSystem.isSideView()) { + this.anchor.y = 1; + this.y = height; + } else { + this.anchor.y = 0.5; + this.y = height / 2; + } + } +} diff --git a/ts/sprites/Sprite_Battler.ts b/ts/sprites/Sprite_Battler.ts index 8a3e647..143daad 100644 --- a/ts/sprites/Sprite_Battler.ts +++ b/ts/sprites/Sprite_Battler.ts @@ -1,7 +1,9 @@ +import { ScreenSprite } from "../core/ScreenSprite"; +import { BattleManager } from "../managers/BattleManager"; +import { Game_Battler } from "../objects/Game_Battler"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; import { Sprite_Base } from "./Sprite_Base"; import { Sprite_Damage } from "./Sprite_Damage"; -import { Game_Battler } from "../objects/Game_Battler"; -import { ConfigManager } from "../managers/ConfigManager"; // ----------------------------------------------------------------------------- // Sprite_Battler @@ -9,7 +11,16 @@ import { ConfigManager } from "../managers/ConfigManager"; // The superclass of Sprite_Actor and Sprite_Enemy. export class Sprite_Battler extends Sprite_Base { - protected _battler: Game_Battler; + private _battler: Game_Battler; + + public get battler(): Game_Battler { + return this._battler; + } + + public set battler(value: Game_Battler) { + this._battler = value; + } + private _damages: Sprite_Damage[]; protected _homeX: number; protected _homeY: number; @@ -19,13 +30,37 @@ export class Sprite_Battler extends Sprite_Base { private _targetOffsetY: number; private _movementDuration: number; private _selectionEffectCount: number; + private _postSpriteInitialized: boolean; + protected _mainSprite: Sprite_Base; - public constructor(battler?) { + public constructor(battler?: Game_Battler) { super(); + this.preSpriteInitialize(battler); this.initMembers(); this.setBattler(battler); } + public get mainSprite(): Sprite_Base { + if (!this._mainSprite) { + throw new Error("This battler has no main sprite!"); + } + return this._mainSprite; + } + + public get homeX(): number { + return this._homeX; + } + + public get homeY(): number { + return this._homeY; + } + + public preSpriteInitialize(battler) {} + + public postSpriteInitialize() { + this._postSpriteInitialized = true; + } + public initMembers() { this.anchor.x = 0.5; this.anchor.y = 1; @@ -39,10 +74,13 @@ export class Sprite_Battler extends Sprite_Base { this._targetOffsetY = NaN; this._movementDuration = 0; this._selectionEffectCount = 0; + this.adjustAnchor(); + this.setZ(); } - public setBattler(battler) { + public setBattler(battler: Game_Battler) { this._battler = battler; + if (battler) battler.setBattler(this); } public setHome(x, y) { @@ -61,6 +99,8 @@ export class Sprite_Battler extends Sprite_Base { } else { this.bitmap = null; } + if (this._postSpriteInitialized) return; + this.postSpriteInitialize(); } public updateVisibility() { @@ -146,21 +186,6 @@ export class Sprite_Battler extends Sprite_Base { } } - public setupDamagePopup() { - if (this._battler.isDamagePopupRequested()) { - if (this._battler.isSpriteVisible()) { - const sprite = new Sprite_Damage(); - sprite.x = this.x + this.damageOffsetX(); - sprite.y = this.y + this.damageOffsetY(); - sprite.setup(this._battler); - this._damages.push(sprite); - this.parent.addChild(sprite); - } - this._battler.clearDamagePopup(); - this._battler.clearResult(); - } - } - public damageOffsetX() { return 0; } @@ -170,6 +195,7 @@ export class Sprite_Battler extends Sprite_Base { } public startMove(x, y, duration) { + if (this._battler && !this._battler.spriteCanMove()) return; if (this._targetOffsetX !== x || this._targetOffsetY !== y) { this._targetOffsetX = x; this._targetOffsetY = y; @@ -194,4 +220,116 @@ export class Sprite_Battler extends Sprite_Base { public inHomePosition() { return this._offsetX === 0 && this._offsetY === 0; } + + public adjustAnchor() { + this.anchor.x = 0.5; + this.anchor.y = 1.0; + } + + public setZ() { + this.z = 1; + } + + public setupDamagePopup() { + if (this._battler.isDamagePopupRequested()) { + if (this._battler.isSpriteVisible()) { + let sprite = new Sprite_Damage(); + sprite.x = this.x + this.damageOffsetX(); + sprite.y = this.y + this.damageOffsetY(); + sprite.setup(this._battler); + this.pushDamageSprite(sprite); + BattleManager.spriteset.addChild(sprite); + this._battler.clearResult(); + } + } else { + this._battler.clearDamagePopup(); + } + } + + public pushDamageSprite(sprite) { + let heightBuffer = Yanfly.Param.BECPopupOverlap; + if (Yanfly.Param.BECNewPopBottom) { + this._damages.push(sprite); + this._damages.forEach(function(spr) { + for (let i = 0; i < spr.children.length; i++) { + let childSprite = spr.children[i] as ScreenSprite; + childSprite.anchor.y += heightBuffer; + } + }, this); + } else { + this._damages.push(sprite); + heightBuffer *= this._damages.length; + for (let i = 0; i < sprite.children.length; i++) { + let childSprite = sprite.children[i]; + childSprite.anchor.y += heightBuffer; + } + } + } + + public stepForward() { + this.startMove(Yanfly.Param.BECStepDist, 0, 12); + } + + public stepBack() { + this.startMove(0, 0, 12); + } + + public stepFlinch() { + let flinchX = this.x - this._homeX - Yanfly.Param.BECFlinchDist; + let flinchY = this.y - this._homeY; + this.startMove(flinchX, flinchY, 6); + } + + public stepSubBack() { + let backX = (-1 * this.width) / 2; + this.startMove(backX, 0, 6); + } + + public stepToSubstitute(focus) { + let target = focus.battler(); + let targetX = this.x - this._homeX + (target._homeX - this._homeX); + let targetY = this.y - this._homeY + (target._homeY - this._homeY); + if (focus.isActor()) targetX -= this._mainSprite.width / 2; + if (focus.isEnemy()) targetX += this.width / 2; + this.startMove(targetX, targetY, 1); + } + + public startMotion(motionType) {} + + public forceMotion(motionType) {} + + public refreshMotion() {} + + public startActionMotion() {} + + public moveForward(distance, frames) { + distance = parseInt(distance); + frames = parseInt(frames); + if (this._battler.isActor()) distance *= -1; + let moveX = this.x - this._homeX + distance; + let moveY = this.y - this._homeY; + this.startMove(moveX, moveY, frames); + } + + public moveToPoint(pointX, pointY, frames) { + pointX = parseInt(pointX); + pointY = parseInt(pointY); + let targetX = pointX - this._homeX; + let targetY = pointY - this._homeY; + this.startMove(targetX, targetY, frames); + } + + public setMirror(value) { + if (this.scale.x > 0 && value) this.scale.x *= -1; + if (this.scale.x < 0 && !value) this.scale.x *= -1; + } + + public isPopupPlaying() { + if (this._damages.length > 0) { + for (let i = 0; i < this._damages.length; ++i) { + return this._damages[i].isPlaying(); + } + } + return false; + } } diff --git a/ts/sprites/Sprite_Damage.ts b/ts/sprites/Sprite_Damage.ts index cac7ea0..1dfd975 100644 --- a/ts/sprites/Sprite_Damage.ts +++ b/ts/sprites/Sprite_Damage.ts @@ -1,5 +1,6 @@ import { Sprite } from "../core/Sprite"; import { ImageManager } from "../managers/ImageManager"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; // ----------------------------------------------------------------------------- // Sprite_Damage @@ -11,6 +12,7 @@ export class Sprite_Damage extends Sprite { private _flashColor: number[]; private _flashDuration: number; private _damageBitmap: any; + private _result: any; public constructor() { super(); @@ -18,10 +20,12 @@ export class Sprite_Damage extends Sprite { this._flashColor = [0, 0, 0, 0]; this._flashDuration = 0; this._damageBitmap = ImageManager.loadSystem("Damage"); + this._duration = Yanfly.Param.BECPopupDur; } public setup(target) { - const result = target.result(); + this._result = target.shiftDamagePopup(); + const result = this._result; if (result.missed || result.evaded) { this.createMiss(); } else if (result.hpAffected) { @@ -35,8 +39,8 @@ export class Sprite_Damage extends Sprite { } public setupCriticalEffect() { - this._flashColor = [255, 0, 0, 160]; - this._flashDuration = 60; + this._flashColor = eval("[" + Yanfly.Param.BECCritPopup + "]"); + this._flashDuration = Yanfly.Param.BECCritDur; } public digitWidth() { @@ -90,6 +94,9 @@ export class Sprite_Damage extends Sprite { } this.updateFlash(); this.updateOpacity(); + if (this._duration <= 0 && this.parent) { + this.parent.removeChild(this); + } } public updateChild(sprite) { diff --git a/ts/sprites/Sprite_Enemy.ts b/ts/sprites/Sprite_Enemy.ts index 4fa74ab..8f1c573 100644 --- a/ts/sprites/Sprite_Enemy.ts +++ b/ts/sprites/Sprite_Enemy.ts @@ -6,6 +6,8 @@ import { Sprite_StateIcon } from "./Sprite_StateIcon"; import { ConfigManager } from "../managers/ConfigManager"; import { Game_Enemy } from "../objects/Game_Enemy"; import { Game_Battler } from "../objects/Game_Battler"; +import { SceneManager } from "../managers/SceneManager"; +import { Window_EnemyVisualSelect } from "../windows/Window_EnemyVisualSelect"; // ----------------------------------------------------------------------------- // Sprite_Enemy @@ -21,6 +23,9 @@ export class Sprite_Enemy extends Sprite_Battler { private _effectDuration: number; private _shake: number; private _stateIconSprite: Sprite_StateIcon; + _visualSelect: any; + _visualSelectWindow: any; + _addedVisualSelect: any; public initMembers() { super.initMembers(); @@ -34,6 +39,10 @@ export class Sprite_Enemy extends Sprite_Battler { this.createStateIconSprite(); } + public preSpriteInitialize(battler: Game_Battler) { + if (this._visualSelect) this.createVisualSelectWindow(); + } + public createStateIconSprite() { this._stateIconSprite = new Sprite_StateIcon(); this.addChild(this._stateIconSprite); @@ -54,6 +63,8 @@ export class Sprite_Enemy extends Sprite_Battler { ); this._stateIconSprite.setup(battler); + if (this._visualSelectWindow) + this._visualSelectWindow.setBattler(battler); } public update() { @@ -62,6 +73,8 @@ export class Sprite_Enemy extends Sprite_Battler { this.updateEffect(); this.updateStateSprite(); } + this.addVisualSelectWindow(); + this.checkExistInSceneChildren(); } public updateBitmap() { @@ -275,12 +288,33 @@ export class Sprite_Enemy extends Sprite_Battler { } public updateSelectionEffect() { - if (this._battler.isActor()) { - super.updateSelectionEffect(); - } else { - if (this._battler.isSelected()) { - this.startEffect("whiten"); - } + if (this.battler.isSelected()) { + this.startEffect("whiten"); + } + } + + public addVisualSelectWindow() { + if (!this._visualSelect) return; + if (this._addedVisualSelect) return; + if (!SceneManager.scene) return; + let scene = SceneManager.scene; + if (!scene._windowLayer) return; + this._addedVisualSelect = true; + scene.addChild(this._visualSelectWindow); + } + + public createVisualSelectWindow() { + this._visualSelectWindow = new Window_EnemyVisualSelect(); + } + + public checkExistInSceneChildren() { + if (!this._visualSelect) return; + if (!SceneManager.scene) return; + let scene = SceneManager.scene; + if (!scene._windowLayer) return; + if (!scene.children.includes(this._visualSelectWindow)) { + this._addedVisualSelect = true; + scene.addChild(this._visualSelectWindow); } } } diff --git a/ts/sprites/Sprite_StateIcon.ts b/ts/sprites/Sprite_StateIcon.ts index 8b214be..71531bd 100644 --- a/ts/sprites/Sprite_StateIcon.ts +++ b/ts/sprites/Sprite_StateIcon.ts @@ -5,7 +5,6 @@ import { ImageManager } from "../managers/ImageManager"; // Sprite_StateIcon // // The sprite for displaying state icons. - export class Sprite_StateIcon extends Sprite { private static _iconWidth = 32; private static _iconHeight = 32; @@ -47,6 +46,12 @@ export class Sprite_StateIcon extends Sprite { this.updateFrame(); this._animationCount = 0; } + this.updateMirror(); + } + + public updateMirror() { + if (this.parent.scale.x < 0) this.scale.x = -1 * Math.abs(this.scale.x); + if (this.parent.scale.x > 0) this.scale.x = Math.abs(this.scale.x); } public animationWait() { diff --git a/ts/sprites/Sprite_StateOverlay.ts b/ts/sprites/Sprite_StateOverlay.ts index 1de6b39..93d48a0 100644 --- a/ts/sprites/Sprite_StateOverlay.ts +++ b/ts/sprites/Sprite_StateOverlay.ts @@ -44,6 +44,12 @@ export class Sprite_StateOverlay extends Sprite_Base { this.updateFrame(); this._animationCount = 0; } + this.updateMirror(); + } + + public updateMirror() { + if (this.parent.scale.x < 0) this.scale.x = -1 * Math.abs(this.scale.x); + if (this.parent.scale.x > 0) this.scale.x = Math.abs(this.scale.x); } public animationWait() { diff --git a/ts/sprites/Sprite_Weapon.ts b/ts/sprites/Sprite_Weapon.ts index 906b205..2181d2e 100644 --- a/ts/sprites/Sprite_Weapon.ts +++ b/ts/sprites/Sprite_Weapon.ts @@ -31,6 +31,7 @@ export class Sprite_Weapon extends Sprite_Base { this._pattern = 0; this.loadBitmap(); this.updateFrame(); + this._animationCount -= 1; // Synch with sprite } public update() { diff --git a/ts/sprites/Spriteset_Base.ts b/ts/sprites/Spriteset_Base.ts index eab97ae..cf21d82 100644 --- a/ts/sprites/Spriteset_Base.ts +++ b/ts/sprites/Spriteset_Base.ts @@ -5,9 +5,9 @@ import { Sprite } from "../core/Sprite"; import { ToneFilter } from "../core/ToneFilter"; import { ToneSprite } from "../core/ToneSprite"; import { Utils } from "../core/Utils"; +import { ConfigManager } from "../managers/ConfigManager"; import { Sprite_Picture } from "./Sprite_Picture"; import { Sprite_Timer } from "./Sprite_Timer"; -import { ConfigManager } from "../managers/ConfigManager"; // ----------------------------------------------------------------------------- // Spriteset_Base @@ -102,10 +102,9 @@ export abstract class Spriteset_Base extends Sprite { public createPictures() { const width = Graphics.boxWidth; const height = Graphics.boxHeight; - const x = (ConfigManager.fieldResolution.widthPx - width) / 2; - const y = (ConfigManager.fieldResolution.heightPx - height) / 2; + const offset = ConfigManager.xOffset; this._pictureContainer = new Sprite(); - this._pictureContainer.setFrame(x, y, width, height); + this._pictureContainer.setFrame(0 + offset, 0, width, height); for (let i = 1; i <= $gameScreen.maxPictures(); i++) { this._pictureContainer.addChild(new Sprite_Picture(i)); } diff --git a/ts/sprites/Spriteset_Battle.ts b/ts/sprites/Spriteset_Battle.ts index 44a866e..f791284 100644 --- a/ts/sprites/Spriteset_Battle.ts +++ b/ts/sprites/Spriteset_Battle.ts @@ -1,14 +1,13 @@ -import { Graphics } from "../core/Graphics"; import { Sprite } from "../core/Sprite"; import { TilingSprite } from "../core/TilingSprite"; import { BattleManager } from "../managers/BattleManager"; +import { ConfigManager } from "../managers/ConfigManager"; import { ImageManager } from "../managers/ImageManager"; import { SceneManager } from "../managers/SceneManager"; import { Spriteset_Base } from "./Spriteset_Base"; import { Sprite_Actor } from "./Sprite_Actor"; -import { Sprite_Enemy } from "./Sprite_Enemy"; import { Sprite_Battler } from "./Sprite_Battler"; -import { ConfigManager } from "../managers/ConfigManager"; +import { Sprite_Enemy } from "./Sprite_Enemy"; // ----------------------------------------------------------------------------- // Spriteset_Battle @@ -53,6 +52,47 @@ export class Spriteset_Battle extends Spriteset_Base { super.update(); this._loadingDone ? this.updateActors() : null; this.updateBattleback(); + this.updateZCoordinates(); + } + + public updateZCoordinates() { + // if (Imported.YEP_ImprovedBattlebacks) { + // this.updateBattlebackGroupRemove(); + // } else { + this._battleField.removeChild(this._back1Sprite); + this._battleField.removeChild(this._back2Sprite); + // } + this._battleField.children.sort(this.battleFieldDepthCompare); + // if (Imported.YEP_ImprovedBattlebacks) { + // this.updateBattlebackGroupAdd(); + // } else { + this._battleField.addChildAt(this._back2Sprite, 0); + this._battleField.addChildAt(this._back1Sprite, 0); + // } + } + + public battleFieldDepthCompare(a, b) { + let priority = BattleManager.getSpritePriority(); + if (a._battler && b._battler && priority !== 0) { + if (priority === 1) { + if (a._battler.isActor() && b._battler.isEnemy()) return 1; + if (a._battler.isEnemy() && b._battler.isActor()) return -1; + } else if (priority === 2) { + if (a._battler.isActor() && b._battler.isEnemy()) return -1; + if (a._battler.isEnemy() && b._battler.isActor()) return 1; + } + } + if (a.z < b.z) return -1; + if (a.z > b.z) return 1; + if (a.y < b.y) return -1; + if (a.y > b.y) return 1; + return 0; + } + + public isPopupPlaying() { + return this.battlerSprites().some(function(sprite) { + return sprite.isPopupPlaying(); + }); } public createBattleField() { @@ -350,7 +390,19 @@ export class Spriteset_Battle extends Spriteset_Base { } public battlerSprites(): Sprite_Battler[] { - return [...this._enemySprites, ...this._actorSprites]; + const sprites = [ + ...this._enemySprites, + ...this._actorSprites + ] as Sprite_Battler[]; + const length = sprites.length; + const result: Sprite_Battler[] = []; + for (let i = 0; i < length; ++i) { + const sprite = sprites[i]; + if (!sprite) continue; + if (!sprite.battler) continue; + result.push(sprite); + } + return result; } public isAnimationPlaying() { @@ -372,6 +424,6 @@ export class Spriteset_Battle extends Spriteset_Base { } public isBusy() { - return this.isAnimationPlaying() || this.isAnyoneMoving(); + return false; } } diff --git a/ts/sprites/Spriteset_Map.ts b/ts/sprites/Spriteset_Map.ts index 9676f3a..c8cbc04 100644 --- a/ts/sprites/Spriteset_Map.ts +++ b/ts/sprites/Spriteset_Map.ts @@ -4,11 +4,11 @@ import { Tilemap } from "../core/Tilemap"; import { TilingSprite } from "../core/TilingSprite"; import { Utils } from "../core/Utils"; import { Weather } from "../core/Weather"; +import { ConfigManager } from "../managers/ConfigManager"; import { ImageManager } from "../managers/ImageManager"; import { Spriteset_Base } from "./Spriteset_Base"; import { Sprite_Character } from "./Sprite_Character"; import { Sprite_Destination } from "./Sprite_Destination"; -import { ConfigManager } from "../managers/ConfigManager"; // ----------------------------------------------------------------------------- // Spriteset_Map @@ -101,10 +101,12 @@ export class Spriteset_Map extends Spriteset_Base { this._tilemap.bitmaps.push(bitmap); } const newTilesetFlags = $gameMap.tilesetFlags(); - this._tilemap.refreshTileset(); - if (!Utils.arrayEquals(this._tilemap.flags, newTilesetFlags)) { - this._tilemap.refresh(); - } + Promise.all(this.bitmapPromises).then(() => { + this._tilemap.refreshTileset(); + if (!Utils.arrayEquals(this._tilemap.flags, newTilesetFlags)) { + this._tilemap.refresh(); + } + }); this._tilemap.flags = newTilesetFlags; } } diff --git a/ts/windows/Window_ActorCommand.ts b/ts/windows/Window_ActorCommand.ts index 6ac1051..df738cc 100644 --- a/ts/windows/Window_ActorCommand.ts +++ b/ts/windows/Window_ActorCommand.ts @@ -5,6 +5,7 @@ import { TextManager } from "../managers/TextManager"; import { Game_Actor } from "../objects/Game_Actor"; import { Window_Command } from "./Window_Command"; import { Skill } from "../interfaces/Skill"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; // ----------------------------------------------------------------------------- // Window_ActorCommand @@ -30,7 +31,11 @@ export class Window_ActorCommand extends Window_Command { } public numVisibleRows() { - return 4; + return Yanfly.Param.BECCommandRows; + } + + public itemTextAlign() { + return Yanfly.Param.BECCommandAlign; } public makeCommandList() { @@ -48,10 +53,10 @@ export class Window_ActorCommand extends Window_Command { public addSkillCommands() { const skillTypes = this._actor.addedSkillTypes(); - skillTypes.sort(function(a: number, b: number) { + skillTypes.sort(function(a, b) { return a - b; }); - skillTypes.forEach(function(stypeId: string | number) { + skillTypes.forEach(function(stypeId) { const name = $dataSystem.skillTypes[stypeId]; this.addCommand(name, "skill", true, stypeId); }, this); diff --git a/ts/windows/Window_Base.ts b/ts/windows/Window_Base.ts index f5301c9..cba5790 100644 --- a/ts/windows/Window_Base.ts +++ b/ts/windows/Window_Base.ts @@ -1,11 +1,13 @@ import { Bitmap } from "../core/Bitmap"; import { Sprite } from "../core/Sprite"; +import { Utils } from "../core/Utils"; import { Window } from "../core/Window"; import { Item } from "../interfaces/Item"; +import { ConfigManager } from "../managers/ConfigManager"; import { ImageManager } from "../managers/ImageManager"; import { TextManager } from "../managers/TextManager"; import { Game_Actor } from "../objects/Game_Actor"; -import { ConfigManager } from "../managers/ConfigManager"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; interface ListItem { name: string; @@ -15,10 +17,10 @@ interface ListItem { } export class Window_Base extends Window { - public static _iconWidth: number = 32; - public static _iconHeight: number = 32; - public static _faceWidth: number = 144; - public static _faceHeight: number = 144; + public static _iconWidth: number = Yanfly.Param.IconWidth; + public static _iconHeight: number = Yanfly.Param.IconHeight; + public static _faceWidth: number = Yanfly.Param.FaceWidth; + public static _faceHeight: number = Yanfly.Param.FaceHeight; public windowskin: Bitmap; public padding: number; public backOpacity: number; @@ -30,7 +32,7 @@ export class Window_Base extends Window { private _closing: boolean; private _dimmerSprite: Sprite; - public constructor(x, y, width, height) { + public constructor(x: number, y: number, width: number, height: number) { super(); this._list = []; this.loadWindowskin(); @@ -55,33 +57,33 @@ export class Window_Base extends Window { } public lineHeight() { - return 36; + return Yanfly.Param.LineHeight; } public standardFontFace() { if ($gameSystem.isChinese()) { - return "SimHei, Heiti TC, sans-serif"; + return Yanfly.Param.ChineseFont; } else if ($gameSystem.isKorean()) { - return "Dotum, AppleGothic, sans-serif"; + return Yanfly.Param.KoreanFont; } else { - return "GameFont"; + return Yanfly.Param.DefaultFont; } } public standardFontSize() { - return 28; + return Yanfly.Param.FontSize; } public standardPadding() { - return 18; + return Yanfly.Param.WindowPadding; } public textPadding() { - return 6; + return Yanfly.Param.TextPadding; } public standardBackOpacity() { - return 192; + return Yanfly.Param.WindowOpacity; } public loadWindowskin() { @@ -90,7 +92,7 @@ export class Window_Base extends Window { if (files.length > 0) { const maxValue = files.length; let value = this.getGameSettingsMoe("_windowskin"); - if (Number.isInteger(value) == false) { + if (Number.isInteger(value) === false) { value = 0; ConfigManager["_windowskin"] = 0; } @@ -123,7 +125,7 @@ export class Window_Base extends Window { return this._height - this.standardPadding() * 2; } - public fittingHeight(numLines) { + public fittingHeight(numLines: number) { return numLines * this.lineHeight() + this.standardPadding() * 2; } @@ -211,70 +213,70 @@ export class Window_Base extends Window { this.active = false; } - public textColor(n) { + public textColor(n: number) { const px = 96 + (n % 8) * 12 + 6; const py = 144 + Math.floor(n / 8) * 12 + 6; return this.windowskin.getPixel(px, py); } public normalColor() { - return this.textColor(0); + return this.textColor(Yanfly.Param.ColorNormal); } public systemColor() { - return this.textColor(16); + return this.textColor(Yanfly.Param.ColorSystem); } public crisisColor() { - return this.textColor(17); + return this.textColor(Yanfly.Param.ColorCrisis); } public deathColor() { - return this.textColor(18); + return this.textColor(Yanfly.Param.ColorDeath); } public gaugeBackColor() { - return this.textColor(19); + return this.textColor(Yanfly.Param.ColorGaugeBack); } public hpGaugeColor1() { - return this.textColor(20); + return this.textColor(Yanfly.Param.ColorHpGauge1); } public hpGaugeColor2() { - return this.textColor(21); + return this.textColor(Yanfly.Param.ColorHpGauge2); } public mpGaugeColor1() { - return this.textColor(22); + return this.textColor(Yanfly.Param.ColorMpGauge1); } public mpGaugeColor2() { - return this.textColor(23); + return this.textColor(Yanfly.Param.ColorMpGauge2); } public mpCostColor() { - return this.textColor(23); + return this.textColor(Yanfly.Param.ColorMpCost); } public powerUpColor() { - return this.textColor(24); + return this.textColor(Yanfly.Param.ColorPowerUp); } public powerDownColor() { - return this.textColor(25); + return this.textColor(Yanfly.Param.ColorPowerDown); } public tpGaugeColor1() { - return this.textColor(28); + return this.textColor(Yanfly.Param.ColorTpGauge1); } public tpGaugeColor2() { - return this.textColor(29); + return this.textColor(Yanfly.Param.ColorTpGauge1); } public tpCostColor() { - return this.textColor(29); + return this.textColor(Yanfly.Param.ColorTpCost); } public pendingColor() { @@ -285,11 +287,11 @@ export class Window_Base extends Window { return 160; } - public changeTextColor(color) { + public changeTextColor(color: string) { this.contents.textColor = color; } - public changePaintOpacity(enabled) { + public changePaintOpacity(enabled: number | boolean) { this.contents.paintOpacity = enabled ? 255 : this.translucentOpacity(); } @@ -311,7 +313,7 @@ export class Window_Base extends Window { ); } - public textWidth(text) { + public textWidth(text: string) { return this.contents.measureTextWidth(text); } @@ -323,10 +325,9 @@ export class Window_Base extends Window { x: x, y: y, left: x, - text: null, + text: this.convertEscapeCharacters(text), height: null }; - textState.text = this.convertEscapeCharacters(text); textState.height = this.calcTextHeight(textState, false); this.resetFontSettings(); while (textState.index < textState.text.length) { @@ -346,7 +347,7 @@ export class Window_Base extends Window { ); } - public convertEscapeCharacters(text) { + public convertEscapeCharacters(text: string) { text = text.replace(/\\/g, "\x1b"); text = text.replace(/\x1b\x1b/g, "\\"); text = text.replace(/\x1bV\[(\d+)\]/gi, function() { @@ -371,17 +372,17 @@ export class Window_Base extends Window { return text; } - public actorName(n) { + public actorName(n: number) { const actor = n >= 1 ? $gameActors.actor(n) : null; return actor ? actor.name() : ""; } - public partyMemberName(n) { + public partyMemberName(n: number) { const actor = n >= 1 ? $gameParty.members()[n - 1] : null; return actor ? actor.name() : ""; } - public processCharacter(textState) { + public processCharacter(textState: any) { switch (textState.text[textState.index]) { case "\n": this.processNewLine(textState); @@ -401,7 +402,13 @@ export class Window_Base extends Window { } } - public processNormalCharacter(textState) { + public processNormalCharacter(textState: { + text: any[]; + index: number; + x: number; + y: number; + height: number; + }) { const c = textState.text[textState.index++]; const w = this.textWidth(c); this.contents.drawText( @@ -414,18 +421,21 @@ export class Window_Base extends Window { textState.x += w; } - public processNewLine(textState) { + public processNewLine(textState: any) { textState.x = textState.left; textState.y += textState.height; textState.height = this.calcTextHeight(textState, false); textState.index++; } - public processNewPage(textState) { + public processNewPage(textState: { index: number }) { textState.index++; } - public obtainEscapeCode(textState) { + public obtainEscapeCode(textState: { + index: number; + text: { slice: (arg0: any) => string }; + }) { textState.index++; const regExp = /^[.|^!><{}\\]|^[A-Z]+/i; const arr = regExp.exec(textState.text.slice(textState.index)); @@ -437,7 +447,10 @@ export class Window_Base extends Window { } } - public obtainEscapeParam(textState) { + public obtainEscapeParam(textState: { + text: { slice: (arg0: any) => string }; + index: number; + }) { const arr = /^\[\d+\]/.exec(textState.text.slice(textState.index)); if (arr) { textState.index += arr[0].length; @@ -447,7 +460,7 @@ export class Window_Base extends Window { } } - public processEscapeCharacter(code, textState) { + public processEscapeCharacter(code: string, textState: any) { switch (code) { case "C": this.changeTextColor( @@ -469,7 +482,10 @@ export class Window_Base extends Window { } } - public processDrawIcon(iconIndex, textState) { + public processDrawIcon( + iconIndex: number, + textState: { x: number; y: number } + ) { this.drawIcon(iconIndex, textState.x + 2, textState.y + 2); textState.x += Window_Base._iconWidth + 4; } @@ -486,7 +502,17 @@ export class Window_Base extends Window { } } - public calcTextHeight(textState, all) { + public calcTextHeight( + textState: { + index: any; + x?: number; + y?: number; + left?: number; + text: any; + height?: any; + }, + all: boolean + ) { const lastFontSize = this.contents.fontSize; let textHeight = 0; const lines = textState.text.slice(textState.index).split("\n"); @@ -518,7 +544,7 @@ export class Window_Base extends Window { return textHeight; } - public async drawIcon(iconIndex, x, y) { + public async drawIcon(iconIndex: number, x: number, y: number) { const bitmap = ImageManager.loadSystem("IconSet"); await bitmap.imagePromise; const pw = Window_Base._iconWidth; @@ -568,14 +594,44 @@ export class Window_Base extends Window { this.contents.blt(bitmap, sx, sy, pw, ph, x - pw / 2, y - ph); } - public drawGauge(x, y, width, rate, color1, color2) { - const fillW = Math.floor(width * rate); - const gaugeY = y + this.lineHeight() - 8; - this.contents.fillRect(x, gaugeY, width, 6, this.gaugeBackColor()); - this.contents.gradientFillRect(x, gaugeY, fillW, 6, color1, color2); + public drawGauge( + dx: number, + dy: number, + dw: number, + rate: number, + color1: string, + color2: string + ) { + const color3 = this.gaugeBackColor(); + let fillW = Utils.clamp(Math.floor(dw * rate), 0, dw); + let gaugeH = this.gaugeHeight(); + let gaugeY = dy + this.lineHeight() - gaugeH - 2; + if (Yanfly.Param.GaugeOutline) { + this.contents.paintOpacity = this.translucentOpacity(); + this.contents.fillRect(dx, gaugeY - 1, dw, gaugeH, color3); + fillW = Math.max(fillW - 2, 0); + gaugeH -= 2; + dx += 1; + } else { + fillW = Math.floor(dw * rate); + gaugeY = dy + this.lineHeight() - gaugeH - 2; + this.contents.fillRect(dx, gaugeY, dw, gaugeH, color3); + } + this.contents.gradientFillRect( + dx, + gaugeY, + fillW, + gaugeH, + color1, + color2 + ); + } + + public gaugeHeight() { + return Yanfly.Param.GaugeHeight; } - public hpColor(actor) { + public hpColor(actor: Game_Actor) { if (actor.isDead()) { return this.deathColor(); } else if (actor.isDying()) { @@ -585,19 +641,29 @@ export class Window_Base extends Window { } } - public mpColor(actor) { + public mpColor(actor: Game_Actor) { return this.normalColor(); } - public tpColor(actor) { + public tpColor(actor: any) { return this.normalColor(); } - public drawActorCharacter(actor, x, y) { + public drawActorCharacter( + actor: { characterName: () => string; characterIndex: () => number }, + x: number, + y: number + ) { this.drawCharacter(actor.characterName(), actor.characterIndex(), x, y); } - public async drawActorFace(actor, x, y, width?, height?) { + public async drawActorFace( + actor: Game_Actor, + x: number, + y: number, + width?: number, + height?: number + ) { await this.drawFace( actor.faceName(), actor.faceIndex(), @@ -630,24 +696,25 @@ export class Window_Base extends Window { this.drawText(actor.currentClass().name, x, y, width); } - public drawActorNickname(actor, x, y, width?) { + public drawActorNickname( + actor: Game_Actor, + x: number, + y: number, + width?: number + ) { width = width || 270; this.resetTextColor(); this.drawText(actor.nickname(), x, y, width); } - public drawActorLevel(actor: Game_Actor, x, y) { + public drawActorLevel(actor: Game_Actor, x: number, y: number) { this.changeTextColor(this.systemColor()); - this.drawText(TextManager.levelA, x, y, 48); + const dw1 = this.textWidth(TextManager.levelA); + this.drawText(TextManager.levelA, x, y, dw1); this.resetTextColor(); - this.drawText( - actor.level.toString(), - x + 84, - y, - 36, - undefined, - "right" - ); + const level = Yanfly.Util.toGroup(actor.level); + const dw2 = this.textWidth(Yanfly.Util.toGroup(actor.maxLevel())); + this.drawText(level, x + dw1, y, dw2, undefined, "right"); } public async drawActorIcons( @@ -669,22 +736,51 @@ export class Window_Base extends Window { await Promise.all(promises); } - public drawCurrentAndMax(current, max, x, y, width, color1, color2) { + public drawCurrentAndMax( + current: any, + max: any, + x: number, + y: number, + width: number, + color1: string, + color2: string + ) { const labelWidth = this.textWidth("HP"); - const valueWidth = this.textWidth("0000"); + const valueWidth = this.textWidth(Yanfly.Util.toGroup(max)); const slashWidth = this.textWidth("/"); const x1 = x + width - valueWidth; const x2 = x1 - slashWidth; const x3 = x2 - valueWidth; if (x3 >= x + labelWidth) { this.changeTextColor(color1); - this.drawText(current, x3, y, valueWidth, undefined, "right"); + this.drawText( + Yanfly.Util.toGroup(current), + x3, + y, + valueWidth, + undefined, + "right" + ); this.changeTextColor(color2); this.drawText("/", x2, y, slashWidth, undefined, "right"); - this.drawText(max, x1, y, valueWidth, undefined, "right"); + this.drawText( + Yanfly.Util.toGroup(max), + x1, + y, + valueWidth, + undefined, + "right" + ); } else { this.changeTextColor(color1); - this.drawText(current, x1, y, valueWidth, undefined, "right"); + this.drawText( + Yanfly.Util.toGroup(current), + x1, + y, + valueWidth, + undefined, + "right" + ); } } @@ -734,7 +830,7 @@ export class Window_Base extends Window { ); } - public drawActorTp(actor, x, y, width) { + public drawActorTp(actor: Game_Actor, x: number, y: number, width: number) { width = width || 96; const color1 = this.tpGaugeColor1(); const color2 = this.tpGaugeColor2(); @@ -745,16 +841,25 @@ export class Window_Base extends Window { this.drawText(actor.tp, x + width - 64, y, 64, undefined, "right"); } - public async drawActorSimpleStatus(actor, x, y, width) { + public async drawActorSimpleStatus( + actor: Game_Actor, + x: number, + y: number, + width: number + ) { const lineHeight = this.lineHeight(); + const xpad = Window_Base._faceWidth + 2 * Yanfly.Param.TextPadding; const x2 = x + 180; - const width2 = Math.min(200, width - 180 - this.textPadding()); + const width2 = Math.max(180, width - xpad - this.textPadding()); this.drawActorName(actor, x, y); this.drawActorLevel(actor, x, y + lineHeight * 1); await this.drawActorIcons(actor, x, y + lineHeight * 2); this.drawActorClass(actor, x2, y); this.drawActorHp(actor, x2, y + lineHeight * 1, width2); this.drawActorMp(actor, x2, y + lineHeight * 2, width2); + if (Yanfly.Param.MenuTpGauge) { + this.drawActorTp(actor, x2, y + lineHeight * 3, width2); + } } public drawItemName(item: Item, x: number, y: number, width?: number) { @@ -767,22 +872,44 @@ export class Window_Base extends Window { } } - public drawCurrencyValue(value, unit, x, y, width) { - const unitWidth = Math.min(80, this.textWidth(unit)); + public drawCurrencyValue( + value: number, + unit: string, + wx: number, + wy: number, + ww: number + ) { this.resetTextColor(); - this.drawText(value, x, y, width - unitWidth - 6, undefined, "right"); - this.changeTextColor(this.systemColor()); - this.drawText( - unit, - x + width - unitWidth, - y, - unitWidth, - undefined, - "right" - ); + this.contents.fontSize = Yanfly.Param.GoldFontSize; + if (this.usingGoldIcon(unit)) { + var cx = Window_Base._iconWidth; + } else { + var cx = this.textWidth(unit); + } + var text = Yanfly.Util.toGroup(value); + if (this.textWidth(text) > ww - cx) { + text = Yanfly.Param.GoldOverlap; + } + this.drawText(text, wx, wy, ww - cx - 4, undefined, "right"); + if (this.usingGoldIcon(unit)) { + this.drawIcon( + Yanfly.Icon.Gold, + wx + ww - Window_Base._iconWidth, + wy + 2 + ); + } else { + this.changeTextColor(this.systemColor()); + this.drawText(unit, wx, wy, ww, undefined, "right"); + } + this.resetFontSettings(); + } + + public usingGoldIcon(unit: string) { + if (unit !== TextManager.currencyUnit) return false; + return Yanfly.Icon.Gold > 0; } - public paramchangeTextColor(change) { + public paramchangeTextColor(change: number) { if (change > 0) { return this.powerUpColor(); } else if (change < 0) { @@ -792,7 +919,7 @@ export class Window_Base extends Window { } } - public setBackgroundType(type) { + public setBackgroundType(type: number) { if (type === 0) { this.opacity = 255; } else { @@ -855,7 +982,7 @@ export class Window_Base extends Window { return "rgba(0, 0, 0, 0)"; } - public canvasToLocalX(x) { + public canvasToLocalX(x: number) { let node = this; while (node) { x -= node.x; @@ -865,7 +992,7 @@ export class Window_Base extends Window { return x; } - public canvasToLocalY(y) { + public canvasToLocalY(y: number) { let node = this; while (node) { y -= node.y; diff --git a/ts/windows/Window_BattleActor.ts b/ts/windows/Window_BattleActor.ts index 2c6aae7..f452889 100644 --- a/ts/windows/Window_BattleActor.ts +++ b/ts/windows/Window_BattleActor.ts @@ -1,3 +1,8 @@ +import { Rectangle } from "../core/Rectangle"; +import { TouchInput } from "../core/TouchInput"; +import { BattleManager } from "../managers/BattleManager"; +import { SoundManager } from "../managers/SoundManager"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; import { Window_BattleStatus } from "./Window_BattleStatus"; // ----------------------------------------------------------------------------- @@ -9,6 +14,7 @@ export class Window_BattleActor extends Window_BattleStatus { public x: any; public y: any; public openness: number; + private _selectDead: boolean; public constructor(x, y) { super(); @@ -36,4 +42,153 @@ export class Window_BattleActor extends Window_BattleStatus { public actor() { return $gameParty.members()[this.index()]; } + + public autoSelect() { + let action = BattleManager.inputtingAction(); + if (!action) return; + this._inputLock = false; + this._selectDead = false; + this.setCursorAll(false); + if (action.isForUser()) { + this.select(BattleManager.actor().index()); + this._inputLock = true; + } else if (action.isForAll()) { + this._inputLock = true; + this.setCursorAll(true); + } else if (action.isForDeadFriend()) { + this._selectDead = true; + this.autoSelectFirstDeadActor(); + } + this.updateCursor(); + } + + public updateCursor() { + if (this._cursorAll) { + let allRowsHeight = this.maxRows() * this.itemHeight(); + this.setCursorRect(0, 0, this.contents.width, allRowsHeight); + this.setTopRow(0); + } else if (this.isCursorVisible()) { + let rect = this.itemRect(this.index()); + this.setCursorRect(rect.x, rect.y, rect.width, rect.height); + } else { + this.setCursorRect(0, 0, 0, 0); + } + } + + public autoSelectFirstDeadActor() { + let length = $gameParty.members().length; + for (let i = 0; i < length; ++i) { + let member = $gameParty.members()[i]; + if (member && member.isDead()) return this.select(i); + } + } + + public isOkEnabled() { + if (this._selectDead) return this.actor().isDead(); + return super.isOkEnabled(); + } + + public updateHelp() { + if (!this._helpWindow) return; + this._helpWindow.setBattler(this.actor()); + } + + public processTouch() { + if (Yanfly.Param.BECActorSelect && this.isOpenAndActive()) { + if (TouchInput.isTriggered() && !this.isTouchedInsideFrame()) { + if (this.getClickedActor() >= 0) { + var index = this.getClickedActor(); + if (this.index() === index) { + return this.processOk(); + } else { + SoundManager.playCursor(); + return this.select(index); + } + } + } + if (TouchInput.isPressed() && !this.isTouchedInsideFrame()) { + if (this.getClickedActor() >= 0) { + var index = this.getClickedActor(); + if (this.index() !== index) { + SoundManager.playCursor(); + return this.select(index); + } + } + } + if (Yanfly.Param.BECSelectMouseOver) { + var index = this.getMouseOverActor(); + if (index >= 0 && this.index() !== index) { + SoundManager.playCursor(); + return this.select(index); + } + } + } + super.processTouch(); + } + + public getClickedActor() { + for (let i = 0; i < $gameParty.battleMembers().length; ++i) { + let actor = $gameParty.battleMembers().reverse()[i]; + if (!actor) continue; + if (this.isClickedActor(actor)) { + if (this._selectDead && !actor.isDead()) continue; + if (this._inputLock && actor.index() !== this.index()) continue; + return actor.index(); + } + } + return -1; + } + + public isClickedActor(actor) { + if (!actor) return false; + if (!actor.isSpriteVisible()) return false; + if (!actor.isAppeared()) return false; + if ($gameTemp.mouseOverSelectDisabled()) return false; + let x = TouchInput.x; + let y = TouchInput.y; + let rect = new Rectangle(); + rect.width = actor.spriteWidth(); + rect.height = actor.spriteHeight(); + rect.x = actor.spritePosX() - rect.width / 2; + rect.y = actor.spritePosY() - rect.height; + return ( + x >= rect.x && + y >= rect.y && + x < rect.x + rect.width && + y < rect.y + rect.height + ); + } + + public getMouseOverActor() { + for (let i = 0; i < $gameParty.battleMembers().length; ++i) { + let actor = $gameParty.battleMembers().reverse()[i]; + if (!actor) continue; + if (this.isMouseOverActor(actor)) { + if (this._selectDead && !actor.isDead()) continue; + if (this._inputLock && actor.index() !== this.index()) continue; + return actor.index(); + } + } + return -1; + } + + public isMouseOverActor(actor) { + if (!actor) return false; + if (!actor.isSpriteVisible()) return false; + if (!actor.isAppeared()) return false; + if ($gameTemp.mouseOverSelectDisabled()) return false; + let x = TouchInput._mouseOverX; + let y = TouchInput._mouseOverY; + let rect = new Rectangle(); + rect.width = actor.spriteWidth(); + rect.height = actor.spriteHeight(); + rect.x = actor.spritePosX() - rect.width / 2; + rect.y = actor.spritePosY() - rect.height; + return ( + x >= rect.x && + y >= rect.y && + x < rect.x + rect.width && + y < rect.y + rect.height + ); + } } diff --git a/ts/windows/Window_BattleEnemy.ts b/ts/windows/Window_BattleEnemy.ts index 6d8455c..8546830 100644 --- a/ts/windows/Window_BattleEnemy.ts +++ b/ts/windows/Window_BattleEnemy.ts @@ -1,7 +1,10 @@ -import { Graphics } from "../core/Graphics"; +import { Rectangle } from "../core/Rectangle"; +import { TouchInput } from "../core/TouchInput"; +import { ConfigManager } from "../managers/ConfigManager"; +import { SoundManager } from "../managers/SoundManager"; import { Game_Enemy } from "../objects/Game_Enemy"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; import { Window_Selectable } from "./Window_Selectable"; -import { ConfigManager } from "../managers/ConfigManager"; // ----------------------------------------------------------------------------- // Window_BattleEnemy @@ -9,7 +12,17 @@ import { ConfigManager } from "../managers/ConfigManager"; // The window for selecting a target enemy on the battle screen. export class Window_BattleEnemy extends Window_Selectable { - private get _enemies(): Game_Enemy[] { + private _selectDead: boolean; + + public get selectDead(): boolean { + return this._selectDead; + } + + public set selectDead(value: boolean) { + this._selectDead = value; + } + + public get _enemies(): Game_Enemy[] { if (!this.__enemies) { this.__enemies = $gameTroop.aliveMembers(); } @@ -19,6 +32,10 @@ export class Window_BattleEnemy extends Window_Selectable { private __enemies: Game_Enemy[]; public constructor(x: number, y: number) { + if (Yanfly.Param.BECEnemySelect) { + x -= ConfigManager.currentResolution.widthPx * 200; + y -= ConfigManager.currentResolution.heightPx * 200; + } super( x, y, @@ -42,6 +59,7 @@ export class Window_BattleEnemy extends Window_Selectable { } public maxCols() { + if (Yanfly.Param.BECEnemySelect) return this._enemies.length; return 2; } @@ -49,6 +67,12 @@ export class Window_BattleEnemy extends Window_Selectable { return this._enemies.length; } + public allowedTargets() { + let targets = []; + targets = targets.concat($gameTroop.aliveMembers()); + return targets; + } + public enemy() { return this._enemies[this.index()]; } @@ -77,7 +101,8 @@ export class Window_BattleEnemy extends Window_Selectable { } public async refresh() { - this.__enemies = $gameTroop.aliveMembers(); + this.__enemies = this.allowedTargets(); + this.sortTargets(); await super.refresh(); } @@ -85,4 +110,133 @@ export class Window_BattleEnemy extends Window_Selectable { super.select(index); $gameTroop.select(this.enemy()); } + + public sortTargets() { + this._enemies.sort(function(a, b) { + if (a.spritePosX() === b.spritePosX()) { + return a.spritePosY() - b.spritePosY(); + } + return a.spritePosX() - b.spritePosX(); + }); + } + + public autoSelect() { + if ( + Yanfly.Param.BECEnemyAutoSel === 0 || + Yanfly.Param.BECEnemyAutoSel === "0" + ) { + var selectIndex = 0; + } else { + var selectIndex = this.furthestRight(); + } + this.select(selectIndex); + } + + public furthestRight() { + return this.maxItems() - 1; + } + + public updateHelp() { + if (!this._helpWindow) return; + this._helpWindow.setBattler(this.enemy()); + } + + public processTouch() { + if (Yanfly.Param.BECEnemySelect && this.isOpenAndActive()) { + if (TouchInput.isTriggered() && !this.isTouchedInsideFrame()) { + if (this.getClickedEnemy() >= 0) { + var index = this.getClickedEnemy(); + if (this.index() === index) { + return this.processOk(); + } else { + SoundManager.playCursor(); + return this.select(index); + } + } + } + if (TouchInput.isPressed() && !this.isTouchedInsideFrame()) { + if (this.getClickedEnemy() >= 0) { + var index = this.getClickedEnemy(); + if (this.index() !== index) { + SoundManager.playCursor(); + return this.select(index); + } + } + } + if (Yanfly.Param.BECSelectMouseOver) { + var index = this.getMouseOverEnemy(); + if (index >= 0 && this.index() !== index) { + SoundManager.playCursor(); + return this.select(index); + } + } + } + super.processTouch(); + } + + public getClickedEnemy() { + for (let i = 0; i < this._enemies.length; ++i) { + let enemy = this._enemies[i]; + if (!enemy) continue; + if (this.isClickedEnemy(enemy)) { + if (this._selectDead && !enemy.isDead()) continue; + let index = this._enemies.indexOf(enemy); + if (this._inputLock && index !== this.index()) continue; + return index; + } + } + return -1; + } + + public isClickedEnemy(enemy) { + if (!enemy) return false; + if (!enemy.isSpriteVisible()) return false; + if ($gameTemp.mouseOverSelectDisabled()) return false; + let x = TouchInput.x; + let y = TouchInput.y; + let rect = new Rectangle(); + rect.width = enemy.spriteWidth(); + rect.height = enemy.spriteHeight(); + rect.x = enemy.spritePosX() - rect.width / 2; + rect.y = enemy.spritePosY() - rect.height; + return ( + x >= rect.x && + y >= rect.y && + x < rect.x + rect.width && + y < rect.y + rect.height + ); + } + + public getMouseOverEnemy() { + for (let i = 0; i < this._enemies.length; ++i) { + let enemy = this._enemies[i]; + if (!enemy) continue; + if (this.isMouseOverEnemy(enemy)) { + if (this._selectDead && !enemy.isDead()) continue; + let index = this._enemies.indexOf(enemy); + if (this._inputLock && index !== this.index()) continue; + return index; + } + } + return -1; + } + + public isMouseOverEnemy(enemy) { + if (!enemy) return false; + if (!enemy.isSpriteVisible()) return false; + if ($gameTemp.mouseOverSelectDisabled()) return false; + let x = TouchInput._mouseOverX; + let y = TouchInput._mouseOverY; + let rect = new Rectangle(); + rect.width = enemy.spriteWidth(); + rect.height = enemy.spriteHeight(); + rect.x = enemy.spritePosX() - rect.width / 2; + rect.y = enemy.spritePosY() - rect.height; + return ( + x >= rect.x && + y >= rect.y && + x < rect.x + rect.width && + y < rect.y + rect.height + ); + } } diff --git a/ts/windows/Window_BattleItem.ts b/ts/windows/Window_BattleItem.ts index 7e1f614..7c96a5a 100644 --- a/ts/windows/Window_BattleItem.ts +++ b/ts/windows/Window_BattleItem.ts @@ -1,4 +1,6 @@ import { Window_ItemList } from "./Window_ItemList"; +import { Game_Actor } from "../objects/Game_Actor"; +import { Item } from "../interfaces/Item"; // ----------------------------------------------------------------------------- // Window_BattleItem @@ -6,16 +8,27 @@ import { Window_ItemList } from "./Window_ItemList"; // The window for selecting an item to use on the battle screen. export class Window_BattleItem extends Window_ItemList { - public constructor(x, y, width, height) { + private _actor: Game_Actor; + + public constructor(x: number, y: number, width: number, height: number) { super(x, y, width, height); this.hide(); } - public includes(item) { + public includes(item: Item) { return $gameParty.canUse(item); } + public maxCols() { + return 1; + } + public show() { + const width = 300; + const height = 300; + const sprite = $gameActors.actor(this._actor.actorId()).battler(); + const scale = $gameScreen.zoomScale(); + this.move(sprite.x * scale - width, sprite.y * scale, width, height); this.selectLast(); this.showHelpWindow(); super.show(); @@ -25,4 +38,8 @@ export class Window_BattleItem extends Window_ItemList { this.hideHelpWindow(); super.hide(); } + + public set actor(actor: Game_Actor) { + this._actor = actor; + } } diff --git a/ts/windows/Window_BattleLog.ts b/ts/windows/Window_BattleLog.ts index bc1eafd..fa683db 100644 --- a/ts/windows/Window_BattleLog.ts +++ b/ts/windows/Window_BattleLog.ts @@ -4,9 +4,11 @@ import { Input } from "../core/Input"; import { Sprite } from "../core/Sprite"; import { TouchInput } from "../core/TouchInput"; import { Utils } from "../core/Utils"; +import { BattleManager } from "../managers/BattleManager"; import { DataManager } from "../managers/DataManager"; import { SoundManager } from "../managers/SoundManager"; import { TextManager } from "../managers/TextManager"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; import { Window_Selectable } from "./Window_Selectable"; // ----------------------------------------------------------------------------- @@ -25,6 +27,7 @@ export class Window_BattleLog extends Window_Selectable { private _spriteset: any; private _backBitmap: Bitmap; private _backSprite: Sprite; + _actionIcon: any; public constructor() { super( @@ -96,33 +99,6 @@ export class Window_BattleLog extends Window_Selectable { return this.updateWaitCount() || this.updateWaitMode(); } - public updateWaitCount() { - if (this._waitCount > 0) { - this._waitCount -= this.isFastForward() ? 3 : 1; - if (this._waitCount < 0) { - this._waitCount = 0; - } - return true; - } - return false; - } - - public updateWaitMode() { - let waiting = false; - switch (this._waitMode) { - case "effect": - waiting = this._spriteset.isEffecting(); - break; - case "movement": - waiting = this._spriteset.isAnyoneMoving(); - break; - } - if (!waiting) { - this._waitMode = ""; - } - return waiting; - } - public setWaitMode(waitMode) { this._waitMode = waitMode; } @@ -139,6 +115,7 @@ export class Window_BattleLog extends Window_Selectable { } public isFastForward() { + if (Yanfly.Param.BECOptSpeed) return true; return ( Input.isLongPressed("ok") || Input.isPressed("shift") || @@ -161,10 +138,6 @@ export class Window_BattleLog extends Window_Selectable { this._waitCount = this.messageSpeed(); } - public waitForEffect() { - this.setWaitMode("effect"); - } - public waitForMovement() { this.setWaitMode("movement"); } @@ -196,10 +169,6 @@ export class Window_BattleLog extends Window_Selectable { } } - public popupDamage(target) { - target.startDamagePopup(); - } - public performActionStart(subject, action) { subject.performActionStart(action); } @@ -270,29 +239,61 @@ export class Window_BattleLog extends Window_Selectable { } public showEnemyAttackAnimation(subject, targets) { - SoundManager.playEnemyAttack(); + if ($gameSystem.isSideView()) { + this.showNormalAnimation( + targets, + subject.attackAnimationId(), + false + ); + } else { + this.showNormalAnimation( + targets, + subject.attackAnimationId(), + false + ); + SoundManager.playEnemyAttack(); + } + } + + public showActorAtkAniMirror(subject, targets) { + if (subject.isActor()) { + this.showNormalAnimation( + targets, + subject.attackAnimationId1(), + true + ); + this.showNormalAnimation( + targets, + subject.attackAnimationId2(), + false + ); + } else { + this.showNormalAnimation( + targets, + subject.attackAnimationId1(), + true + ); + } } public showNormalAnimation(targets, animationId, mirror?) { const animation = $dataAnimations[animationId]; if (animation) { - let delay = this.animationBaseDelay(); - const nextDelay = this.animationNextDelay(); - targets.forEach(function(target) { - target.startAnimation(animationId, mirror, delay); - delay += nextDelay; - }); + if (animation.position === 3) { + targets.forEach(function(target) { + target.startAnimation(animationId, mirror, 0); + }); + } else { + let delay = this.animationBaseDelay(); + const nextDelay = this.animationNextDelay(); + targets.forEach(function(target) { + target.startAnimation(animationId, mirror, delay); + delay += nextDelay; + }); + } } } - public animationBaseDelay() { - return 8; - } - - public animationNextDelay() { - return 12; - } - public async refresh() { this.drawBackground(); this.contents.clear(); @@ -336,36 +337,23 @@ export class Window_BattleLog extends Window_Selectable { } public drawLineText(index) { - const rect = this.itemRectForText(index); - this.contents.clearRect(rect.x, rect.y, rect.width, rect.height); - this.drawTextEx(this._lines[index], rect.x, rect.y); + if (this._lines[index].match("
")) { + this.drawCenterLine(index); + } else if (this._lines[index].match("")) { + this.drawSimpleActionLine(index); + } else { + const rect = this.itemRectForText(index); + this.contents.clearRect(rect.x, rect.y, rect.width, rect.height); + this.drawTextEx(this._lines[index], rect.x, rect.y); + } } public startTurn() { this.push("wait"); } - public startAction(subject, action, targets) { - const item = action.item(); - this.push("performActionStart", subject, action); - this.push("waitForMovement"); - this.push("performAction", subject, action); - this.push( - "showAnimation", - subject, - Utils.arrayClone(targets), - item.animationId - ); - this.displayAction(subject, item); - } - - public endAction(subject) { - this.push("waitForNewLine"); - this.push("clear"); - this.push("performActionEnd", subject); - } - public displayCurrentState(subject) { + if (!Yanfly.Param.BECShowStateText) return; const stateText = subject.mostImportantStateText(); if (stateText) { this.push("addText", subject.name() + stateText); @@ -379,69 +367,78 @@ export class Window_BattleLog extends Window_Selectable { } public displayAction(subject, item) { - const numMethods = this._methods.length; - if (DataManager.isSkill(item)) { - if (item.message1) { + if (Yanfly.Param.BECFullActText) { + const numMethods = this._methods.length; + if (DataManager.isSkill(item)) { + if (item.message1) { + this.push( + "addText", + subject.name() + Utils.format(item.message1, item.name) + ); + } + if (item.message2) { + this.push( + "addText", + Utils.format(item.message2, item.name) + ); + } + } else { this.push( "addText", - subject.name() + Utils.format(item.message1, item.name) + Utils.format(TextManager.useItem, subject.name(), item.name) ); } - if (item.message2) { - this.push("addText", Utils.format(item.message2, item.name)); + if (this._methods.length === numMethods) { + this.push("wait"); } } else { - this.push( - "addText", - Utils.format(TextManager.useItem, subject.name(), item.name) - ); - } - if (this._methods.length === numMethods) { - this.push("wait"); + this._actionIcon = this.displayIcon(item); + var text = this.displayText(item); + this.push("addText", "" + text); + if (item.message2) { + this.push("addText", "
" + item.message2.format(text)); + } } } - public displayCounter(target) { - this.push("performCounter", target); - this.push( - "addText", - Utils.format(TextManager.counterAttack, target.name()) - ); + public displayIcon(item) { + if (!item) return 0; + return item.battleDisplayIcon; } - public displayReflection(target) { - this.push("performReflection", target); - this.push( - "addText", - Utils.format(TextManager.magicReflection, target.name()) - ); - } - - public displaySubstitute(substitute, target) { - const substName = substitute.name(); - this.push("performSubstitute", substitute, target); - this.push( - "addText", - Utils.format(TextManager.substitute, substName, target.name()) - ); + public displayText(item) { + if (!item) return ""; + return item.battleDisplayText; } public displayActionResults(subject, target) { - if (target.result().used) { - this.push("pushBaseLine"); - this.displayCritical(target); - this.push("popupDamage", target); - this.push("popupDamage", subject); - this.displayDamage(target); - this.displayAffectedStatus(target); - this.displayFailure(target); - this.push("waitForNewLine"); - this.push("popBaseLine"); + if (Yanfly.Param.BECOptSpeed) { + if (target.result.used) { + this.displayCritical(target); + this.displayDamage(target); + this.displayAffectedStatus(target); + this.displayFailure(target); + } + } else { + if (target.result.used) { + this.push("pushBaseLine"); + this.displayCritical(target); + this.push("popupDamage", target); + this.push("popupDamage", subject); + this.displayDamage(target); + this.displayAffectedStatus(target); + this.displayFailure(target); + this.push("waitForNewLine"); + this.push("popBaseLine"); + } } + + if (target.isDead()) target.performCollapse(); } public displayFailure(target) { - if (target.result().isHit() && !target.result().success) { + if (!Yanfly.Param.BECShowFailText) return; + if (target.result.isHit() && !target.result.success) { this.push( "addText", Utils.format(TextManager.actionFailure, target.name()) @@ -450,7 +447,8 @@ export class Window_BattleLog extends Window_Selectable { } public displayCritical(target) { - if (target.result().critical) { + if (!Yanfly.Param.BECShowCritText) return; + if (target.result.critical) { if (target.isActor()) { this.push("addText", TextManager.criticalToActor); } else { @@ -460,9 +458,9 @@ export class Window_BattleLog extends Window_Selectable { } public displayDamage(target) { - if (target.result().missed) { + if (target.result.missed) { this.displayMiss(target); - } else if (target.result().evaded) { + } else if (target.result.evaded) { this.displayEvasion(target); } else { this.displayHpDamage(target); @@ -472,8 +470,9 @@ export class Window_BattleLog extends Window_Selectable { } public displayMiss(target) { + if (!Yanfly.Param.BECShowMissText) return; let fmt; - if (target.result().physical) { + if (target.result.physical) { fmt = target.isActor() ? TextManager.actorNoHit : TextManager.enemyNoHit; @@ -485,8 +484,9 @@ export class Window_BattleLog extends Window_Selectable { } public displayEvasion(target) { + if (!Yanfly.Param.BECShowEvaText) return; let fmt; - if (target.result().physical) { + if (target.result.physical) { fmt = TextManager.evasion; this.push("performEvasion", target); } else { @@ -497,11 +497,12 @@ export class Window_BattleLog extends Window_Selectable { } public displayHpDamage(target) { - if (target.result().hpAffected) { - if (target.result().hpDamage > 0 && !target.result().drain) { + if (!Yanfly.Param.BECShowHpText) return; + if (target.result.hpAffected) { + if (target.result.hpDamage > 0 && !target.result.drain) { this.push("performDamage", target); } - if (target.result().hpDamage < 0) { + if (target.result.hpDamage < 0) { this.push("performRecovery", target); } this.push("addText", this.makeHpDamageText(target)); @@ -509,8 +510,9 @@ export class Window_BattleLog extends Window_Selectable { } public displayMpDamage(target) { - if (target.isAlive() && target.result().mpDamage !== 0) { - if (target.result().mpDamage < 0) { + if (!Yanfly.Param.BECShowMpText) return; + if (target.isAlive() && target.result.mpDamage !== 0) { + if (target.result.mpDamage < 0) { this.push("performRecovery", target); } this.push("addText", this.makeMpDamageText(target)); @@ -518,8 +520,9 @@ export class Window_BattleLog extends Window_Selectable { } public displayTpDamage(target) { - if (target.isAlive() && target.result().tpDamage !== 0) { - if (target.result().tpDamage < 0) { + if (!Yanfly.Param.BECShowTpText) return; + if (target.isAlive() && target.result.tpDamage !== 0) { + if (target.result.tpDamage < 0) { this.push("performRecovery", target); } this.push("addText", this.makeTpDamageText(target)); @@ -527,7 +530,7 @@ export class Window_BattleLog extends Window_Selectable { } public displayAffectedStatus(target) { - if (target.result().isStatusAffected()) { + if (target.result.isStatusAffected()) { this.push("pushBaseLine"); this.displayChangedStates(target); this.displayChangedBuffs(target); @@ -537,7 +540,7 @@ export class Window_BattleLog extends Window_Selectable { } public displayAutoAffectedStatus(target) { - if (target.result().isStatusAffected()) { + if (target.result.isStatusAffected()) { this.displayAffectedStatus(target); this.push("clear"); } @@ -549,40 +552,35 @@ export class Window_BattleLog extends Window_Selectable { } public displayAddedStates(target) { - target - .result() - .addedStateObjects() - .forEach(function(state) { - const stateMsg = target.isActor() - ? state.message1 - : state.message2; - if (state.id === target.deathStateId()) { - this.push("performCollapse", target); - } - if (stateMsg) { - this.push("popBaseLine"); - this.push("pushBaseLine"); - this.push("addText", target.name() + stateMsg); - this.push("waitForEffect"); - } - }, this); + if (!Yanfly.Param.BECShowStateText) return; + target.result.addedStateObjects().forEach(function(state) { + const stateMsg = target.isActor() ? state.message1 : state.message2; + if (state.id === target.deathStateId()) { + this.push("performCollapse", target); + } + if (stateMsg) { + this.push("popBaseLine"); + this.push("pushBaseLine"); + this.push("addText", target.name() + stateMsg); + this.push("waitForEffect"); + } + }, this); } public displayRemovedStates(target) { - target - .result() - .removedStateObjects() - .forEach(function(state) { - if (state.message4) { - this.push("popBaseLine"); - this.push("pushBaseLine"); - this.push("addText", target.name() + state.message4); - } - }, this); + if (!Yanfly.Param.BECShowStateText) return; + target.result.removedStateObjects().forEach(function(state) { + if (state.message4) { + this.push("popBaseLine"); + this.push("pushBaseLine"); + this.push("addText", target.name() + state.message4); + } + }, this); } public displayChangedBuffs(target) { - const result = target.result(); + if (!Yanfly.Param.BECShowBuffText) return; + const result = target.result; this.displayBuffs(target, result.addedBuffs, TextManager.buffAdd); this.displayBuffs(target, result.addedDebuffs, TextManager.debuffAdd); this.displayBuffs(target, result.removedBuffs, TextManager.buffRemove); @@ -600,7 +598,7 @@ export class Window_BattleLog extends Window_Selectable { } public makeHpDamageText(target) { - const result = target.result(); + const result = target.result; const damage = result.hpDamage; const isActor = target.isActor(); let fmt; @@ -624,7 +622,7 @@ export class Window_BattleLog extends Window_Selectable { } public makeMpDamageText(target) { - const result = target.result(); + const result = target.result; const damage = result.mpDamage; const isActor = target.isActor(); let fmt; @@ -645,7 +643,7 @@ export class Window_BattleLog extends Window_Selectable { } public makeTpDamageText(target) { - const result = target.result(); + const result = target.result; const damage = result.tpDamage; const isActor = target.isActor(); let fmt; @@ -659,4 +657,133 @@ export class Window_BattleLog extends Window_Selectable { return ""; } } + + public updateWaitCount() { + if (this._waitCount > 0) { + this._waitCount -= 1; + if (this._waitCount < 0) { + this._waitCount = 0; + } + return true; + } + return false; + } + + public animationBaseDelay() { + return Yanfly.Param.BECAniBaseDel; + } + + public animationNextDelay() { + return Yanfly.Param.BECAniNextDel; + } + + public updateWaitMode() { + var waiting = false; + switch (this._waitMode) { + case "effect": + waiting = this._spriteset.isEffecting(); + break; + case "movement": + waiting = this._spriteset.isAnyoneMoving(); + break; + case "animation": + waiting = this._spriteset.isAnimationPlaying(); + break; + case "popups": + waiting = this._spriteset.isPopupPlaying(); + break; + } + if (!waiting) { + this._waitMode = ""; + } + return waiting; + } + + public startAction(subject, action, targets) {} + + public endAction(subject) {} + + public waitForAnimation() { + this.setWaitMode("animation"); + } + + public waitForEffect() { + this.setWaitMode("effect"); + } + + public waitForPopups() { + this.setWaitMode("popups"); + } + + public textWidthEx(text) { + return this.drawTextEx( + text, + 0, + this.contents.height + this.lineHeight() + ); + } + + public drawCenterLine(index) { + let text = this._lines[index].replace("
", ""); + let rect = this.itemRectForText(index); + this.contents.clearRect(rect.x, rect.y, rect.width, rect.height); + let tw = this.textWidthEx(text); + let wx = rect.x + (rect.width - tw) / 2; + this.resetFontSettings(); + this.drawTextEx(text, wx, rect.y); + } + + public drawSimpleActionLine(index) { + let text = this._lines[index].replace("", ""); + let rect = this.itemRectForText(index); + this.contents.clearRect(rect.x, rect.y, rect.width, rect.height); + if (this._actionIcon) { + let tw = this.textWidth(text); + let ix = (rect.width - tw) / 2 - 4; + this.drawIcon(this._actionIcon, ix, rect.y + 2); + } + this.drawText( + text, + rect.x, + rect.y, + Graphics.boxWidth, + undefined, + "center" + ); + } + + public displayCounter(target) { + if (Yanfly.Param.BECShowCntText) { + this.addText( + Utils.format(TextManager.counterAttack, target.name()) + ); + } + target.performCounter(); + this.showAttackAnimation(target, [BattleManager.subject]); + this.waitForAnimation(); + } + + public displayReflection(target) { + if (Yanfly.Param.BECShowRflText) { + this.addText( + Utils.format(TextManager.magicReflection, target.name()) + ); + } + target.performReflection(); + let animationId = BattleManager.action.item().animationId; + this.showNormalAnimation([BattleManager.subject], animationId); + this.waitForAnimation(); + } + + public displaySubstitute(substitute, target) { + if (Yanfly.Param.BECShowSubText) { + let substName = substitute.name(); + this.addText( + Utils.format(TextManager.substitute, substName, target.name()) + ); + } + substitute.performSubstitute(target); + } + + public popupDamage(target) {} } diff --git a/ts/windows/Window_BattleSkill.ts b/ts/windows/Window_BattleSkill.ts index 6bd3cdc..a7c84e9 100644 --- a/ts/windows/Window_BattleSkill.ts +++ b/ts/windows/Window_BattleSkill.ts @@ -6,12 +6,19 @@ import { Window_SkillList } from "./Window_SkillList"; // The window for selecting a skill to use on the battle screen. export class Window_BattleSkill extends Window_SkillList { - public constructor(x, y, width, height) { + public constructor(x: number, y: number, width: number, height: number) { super(x, y, width, height); this.hide(); } + public maxCols() { + return 1; + } + public show() { + const sprite = $gameActors.actor(this._actor.actorId()).battler(); + const scale = $gameScreen.zoomScale(); + this.move(sprite.x * scale - 300, sprite.y * scale, 300, 300); this.selectLast(); this.showHelpWindow(); super.show(); diff --git a/ts/windows/Window_BattleStatus.ts b/ts/windows/Window_BattleStatus.ts index f600d01..61e91fd 100644 --- a/ts/windows/Window_BattleStatus.ts +++ b/ts/windows/Window_BattleStatus.ts @@ -1,6 +1,8 @@ -import { Graphics } from "../core/Graphics"; -import { Window_Selectable } from "./Window_Selectable"; +import { BattleManager } from "../managers/BattleManager"; import { ConfigManager } from "../managers/ConfigManager"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; +import { Window_Base } from "./Window_Base"; +import { Window_Selectable } from "./Window_Selectable"; // ----------------------------------------------------------------------------- // Window_BattleStatus @@ -32,7 +34,7 @@ export class Window_BattleStatus extends Window_Selectable { } public numVisibleRows() { - return 4; + return Yanfly.Param.BECCommandRows; } public maxItems() { @@ -64,12 +66,16 @@ export class Window_BattleStatus extends Window_Selectable { } public gaugeAreaWidth() { - return 330; + return this.width / 2 + this.standardPadding(); } public drawBasicArea(rect, actor) { - this.drawActorName(actor, rect.x + 0, rect.y, 150); - this.drawActorIcons(actor, rect.x + 156, rect.y, rect.width - 156); + const minIconArea = Window_Base._iconWidth * 2; + const nameLength = this.textWidth("0") * 16 + 6; + const iconWidth = Math.max(rect.width - nameLength, minIconArea); + const nameWidth = rect.width - iconWidth; + this.drawActorName(actor, rect.x + 0, rect.y, nameWidth); + this.drawActorIcons(actor, rect.x + nameWidth, rect.y, iconWidth); } public drawGaugeArea(rect, actor) { @@ -81,13 +87,57 @@ export class Window_BattleStatus extends Window_Selectable { } public drawGaugeAreaWithTp(rect, actor) { - this.drawActorHp(actor, rect.x + 0, rect.y, 108); - this.drawActorMp(actor, rect.x + 123, rect.y, 96); - this.drawActorTp(actor, rect.x + 234, rect.y, 96); + const totalArea = this.gaugeAreaWidth() - 30; + const hpW = Math.floor((totalArea * 108) / 300); + const otW = Math.floor((totalArea * 96) / 300); + this.drawActorHp(actor, rect.x + 0, rect.y, hpW); + this.drawActorMp(actor, rect.x + hpW + 15, rect.y, otW); + this.drawActorTp(actor, rect.x + hpW + otW + 30, rect.y, otW); } public drawGaugeAreaWithoutTp(rect, actor) { - this.drawActorHp(actor, rect.x + 0, rect.y, 201); - this.drawActorMp(actor, rect.x + 216, rect.y, 114); + let totalArea = this.gaugeAreaWidth() - 15; + let hpW = Math.floor((totalArea * 201) / 315); + let otW = Math.floor((totalArea * 114) / 315); + this.drawActorHp(actor, rect.x + 0, rect.y, hpW); + this.drawActorMp(actor, rect.x + hpW + 15, rect.y, otW); + } + + public updateStatusRequests() { + if (BattleManager.isVictoryPhase()) return; + for (let i = 0; i < $gameParty.battleMembers().length; ++i) { + let actor = $gameParty.battleMembers()[i]; + if (!actor) continue; + if (actor.isStatusRefreshRequested()) this.processStatusRefresh(i); + } + } + + public processStatusRefresh(index) { + let actor = $gameParty.battleMembers()[index]; + if (!actor) return; + let rect = this.itemRect(index); + this.contents.clearRect(rect.x, rect.y, rect.width, rect.height); + this.drawItem(index); + actor.completetStatusRefreshRequest(); + } + + public drawCurrentAndMax(current, max, x, y, width, color1, color2) { + if (!Yanfly.Param.BECCurMax) { + const labelWidth = this.textWidth("HP"); + const valueWidth = this.textWidth(Yanfly.Util.toGroup(max)); + const slashWidth = this.textWidth("/"); + const x1 = x + width - valueWidth; + this.changeTextColor(color1); + this.drawText( + Yanfly.Util.toGroup(current), + x1, + y, + valueWidth, + undefined, + "right" + ); + } else { + super.drawCurrentAndMax(current, max, x, y, width, color1, color2); + } } } diff --git a/ts/windows/Window_Command.ts b/ts/windows/Window_Command.ts index 0843249..f3ad02b 100644 --- a/ts/windows/Window_Command.ts +++ b/ts/windows/Window_Command.ts @@ -1,5 +1,6 @@ import { Window_Message } from "./Window_Message"; import { Window_Selectable } from "./Window_Selectable"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; // ----------------------------------------------------------------------------- // Window_Command @@ -143,7 +144,7 @@ export class Window_Command extends Window_Selectable { } public itemTextAlign(): CanvasTextAlign { - return "left"; + return Yanfly.Param.TextAlign; } public isOkEnabled() { diff --git a/ts/windows/Window_EnemyVisualSelect.ts b/ts/windows/Window_EnemyVisualSelect.ts new file mode 100644 index 0000000..a537e8b --- /dev/null +++ b/ts/windows/Window_EnemyVisualSelect.ts @@ -0,0 +1,157 @@ +import { Window_Base } from "./Window_Base"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; +import { Graphics } from "../core/Graphics"; +import { SceneManager } from "../managers/SceneManager"; +import { Utils } from "../core/Utils"; +import { Scene_Battle } from "../scenes/Scene_Battle"; + +export class Window_EnemyVisualSelect extends Window_Base { + private _battler: any; + private _battlerName: string; + private _requestRefresh: boolean; + private _showSelectCursor: any; + private _showEnemyName: any; + private _nameTextWidth: any; + private _minX: number; + private _maxX: number; + private _minY: number; + private _maxY: number; + + public constructor() { + super(0, 0, 1, 1); + this._battler = null; + this._battlerName = ""; + this._requestRefresh = false; + this._showSelectCursor = Yanfly.Param.BECShowSelectBox; + this._showEnemyName = Yanfly.Param.BECShowEnemyName; + this.contentsOpacity = 0; + this.opacity = 0; + } + + public setBattler(battler) { + if (this._battler === battler) return; + this._battler = battler; + this._battlerName = battler.name(); + } + + public update() { + super.update(); + if (!this._battler) return; + this.updateWindowAspects(); + } + + public updateWindowAspects() { + this.updateBattlerName(); + this.updateWindowSize(); + this.updateWindowPosition(); + this.updateOpacity(); + this.updateRefresh(); + this.updateCursor(); + } + + public updateBattlerName() { + if (this._battlerName !== this._battler.name()) + this._battlerName = this._battler.name(); + this._requestRefresh = true; + this._nameTextWidth = undefined; + } + + public updateWindowSize() { + let spriteWidth = this._battler.spriteWidth(); + this.contents.fontSize = Yanfly.Param.BECEnemyFontSize; + if (this._nameTextWidth === undefined) { + this._nameTextWidth = this.textWidth(this._battler.name()); + } + let textWidth = this._nameTextWidth; + textWidth += this.textPadding() * 2; + let width = + Math.max(spriteWidth, textWidth) + this.standardPadding() * 2; + width = Math.ceil(width); + let height = this._battler.spriteHeight() + this.standardPadding() * 2; + height = Math.ceil(height); + height = Math.max( + height, + this.lineHeight() + this.standardPadding() * 2 + ); + if (width === this.width && height === this.height) return; + this.width = width; + this.height = height; + this.createContents(); + this._requestRefresh = true; + this.makeWindowBoundaries(); + } + + public makeWindowBoundaries() { + if (!this._requestRefresh) return; + this._minX = -1 * this.standardPadding(); + this._maxX = Graphics.boxWidth - this.width + this.standardPadding(); + this._minY = -1 * this.standardPadding(); + this._maxY = Graphics.boxHeight - this.height + this.standardPadding(); + this._maxY -= (SceneManager.scene as Scene_Battle).statusWindow.height; + } + + public updateWindowPosition() { + if (!this._battler) return; + this.x = (-1 * this.width) / 2; + this.y = -1 * this.height + this.standardPadding(); + this.x += this._battler.spritePosX(); + this.y += this._battler.spritePosY(); + this.x = Utils.clamp(this.x, this._minX, this._maxX); + this.y = Utils.clamp(this.y, this._minY, this._maxY); + } + + public updateOpacity() { + if (this.isShowWindow()) { + this.contentsOpacity += 32; + } else { + this.contentsOpacity -= 32; + } + } + + public isShowWindow() { + let scene = SceneManager.scene as Scene_Battle; + if (!scene.enemyWindow) return false; + let enemyWindow = scene.enemyWindow; + if (!enemyWindow.active) return false; + if (!this._battler.isAppeared()) return false; + if (this._battler.isDead()) { + return enemyWindow.selectDead; + } + return enemyWindow._enemies.includes(this._battler); + } + + public updateCursor() { + if (this.isShowCursor()) { + let wy = this.contents.height - this.lineHeight(); + this.setCursorRect(0, wy, this.contents.width, this.lineHeight()); + } else { + this.setCursorRect(0, 0, 0, 0); + } + } + + public isShowCursor() { + if (!this._showSelectCursor) return false; + let scene = SceneManager.scene as Scene_Battle; + if (!scene.enemyWindow) return false; + let enemyWindow = scene.enemyWindow; + if (!enemyWindow.active) return false; + if (!this._battler.isAppeared()) return false; + return this._battler.isSelected(); + } + + public updateRefresh() { + if (this._requestRefresh) this.refresh(); + } + + public refresh() { + this.contents.clear(); + if (!this._battler) return; + if (!this._showEnemyName) return; + if (this._battler.isHidden()) return; + this._requestRefresh = false; + this.contents.fontSize = Yanfly.Param.BECEnemyFontSize; + let text = this._battler.name(); + let wy = this.contents.height - this.lineHeight(); + this.drawText(text, 0, wy, this.contents.width, undefined, "center"); + } +} diff --git a/ts/windows/Window_EquipItem.ts b/ts/windows/Window_EquipItem.ts index f44f491..544ae84 100644 --- a/ts/windows/Window_EquipItem.ts +++ b/ts/windows/Window_EquipItem.ts @@ -62,10 +62,7 @@ export class Window_EquipItem extends Window_ItemList { public updateHelp() { super.updateHelp(); if (this._actor && this._statusWindow) { - const actor = new Game_Actor( - this._actor.actorId(), - JsonEx.makeDeepCopy(this._actor) as Game_Actor_OnLoad - ); + const actor = JsonEx.makeDeepCopy(this._actor); actor.forceChangeEquip(this._slotId, this.item()); this._statusWindow.setTempActor(actor); } diff --git a/ts/windows/Window_EquipStatus.ts b/ts/windows/Window_EquipStatus.ts index 4f561f5..a946514 100644 --- a/ts/windows/Window_EquipStatus.ts +++ b/ts/windows/Window_EquipStatus.ts @@ -1,5 +1,6 @@ import { TextManager } from "../managers/TextManager"; import { Window_Base } from "./Window_Base"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; // ----------------------------------------------------------------------------- // Window_EquipStatus @@ -76,7 +77,8 @@ export class Window_EquipStatus extends Window_Base { public drawCurrentParam(x, y, paramId) { this.resetTextColor(); - this.drawText(this._actor.param(paramId), x, y, 48, undefined, "right"); + const actorparam = Yanfly.Util.toGroup(this._actor.param(paramId)); + this.drawText(actorparam, x, y, 48, undefined, "right"); } public drawRightArrow(x, y) { @@ -87,7 +89,8 @@ export class Window_EquipStatus extends Window_Base { public drawNewParam(x, y, paramId) { const newValue = this._tempActor.param(paramId); const diffvalue = newValue - this._actor.param(paramId); + const actorparam = Yanfly.Util.toGroup(newValue); this.changeTextColor(this.paramchangeTextColor(diffvalue)); - this.drawText(newValue, x, y, 48, undefined, "right"); + this.drawText(actorparam, x, y, 48, undefined, "right"); } } diff --git a/ts/windows/Window_Help.ts b/ts/windows/Window_Help.ts index 61c4858..34761d6 100644 --- a/ts/windows/Window_Help.ts +++ b/ts/windows/Window_Help.ts @@ -1,5 +1,8 @@ import { Graphics } from "../core/Graphics"; import { Window_Base } from "./Window_Base"; +import { BattleManager } from "../managers/BattleManager"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; +import { Utils } from "../core/Utils"; // ----------------------------------------------------------------------------- // Window_Help @@ -25,6 +28,7 @@ export class Window_Help extends Window_Base { public clear() { this.setText(""); + this.contents.clear(); } public setItem(item) { @@ -35,4 +39,66 @@ export class Window_Help extends Window_Base { this.contents.clear(); this.drawTextEx(this._text, this.textPadding(), 0); } + + public setBattler(battler) { + this.contents.clear(); + this.clear(); + this.resetFontSettings(); + if (!$gameParty.inBattle()) return; + if (!battler) return; + let action = BattleManager.inputtingAction(); + if (this.specialSelectionText(action)) { + this.drawSpecialSelectionText(action); + } else { + this.drawBattler(battler); + } + } + + public specialSelectionText(action) { + BattleManager.resetSelection(); + if (!action) return false; + return !action.needsSelection(); + } + + public drawBattler(battler) { + let text = battler.name(); + let wx = 0; + let wy = (this.contents.height - this.lineHeight()) / 2; + this.drawText(text, wx, wy, this.contents.width, undefined, "center"); + } + + public drawSpecialSelectionText(action) { + let wx = 0; + let wy = (this.contents.height - this.lineHeight()) / 2; + let text = ""; + if (action.isForUser()) { + text = Yanfly.Param.BECHelpUserTx; + } else if (action.isForRandom()) { + BattleManager.startAllSelection(); + let fmt = Yanfly.Param.BECHelpRandTx; + let target = Yanfly.Param.BECHelpAllyTx; + if (action.isForOpponent() && action.numTargets() !== 1) { + target = Yanfly.Param.BECHelpEnemiesTx; + } else if (action.isForOpponent() && action.numTargets() === 1) { + target = Yanfly.Param.BECHelpEnemyTx; + } else if (action.isForFriend() && action.numTargets() !== 1) { + target = Yanfly.Param.BECHelpAlliesTx; + } + + text = Utils.format( + fmt, + target, + Yanfly.Util.toGroup(action.numTargets()) + ); + } else if (action.isForAll()) { + BattleManager.startAllSelection(); + let fmt = Yanfly.Param.BECHelpAllTx; + let target = Yanfly.Param.BECHelpAlliesTx; + if (action.isForOpponent()) { + target = Yanfly.Param.BECHelpEnemiesTx; + } + text = Utils.format(fmt, target); + } + this.drawText(text, wx, wy, this.contents.width, undefined, "center"); + } } diff --git a/ts/windows/Window_ItemList.ts b/ts/windows/Window_ItemList.ts index 8e9eea6..2f29744 100644 --- a/ts/windows/Window_ItemList.ts +++ b/ts/windows/Window_ItemList.ts @@ -1,6 +1,7 @@ import { Item } from "../interfaces/Item"; import { DataManager } from "../managers/DataManager"; import { Window_Selectable } from "./Window_Selectable"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; // ----------------------------------------------------------------------------- // Window_ItemList @@ -97,28 +98,15 @@ export class Window_ItemList extends Window_Selectable { } public numberWidth() { - return this.textWidth("000"); + return this.textWidth("\u00d70,000"); } public drawItemNumber(item, x, y, width) { - if (this.needsNumber()) { - this.drawText( - ":", - x, - y, - width - this.textWidth("00"), - undefined, - "right" - ); - this.drawText( - $gameParty.numItems(item).toString(), - x, - y, - width, - undefined, - "right" - ); - } + if (!this.needsNumber()) return; + let numItems = Yanfly.Util.toGroup($gameParty.numItems(item)); + this.contents.fontSize = Yanfly.Param.ItemQuantitySize; + this.drawText("\u00d7" + numItems, x, y, width, undefined, "right"); + this.resetFontSettings(); } public updateHelp() { diff --git a/ts/windows/Window_MenuStatus.ts b/ts/windows/Window_MenuStatus.ts index 676c5f0..0fb08af 100644 --- a/ts/windows/Window_MenuStatus.ts +++ b/ts/windows/Window_MenuStatus.ts @@ -2,6 +2,7 @@ import { Graphics } from "../core/Graphics"; import { ImageManager } from "../managers/ImageManager"; import { Window_Base } from "./Window_Base"; import { Window_Selectable } from "./Window_Selectable"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; // ----------------------------------------------------------------------------- // Window_MenuStatus @@ -77,12 +78,13 @@ export class Window_MenuStatus extends Window_Selectable { const actor = $gameParty.members()[index]; const rect = this.itemRect(index); this.changePaintOpacity(actor.isBattleMember()); + const fw = Window_Base._faceWidth; await this.drawActorFace( actor, rect.x + 1, rect.y + 1, - Window_Base._faceWidth, - Window_Base._faceHeight + fw, + rect.height - 2 ); this.changePaintOpacity(true); } @@ -90,8 +92,14 @@ export class Window_MenuStatus extends Window_Selectable { public async drawItemStatus(index) { const actor = $gameParty.members()[index]; const rect = this.itemRect(index); - const x = rect.x + 162; - const y = rect.y + rect.height / 2 - this.lineHeight() * 1.5; + const xpad = Yanfly.Param.WindowPadding + Window_Base._faceWidth; + const x = rect.x + xpad; + let y = 0; + if (!Yanfly.Param.MenuTpGauge) { + y = Math.floor(rect.y + rect.height / 2 - this.lineHeight() * 1.5); + } else { + y = Math.floor(rect.y); + } const width = rect.width - x - this.textPadding(); await this.drawActorSimpleStatus(actor, x, y, width); } diff --git a/ts/windows/Window_Message.ts b/ts/windows/Window_Message.ts index afb3241..d6f1ac6 100644 --- a/ts/windows/Window_Message.ts +++ b/ts/windows/Window_Message.ts @@ -32,13 +32,6 @@ export class Window_Message extends Window_Base { private _pauseSkip: boolean; private _textSpeed: number; private _textSpeedCount: number; - wordwrapWidth: () => any; - adjustWindowSettings: () => void; - isFastForward: () => boolean; - convertNameBox: (text: any) => any; - convertMessageCharacters: (text: any) => any; - convertActorFace: (actor: any) => string; - hasDifferentNameBoxText: () => boolean; public constructor() { const width = Window_Message.prototype.windowWidth(); @@ -80,7 +73,7 @@ export class Window_Message extends Window_Base { } public windowWidth() { - return Graphics.boxWidth; + return Window_Message.maxWidthOfWindow; } public windowHeight() { diff --git a/ts/windows/Window_NameEdit.ts b/ts/windows/Window_NameEdit.ts index 5103938..b748f0c 100644 --- a/ts/windows/Window_NameEdit.ts +++ b/ts/windows/Window_NameEdit.ts @@ -75,7 +75,7 @@ export class Window_NameEdit extends Window_Base { } public faceWidth() { - return 144; + return Window_Base._faceWidth; } public charWidth() { diff --git a/ts/windows/Window_PartyCommand.ts b/ts/windows/Window_PartyCommand.ts index e1e80c1..48383d4 100644 --- a/ts/windows/Window_PartyCommand.ts +++ b/ts/windows/Window_PartyCommand.ts @@ -2,6 +2,7 @@ import { Graphics } from "../core/Graphics"; import { BattleManager } from "../managers/BattleManager"; import { TextManager } from "../managers/TextManager"; import { Window_Command } from "./Window_Command"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; // ----------------------------------------------------------------------------- // Window_PartyCommand @@ -25,7 +26,11 @@ export class Window_PartyCommand extends Window_Command { } public numVisibleRows() { - return 4; + return Yanfly.Param.BECCommandRows; + } + + public itemTextAlign() { + return Yanfly.Param.BECCommandAlign; } public makeCommandList() { diff --git a/ts/windows/Window_Selectable.ts b/ts/windows/Window_Selectable.ts index eadc7b2..fe3b5bf 100644 --- a/ts/windows/Window_Selectable.ts +++ b/ts/windows/Window_Selectable.ts @@ -2,8 +2,10 @@ import { Input } from "../core/Input"; import { Rectangle } from "../core/Rectangle"; import { TouchInput } from "../core/TouchInput"; import { Utils } from "../core/Utils"; +import { Item } from "../interfaces/Item"; import { SoundManager } from "../managers/SoundManager"; import { Window_Base } from "./Window_Base"; +import { Window_Help } from "./Window_Help"; // ----------------------------------------------------------------------------- // Window_Selectable @@ -12,14 +14,15 @@ import { Window_Base } from "./Window_Base"; export class Window_Selectable extends Window_Base { protected _index: number; - private _cursorFixed: boolean; - private _cursorAll: boolean; - private _stayCount: number; - private _helpWindow: any; - private _handlers: {}; - private _touching: boolean; - private _scrollX: number; - private _scrollY: number; + protected _cursorFixed: boolean; + protected _cursorAll: boolean; + protected _stayCount: number; + protected _helpWindow: any; + protected _handlers: {}; + protected _touching: boolean; + protected _scrollX: number; + protected _scrollY: number; + protected _inputLock: any; public constructor(x: number, y: number, width: number, height: number) { super(x, y, width, height); @@ -177,9 +180,7 @@ export class Window_Selectable extends Window_Base { return rect; } - public setHelpWindow( - helpWindow: import("../../../../Projects/Dragon Slayers/ts/windows/Window_Help").Window_Help - ) { + public setHelpWindow(helpWindow: Window_Help) { this._helpWindow = helpWindow; this.callUpdateHelp(); } @@ -215,6 +216,7 @@ export class Window_Selectable extends Window_Base { } public isCursorMovable() { + if (this._inputLock) return false; return ( this.isOpenAndActive() && !this._cursorFixed && @@ -563,9 +565,7 @@ export class Window_Selectable extends Window_Base { this._helpWindow.clear(); } - public setHelpWindowItem( - item: import("../../../../Projects/Dragon Slayers/ts/interfaces/Item").Item - ) { + public setHelpWindowItem(item: Item) { if (this._helpWindow) { this._helpWindow.setItem(item); } diff --git a/ts/windows/Window_ShopBuy.ts b/ts/windows/Window_ShopBuy.ts index 6bf88ac..3516076 100644 --- a/ts/windows/Window_ShopBuy.ts +++ b/ts/windows/Window_ShopBuy.ts @@ -1,4 +1,5 @@ import { Window_Selectable } from "./Window_Selectable"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; // ----------------------------------------------------------------------------- // Window_ShopBuy @@ -89,8 +90,10 @@ export class Window_ShopBuy extends Window_Selectable { rect.width -= this.textPadding(); this.changePaintOpacity(this.isEnabled(item)); await this.drawItemName(item, rect.x, rect.y, rect.width - priceWidth); + this.contents.fontSize = Yanfly.Param.GoldFontSize; + const itemPrice = Yanfly.Util.toGroup(this.price(item)); await this.drawText( - this.price(item), + itemPrice, rect.x + rect.width - priceWidth, rect.y, priceWidth, @@ -98,6 +101,7 @@ export class Window_ShopBuy extends Window_Selectable { "right" ); this.changePaintOpacity(true); + this.resetFontSettings(); } public setStatusWindow(statusWindow) { diff --git a/ts/windows/Window_ShopNumber.ts b/ts/windows/Window_ShopNumber.ts index 0556f45..16f98de 100644 --- a/ts/windows/Window_ShopNumber.ts +++ b/ts/windows/Window_ShopNumber.ts @@ -6,6 +6,7 @@ import { SoundManager } from "../managers/SoundManager"; import { TextManager } from "../managers/TextManager"; import { Sprite_Button } from "../sprites/Sprite_Button"; import { Window_Selectable } from "./Window_Selectable"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; // ----------------------------------------------------------------------------- // Window_ShopNumber @@ -135,14 +136,8 @@ export class Window_ShopNumber extends Window_Selectable { const y = this.itemY(); const width = this.cursorWidth() - this.textPadding(); this.resetTextColor(); - await this.drawText( - this._number.toString(), - x, - y, - width, - undefined, - "right" - ); + const itemNumber = Yanfly.Util.toGroup(this._number); + await this.drawText(itemNumber, x, y, width, undefined, "right"); } public async drawTotalPrice() { diff --git a/ts/windows/Window_SkillList.ts b/ts/windows/Window_SkillList.ts index 229fb8b..89e395c 100644 --- a/ts/windows/Window_SkillList.ts +++ b/ts/windows/Window_SkillList.ts @@ -1,4 +1,6 @@ import { Window_Selectable } from "./Window_Selectable"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; +import { Game_Actor } from "../objects/Game_Actor"; // ----------------------------------------------------------------------------- // Window_SkillList @@ -6,18 +8,18 @@ import { Window_Selectable } from "./Window_Selectable"; // The window for selecting a skill on the skill screen. export class Window_SkillList extends Window_Selectable { - public _actor: any; + public _actor: Game_Actor; public _stypeId: number; public _data: any[]; - public constructor(x, y, width, height) { + public constructor(x: number, y: number, width: number, height: number) { super(x, y, width, height); this._actor = null; this._stypeId = 0; this._data = []; } - public setActor(actor) { + public setActor(actor: Game_Actor) { if (this._actor !== actor) { this._actor = actor; this.refresh(); @@ -25,7 +27,7 @@ export class Window_SkillList extends Window_Selectable { } } - public setStypeId(stypeId) { + public setStypeId(stypeId: number) { if (this._stypeId !== stypeId) { this._stypeId = stypeId; this.refresh(); @@ -34,7 +36,7 @@ export class Window_SkillList extends Window_Selectable { } public maxCols() { - return 2; + return 3; } public spacing() { @@ -55,17 +57,17 @@ export class Window_SkillList extends Window_Selectable { return this.isEnabled(this._data[this.index()]); } - public includes(item) { + public includes(item: { stypeId: number }) { return item && item.stypeId === this._stypeId; } - public isEnabled(item) { + public isEnabled(item: any) { return this._actor && this._actor.canUse(item); } public makeItemList() { if (this._actor) { - this._data = this._actor.skills().filter(function(item) { + this._data = this._actor.skills().filter(function(item: any) { return this.includes(item); }, this); } else { @@ -74,7 +76,7 @@ export class Window_SkillList extends Window_Selectable { } public selectLast() { - let skill; + let skill: any; if ($gameParty.inBattle()) { skill = this._actor.lastBattleSkill(); } else { @@ -84,20 +86,15 @@ export class Window_SkillList extends Window_Selectable { this.select(index >= 0 ? index : 0); } - public async drawItem(index) { + public async drawItem(index: number) { const skill = this._data[index]; if (skill) { const costWidth = this.costWidth(); const rect = this.itemRect(index); rect.width -= this.textPadding(); this.changePaintOpacity(this.isEnabled(skill)); - await this.drawItemName( - skill, - rect.x, - rect.y, - rect.width - costWidth - ); - await this.drawSkillCost(skill, rect.x, rect.y, rect.width); + this.drawItemName(skill, rect.x, rect.y, rect.width - costWidth); + this.drawSkillCost(skill, rect.x, rect.y, rect.width); this.changePaintOpacity(1); } } @@ -106,27 +103,19 @@ export class Window_SkillList extends Window_Selectable { return this.textWidth("000"); } - public drawSkillCost(skill, x, y, width) { + public drawSkillCost(skill: any, x: number, y: number, width: number) { if (this._actor.skillTpCost(skill) > 0) { this.changeTextColor(this.tpCostColor()); - this.drawText( - this._actor.skillTpCost(skill), - x, - y, - width, - undefined, - "right" + const skillcost = Yanfly.Util.toGroup( + this._actor.skillTpCost(skill) ); + this.drawText(skillcost, x, y, width, undefined, "right"); } else if (this._actor.skillMpCost(skill) > 0) { this.changeTextColor(this.mpCostColor()); - this.drawText( - this._actor.skillMpCost(skill), - x, - y, - width, - undefined, - "right" + const skillcost = Yanfly.Util.toGroup( + this._actor.skillMpCost(skill) ); + this.drawText(skillcost, x, y, width, undefined, "right"); } } diff --git a/ts/windows/Window_SkillStatus.ts b/ts/windows/Window_SkillStatus.ts index 5219382..17faed0 100644 --- a/ts/windows/Window_SkillStatus.ts +++ b/ts/windows/Window_SkillStatus.ts @@ -1,4 +1,5 @@ import { Window_Base } from "./Window_Base"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; // ----------------------------------------------------------------------------- // Window_SkillStatus @@ -20,15 +21,27 @@ export class Window_SkillStatus extends Window_Base { } } - public refresh() { + public async refresh() { this.contents.clear(); if (this._actor) { const w = this.width - this.padding * 2; const h = this.height - this.padding * 2; - const y = h / 2 - this.lineHeight() * 1.5; - const width = w - 162 - this.textPadding(); - this.drawActorFace(this._actor, 0, 0, 144, h); - this.drawActorSimpleStatus(this._actor, 162, y, width); + let y = 0; + if (!Yanfly.Param.MenuTpGauge) { + y = h / 2 - this.lineHeight() * 1.5; + } else { + y = 0; + } + const xpad = Yanfly.Param.WindowPadding + Window_Base._faceWidth; + const width = w - xpad - this.textPadding(); + await this.drawActorFace( + this._actor, + 0, + 0, + Window_Base._faceWidth, + h + ); + await this.drawActorSimpleStatus(this._actor, xpad, y, width); } } } diff --git a/ts/windows/Window_SkillType.ts b/ts/windows/Window_SkillType.ts index 80a039a..57e23f4 100644 --- a/ts/windows/Window_SkillType.ts +++ b/ts/windows/Window_SkillType.ts @@ -37,7 +37,7 @@ export class Window_SkillType extends Window_Command { return a - b; }); skillTypes.forEach(function(stypeId) { - const name = $dataSystem.skillTypes[stypeId]; + var name = $dataSystem.skillTypes[stypeId]; this.addCommand(name, "skill", true, stypeId); }, this); } diff --git a/ts/windows/Window_Status.ts b/ts/windows/Window_Status.ts index c368f14..cbd1986 100644 --- a/ts/windows/Window_Status.ts +++ b/ts/windows/Window_Status.ts @@ -4,6 +4,7 @@ import { TextManager } from "../managers/TextManager"; import { Game_Actor } from "../objects/Game_Actor"; import { Window_Selectable } from "./Window_Selectable"; import { Item } from "../interfaces/Item"; +import { Yanfly } from "../plugins/Stronk_YEP_CoreEngine"; // ----------------------------------------------------------------------------- // Window_Status @@ -99,15 +100,12 @@ export class Window_Status extends Window_Selectable { this.drawText(TextManager.param(paramId), x, y2, 160) ); this.resetTextColor(); + const actorParam = Yanfly.Util.toGroup(this._actor.param(paramId)); + const dw = this.textWidth( + Yanfly.Util.toGroup(this._actor.paramMax(i + 2)) + ); promises.push( - this.drawText( - this._actor.param(paramId).toString(), - x + 160, - y2, - 60, - undefined, - "right" - ) + this.drawText(actorParam, x + 160, y2, dw, undefined, "right") ); } await Promise.all(promises); @@ -117,14 +115,21 @@ export class Window_Status extends Window_Selectable { const lineHeight = this.lineHeight(); const expTotal = Utils.format(TextManager.expTotal, TextManager.exp); const expNext = Utils.format(TextManager.expNext, TextManager.level); - let value1 = this._actor.currentExp(); - let value2 = this._actor.nextRequiredExp(); + let value1: string = this._actor.currentExp().toString(); + let value2: string = this._actor.nextRequiredExp().toString(); this.changeTextColor(this.systemColor()); + if (this._actor.isMaxLevel()) { + value1 = "-------"; + value2 = "-------"; + } else { + value1 = Yanfly.Util.toGroup(value1); + value2 = Yanfly.Util.toGroup(value2); + } await this.drawText(expTotal, x, y + lineHeight * 0, 270); await this.drawText(expNext, x, y + lineHeight * 2, 270); this.resetTextColor(); await this.drawText( - this._actor.isMaxLevel() ? "-------" : value1.toString(), + value1, x, y + lineHeight * 1, 270, @@ -132,7 +137,7 @@ export class Window_Status extends Window_Selectable { "right" ); await this.drawText( - this._actor.isMaxLevel() ? "-------" : value2.toString(), + value2, x, y + lineHeight * 3, 270, diff --git a/tsconfig.json b/tsconfig.json index edfe4f7..80294a9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,9 +8,10 @@ "moduleResolution": "node", "sourceMap": true, "outDir": "js", - "allowJs": false + "allowJs": false, + "removeComments": false }, "include": ["./**/*"], - "exclude": ["./ts/plugins.ts"], + "exclude": [], "files": ["./ts/globals.d.ts"] }