Guest User

QMovement Mod

a guest
May 29th, 2025
41
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 132.66 KB | None | 0 0
  1. //=============================================================================
  2. // QMovement
  3. //=============================================================================
  4.  
  5. var Imported = Imported || {};
  6.  
  7. if (!Imported.QPlus || !QPlus.versionCheck(Imported.QPlus, '1.6.0')) {
  8. alert('Error: QMovement requires QPlus 1.6.0 or newer to work.');
  9. throw new Error('Error: QMovement requires QPlus 1.6.0 or newer to work.');
  10. }
  11.  
  12. Imported.QMovement = '1.6.3';
  13.  
  14. //=============================================================================
  15. /*:
  16. * @plugindesc <QMovement>
  17. * More control over character movement
  18. * @version 1.6.3
  19. * @author Quxios | Version 1.6.3
  20. * @site https://quxios.github.io/
  21. * @updateurl https://quxios.github.io/data/pluginsMin.json
  22. *
  23. * @repo https://github.com/quxios/QMovement
  24. *
  25. * @requires QPlus
  26. *
  27. * @video TODO
  28. *
  29. * @param Main Settings
  30. *
  31. * @param Grid
  32. * @parent Main Settings
  33. * @desc The amount of pixels you want to move per Movement.
  34. * Plugin Default: 1 MV Default: 48
  35. * @type Number
  36. * @min 1
  37. * @default 1
  38. *
  39. * @param Tile Size
  40. * @parent Main Settings
  41. * @desc Size of tiles in pixels
  42. * Default: 48
  43. * @type Number
  44. * @min 1
  45. * @default 48
  46. *
  47. * @param Off Grid
  48. * @parent Main Settings
  49. * @desc Allow characters to move off grid?
  50. * @type boolean
  51. * @on Yes
  52. * @off No
  53. * @default true
  54. *
  55. * @param Optional Settings
  56. *
  57. * @param Smart Move
  58. * @parent Optional Settings
  59. * @desc If the move didn't succeed, try again at lower speeds or at
  60. * a different direction
  61. * @type select
  62. * @option Disabled
  63. * @value 0
  64. * @option Adjust Speed
  65. * @value 1
  66. * @option Adjust Direction
  67. * @value 2
  68. * @option Adjust Speed and Direction
  69. * @value 3
  70. * @default 2
  71. *
  72. * @param Mid Pass
  73. * @parent Optional Settings
  74. * @desc An extra collision check for the midpoint of the Movement.
  75. * @type boolean
  76. * @on Enable
  77. * @off Disable
  78. * @default false
  79. *
  80. * @param Move on click
  81. * @parent Optional Settings
  82. * @desc Set if player moves with mouse click
  83. * * Requires QPathfind to work
  84. * @type boolean
  85. * @on Enable
  86. * @off Disable
  87. * @default true
  88. *
  89. * @param Diagonal
  90. * @parent Optional Settings
  91. * @desc Allow for diagonal movement?
  92. * @type boolean
  93. * @on Yes
  94. * @off No
  95. * @default true
  96. *
  97. * @param Diagonal Speed
  98. * @parent Optional Settings
  99. * @desc Adjust the speed when moving diagonal.
  100. * Default: 0 TODO not functional
  101. * @type Number
  102. * @min 0
  103. * @default 0
  104. *
  105. * @param Colliders
  106. *
  107. * @param Player Collider
  108. * @text Default Player Collider
  109. * @parent Colliders
  110. * @desc Default collider for the player.
  111. * @type Struct<Collider>
  112. * @default {"Type":"box","Width":"36","Height":"24","Offset X":"6","Offset Y":"24"}
  113. *
  114. * @param Event Collider
  115. * @text Default Event Collider
  116. * @parent Colliders
  117. * @desc Default collider for events.
  118. * @type Struct<Collider>
  119. * @default {"Type":"box","Width":"36","Height":"24","Offset X":"6","Offset Y":"24"}
  120. *
  121. * @param Presets
  122. * @parent Colliders
  123. * @desc List of preset colliders that you can assign to
  124. * events
  125. * @type Struct<ColliderPreset>[]
  126. * @default []
  127. *
  128. * @param Debug Settings
  129. *
  130. * @param Show Colliders
  131. * @parent Debug Settings
  132. * @desc Show the Box Colliders by default during testing.
  133. * -Can be toggled on/off with F10 during play test
  134. * @type boolean
  135. * @on Show by default
  136. * @off Hide by default
  137. * @default true
  138. *
  139. * @help
  140. * ============================================================================
  141. * ## About
  142. * ============================================================================
  143. * This plugin completely rewrites the collision system to use colliders. Using
  144. * colliders enabled more accurate collision checking with dealing with pixel
  145. * movement. This plugin also lets you change how many pixels the characters
  146. * move per step, letting you set up a 24x24 movement or a 1x1 (pixel movement)
  147. *
  148. * Note there are a few mv features disabled/broken; mouse movement, followers,
  149. * and vehicles.
  150. * ============================================================================
  151. * ## Setting up
  152. * ============================================================================
  153. * To setup a pixel based movement, you'll need to change the plugin parameters
  154. * to something like:
  155. *
  156. * - Grid = 1
  157. * - Off Grid = true
  158. * - Mid Pass = false
  159. *
  160. * Other parameters can be set to your preference.
  161. *
  162. * For a grid based movement, set it something like:
  163. *
  164. * - Grid = GRIDSIZE YOU WANT
  165. * - Off Grid = false
  166. * - Mid Pass = true
  167. *
  168. * When in grid based movement, you want your colliders to fill up most of the
  169. * grid size but with a padding of 4 pixels on all sides (this is because some
  170. * tile colliders are 4 tiles wide or tall). So if your grid size was 48, your
  171. * colliders shouldn't be 48x48, instead they should be 40x40, with an ox and oy
  172. * of 4. So your collider setting would look like: box, 40, 40, 4, 4
  173. * ============================================================================
  174. * ## Colliders
  175. * ============================================================================
  176. * There are 3 types of colliders; Polygon, Box and Circle. Though you can only
  177. * create box and circle colliders, unless you modify the code to accept
  178. * polygons. This is intentional since polygon would be "harder" to setup.
  179. *
  180. * ![Colliders Image](https://quxios.github.io/imgs/qmovement/colliders.png)
  181. *
  182. * - Boxes takes in width, height, offset x and offset y
  183. * - Circles similar to boxes, takes in width, height, offset x and offset y
  184. * ----------------------------------------------------------------------------
  185. * **Setting up colliders**
  186. * ----------------------------------------------------------------------------
  187. * Colliders are setup inside the Players notebox or as a comment inside an
  188. * Events page. Events colliders depends it's page, so you may need to make the
  189. * collider on all pages.
  190. *
  191. * There are two ways to setup colliders. using `<collider:-,-,-,->` and using
  192. * `<colliders>-</colliders>`. The first method sets the 'Default' collider for
  193. * that character. The second one you create the colliders for every collider
  194. * type.
  195. * ----------------------------------------------------------------------------
  196. * **Collider Types**
  197. * ----------------------------------------------------------------------------
  198. * There are 3 collider types. Default, Collision and Interaction.
  199. * - Default: This is the collider to use if collider type that was called was
  200. * not found
  201. * - Collision: This collider is used for collision checking
  202. * - Interaction: This collider is used for checking interaction.
  203. * ----------------------------------------------------------------------------
  204. * **Collider Presets**
  205. * ----------------------------------------------------------------------------
  206. * You can create colliders in the plugin parameters which you can use when
  207. * setting up other colliders.
  208. * ----------------------------------------------------------------------------
  209. * **Collider Terms**
  210. * ----------------------------------------------------------------------------
  211. * ![Colliders Terms Image](https://quxios.github.io/imgs/qmovement/colliderInfo.png)
  212. * ----------------------------------------------------------------------------
  213. * **Collider Notetag**
  214. * ----------------------------------------------------------------------------
  215. * ~~~
  216. * <collider: [SHAPE], [WIDTH], [HEIGHT], [OX], [OY]>
  217. * ~~~
  218. * This notetag sets all collider types to these values.
  219. * - SHAPE: Set to box, circle or poly
  220. * - If poly read next section on poly shape
  221. * - WIDTH: The width of the collider, in pixels
  222. * - HEIGHT: The height of the collider, in pixels
  223. * - OX: The X Offset of the collider, in pixels
  224. * - OY: The Y Offset of the collider, in pixels
  225. * ----------------------------------------------------------------------------
  226. * **Colliders Notetag**
  227. * ----------------------------------------------------------------------------
  228. * ~~~
  229. * <colliders>
  230. * [TYPE]: [SHAPE], [WIDTH], [HEIGHT], [OX], [OY]
  231. * </colliders>
  232. * ~~~
  233. * This notetag sets all collider types to these values.
  234. * - TYPE: The type of collider, set to default, collision or interaction
  235. * - SHAPE: Set to box, circle or poly
  236. * - If poly read next section on poly shape
  237. * - WIDTH: The width of the collider, in pixels
  238. * - HEIGHT: The height of the collider, in pixels
  239. * - OX: The X Offset of the collider, in pixels
  240. * - OY: The Y Offset of the collider, in pixels
  241. *
  242. * To add another type, just add `type: shape, width, height, ox, oy` on
  243. * another line.
  244. *
  245. * Example:
  246. * ~~~
  247. * <colliders>
  248. * default: box, 48, 48
  249. * collision: circle, 24, 24, 12, 12
  250. * interaction: box, 32, 32, 8, 8
  251. * </colliders>
  252. * ~~~
  253. * ----------------------------------------------------------------------------
  254. * **Using Preset**
  255. * ----------------------------------------------------------------------------
  256. * To use a collider preset in the notetag, the format is:
  257. * ~~~
  258. * preset, [PRESETID]
  259. * ~~~
  260. * - PRESETID: The PresetID you set in the preset parameter.
  261. *
  262. * You will use this format instead of the: `SHAPE, WIDTH, HEIGHT, OX, OY`
  263. *
  264. * Example:
  265. * ~~~
  266. * <collider: preset, largeCollider>
  267. * ~~~
  268. * Will look for the preset with the ID `largeCollider`
  269. *
  270. * Example 2:
  271. * ~~~
  272. * <colliders>
  273. * default: preset, largeDefault
  274. * collision: preset, largeCollider
  275. * interaction: preset, largeInteraction
  276. * </colliders>
  277. * ~~~
  278. * Will use the presets; `largeDefault`, `largeCollider`, and `largeInteraction`
  279. * ----------------------------------------------------------------------------
  280. * **Poly Colliders**
  281. * ----------------------------------------------------------------------------
  282. * To create a polygon collider, set the shape to poly. After that the rest
  283. * of the line should be a list of points separated with a comma. Points are
  284. * written as "(X,Y)". An example polygon would be:
  285. * ~~~
  286. * poly,(24,0),(48,24),(24,48),(0,24)
  287. * ~~~
  288. * Would create a diamond shaped polygon.
  289. *
  290. * Example of using it inside a collider tag
  291. * ~~~
  292. * <collider:poly,(24,0),(48,24),(24,48),(0,24)>
  293. * ~~~
  294. * ============================================================================
  295. * ## Move Routes
  296. * ============================================================================
  297. * By default, event move commands (moveup, movedown, ect) will convert to a
  298. * qmove that moves the character based off your tilesize. So if your tilesize
  299. * is 48 and your gridsize is 1. Then a moveup command will move the character
  300. * up 48 pixels not 1. But if you want to move the character by a fixed amount
  301. * of pixels, then you will use the QMove commands.
  302. * ----------------------------------------------------------------------------
  303. * **QMove**
  304. * ----------------------------------------------------------------------------
  305. * ![QMove Script Call](https://quxios.github.io/imgs/qmovement/qmove.png)
  306. *
  307. * To do a QMove, add a script in the move route in the format:
  308. * ~~~
  309. * qmove(DIR, AMOUNT, MULTIPLER)
  310. * ~~~
  311. * - DIR: Set to a number representing the direction to move;
  312. * - 4: left, 6: right, 8: up 2: down,
  313. * - 1: lower left, 3: lower right, 7: upper left, 9: upper right,
  314. * - 5: current direction, 0: reverse direction
  315. * - AMOUNT: The amount to move in that direction, in pixels
  316. * - MULTIPLIER: multiplies against amount to make larger values easier [OPTIONAL]
  317. *
  318. * Example:
  319. * ~~~
  320. * qmove(4, 24)
  321. * ~~~
  322. * Will move that character 24 pixels to the left.
  323. * ----------------------------------------------------------------------------
  324. * **Arc**
  325. * ----------------------------------------------------------------------------
  326. * Arcing is used to make a character orbit around a position. Note that collisions
  327. * are ignored when arcing, but interactions still work. To add a arc add a script
  328. * in the move route in the format:
  329. * ~~~
  330. * arc(PIVOTX, PIVOTY, RADIAN, CCWISE?, FRAMES)
  331. * ~~~
  332. * - PIVOTX: The x position to orbit around, in pixels
  333. * - PIVOTY: The y position to orbit around, in pixels
  334. * - RADIAN: The degrees to move, in radians
  335. * - CCWISE?: set to true or false; if true it will arc countclock wise
  336. * - FRAMES: The amount of frames to complete the arc
  337. *
  338. * Example:
  339. * ~~~
  340. * arc(480,480,Math.PI*2,false,60)
  341. * ~~~
  342. * Will make the character do a full 360 arc clockwise around the point 480, 480
  343. * and it'll take 60 frames.
  344. * ============================================================================
  345. * ## Event Notetags/Comments
  346. * ============================================================================
  347. * **Offsets**
  348. * ----------------------------------------------------------------------------
  349. * To shift an events initial starting position, you can use the following
  350. * note tags:
  351. * ~~~
  352. * <ox:X>
  353. * ~~~
  354. * or
  355. * ~~~
  356. * <oy:X>
  357. * ~~~
  358. * Where X is the number of pixels to shift the event. Can be negative.
  359. * ----------------------------------------------------------------------------
  360. * **SmartDir**
  361. * ----------------------------------------------------------------------------
  362. * By default, when the player collides with an event it won't trigger the
  363. * Smart Move Dir effect. To enable this, add following notetag to the event:
  364. * ~~~
  365. * <smartDir>
  366. * ~~~
  367. * ----------------------------------------------------------------------------
  368. * **IgnoreCharas**
  369. * ----------------------------------------------------------------------------
  370. * You can have an event ignore certain characters when collision checking. This
  371. * allows you to let some events move through some events or the player. Note that
  372. * this is not 2 ways, so if an event can move through the player, that doesn't
  373. * mean the player can move through the event.
  374. * ~~~
  375. * <ignoreCharas:CHARAIDS>
  376. * ~~~
  377. * Where CHARAIDS is a list of character Ids, separated by a comma
  378. * ============================================================================
  379. * ## Map Notetags
  380. * ============================================================================
  381. * **GridSize**
  382. * ----------------------------------------------------------------------------
  383. * You can set the grid size for certain maps by using the notetag:
  384. * ~~~
  385. * <grid:X>
  386. * ~~~
  387. * Where X is the grid size to use for this map.
  388. * ----------------------------------------------------------------------------
  389. * **OffGrid**
  390. * ----------------------------------------------------------------------------
  391. * You can set weither you can or can't move off the grid for certain maps by
  392. * using the notetag:
  393. * ~~~
  394. * <offGrid:BOOL>
  395. * ~~~
  396. * Where BOOL is true or false
  397. * ----------------------------------------------------------------------------
  398. * **MidPass**
  399. * ----------------------------------------------------------------------------
  400. * You can set weither you want to use the mid pass function for certain maps by
  401. * using the notetag:
  402. * ~~~
  403. * <midPass:BOOL>
  404. * ~~~
  405. * Where BOOL is true or false
  406. * ============================================================================
  407. * ## Plugin Commands
  408. * ============================================================================
  409. * **Transfer**
  410. * ----------------------------------------------------------------------------
  411. * MV event transfers are grid based. So this plugin command lets you map transfer
  412. * to a pixel x / y position.
  413. * ~~~
  414. * qMovement transfer [MAPID] [X] [Y] [OPTIONS]
  415. * ~~~
  416. * - MAPID: The id of the map to transfer to
  417. * - X: The x position to transfer to, in pixels
  418. * - Y: The y position to transfer to, in pixels
  419. *
  420. * Possible options:
  421. *
  422. * - dirX: Set X to the dir to face after the transfer.
  423. * - Can be 2, 4, 6, 8, or for diagonals 1, 3, 7, 9
  424. * - fadeBlack: Will fade black when transfering
  425. * - fadeWhite: Will fade white when transfering
  426. *
  427. * Example:
  428. * ~~~
  429. * qMovement transfer 1 100 116 dir2 fadeBlack
  430. * ~~~
  431. * Will transfer the player to map 1 at x100, y116. There will be a black fade
  432. * and player will be facing down
  433. * ~~~
  434. * qMovement transfer 1 100 116
  435. * ~~~
  436. * Will transfer the player to map 1 at x100, y116. There will be no fade and
  437. * players direction won't change
  438. * ----------------------------------------------------------------------------
  439. * **Set Pos**
  440. * ----------------------------------------------------------------------------
  441. * This command will let you move a character to a x / y pixel position. Note
  442. * this will not "walk" the character to that position! This will place the
  443. * character at this position, similar to a transfer.
  444. * ~~~
  445. * qMovement setPos [CHARAID] [X] [Y] [OPTIONS]
  446. * ~~~
  447. * - CHARAID: The character identifier.
  448. * - For player: 0, p, or player
  449. * - For events: EVENTID, eEVENTID, eventEVENTID or this for the event that called this (replace EVENTID with a number)
  450. * - X: The x position to set to, in pixels
  451. * - Y: The y position to set to, in pixels
  452. *
  453. * Possible options:
  454. *
  455. * - dirX: Set X to the dir to face after the transfer.
  456. * - Can be 2, 4, 6, 8, or for diagonals 1, 3, 7, 9
  457. *
  458. * ----------------------------------------------------------------------------
  459. * **Change Collider**
  460. * ----------------------------------------------------------------------------
  461. * This command will let you change a collider for a character. Note that you
  462. * should use this carefully. If you don't you can get that character stuck.
  463. * ~~~
  464. * qMovement changeCollider [CHARAID] [TYPE] [SHAPE] [WIDTH] [HEIGHT] [OX] [OY]
  465. * ~~~
  466. * - CHARAID: The character identifier.
  467. * - For player: 0, p, or player
  468. * - For events: EVENTID, eEVENTID, eventEVENTID or this for the event that called this (replace EVENTID with a number)
  469. * - TYPE: The type of collider, set to default, collision or interaction
  470. * - SHAPE: Set to box or circle
  471. * - WIDTH: The width of the collider, in pixels
  472. * - HEIGHT: The height of the collider, in pixels
  473. * - OX: The X Offset of the collider, in pixels
  474. * - OY: The Y Offset of the collider, in pixels
  475. *
  476. * You can also set it to a preset by using the format:
  477. * ~~~
  478. * qMovement changeCollider [CHARAID] [TYPE] preset [PRESETID]
  479. * ~~~
  480. * - CHARAID: The character identifier.
  481. * - For player: 0, p, or player
  482. * - For events: EVENTID, eEVENTID, eventEVENTID or this for the event that called this (replace EVENTID with a number)
  483. * - TYPE: The type of collider, set to default, collision or interaction
  484. * - PRESETID: The PresetID you set in the preset parameter.
  485. * ============================================================================
  486. * ## Tips
  487. * ============================================================================
  488. * **No closed open spaces!**
  489. * ----------------------------------------------------------------------------
  490. * For performance reasons, you should try to avoid having open spaces that are
  491. * closed off.
  492. *
  493. * ![Example](https://quxios.github.io/imgs/qmovement/openSpaces.png)
  494. *
  495. * On the left we can see some tiles that have a collider border, but their inside
  496. * is "open". This issue is should be corrected when using QPathfind because
  497. * if someone was to click inside that "open" space, it is passable and QPathfind
  498. * will try to find a way in even though there is no way in and will cause massive
  499. * lag. The fix can be pretty simple, you could add a CollisionMap (though that
  500. * may be another issue in its own) or add a RegionCollider to fill up the full
  501. * tile like I did on the correct side of that image.
  502. * ----------------------------------------------------------------------------
  503. * **Collision Maps - Heavy**
  504. * ----------------------------------------------------------------------------
  505. * Try to use collision maps only if you absolutely need to. Collision maps
  506. * can be very large images which will make your game use more memory and can
  507. * cause some slower pcs to start lagging. The collision checking for collision
  508. * maps are also take about 2-4x more time to compute and is a lot less accurate
  509. * since it only checks if the colliders edge collided with the collision map.
  510. * So using collision maps, might be pretty, but use it with caution as it can
  511. * slow down your game! A better solution for this would be to use a PolygonMap
  512. * where you create polygon colliders and add them into the map.
  513. * ============================================================================
  514. * ## Addons
  515. * ============================================================================
  516. * **Pathfind**
  517. * ----------------------------------------------------------------------------
  518. * https://quxios.github.io/plugins/QPathfind
  519. *
  520. * QPathfind is an A* pathfinding algorithm. This algorithm can be pretty heavy
  521. * if you are doing pixel based movements. So avoid having to many pathfinders
  522. * running at the same time.
  523. *
  524. * For the interval settings, you want to set this to a value where the path
  525. * can be found in 1-3 frames. You can think of intervals as the number of
  526. * moves to try per frame. The default setting 100, is good for grid based
  527. * since that will take you 100 grid spaces away. But for a pixel based, 100
  528. * steps might not be as far. If most of your pathfinds will be short (paths less then
  529. * 10 tiles away), then you should set this to a value between 100-300. For medium
  530. * paths (10-20 tiles away) try a value between 300-700. For large or complicated
  531. * paths (20+ tiles away or lots of obsticles) try something between 1000-2000.
  532. * I would avoid going over 2000. My opinion is to keep it below 1000, and simplify
  533. * any of your larger paths by either splitting it into multiple pathfinds or
  534. * just making the path less complex.
  535. *
  536. * ----------------------------------------------------------------------------
  537. * **Collision Map**
  538. * ----------------------------------------------------------------------------
  539. * https://quxios.github.io/plugins/QM+CollisionMap
  540. *
  541. * Collision Map is an addon for this plugin that lets you use images for
  542. * collisions. Note that collision map checks are a lot heavier then normal
  543. * collision checks. So this plugin can make your game laggier if used with
  544. * other heavy plugins.
  545. *
  546. * ----------------------------------------------------------------------------
  547. * **Region Colliders**
  548. * ----------------------------------------------------------------------------
  549. * https://quxios.github.io/plugins/QM+RegionColliders
  550. *
  551. * Region Colliders is an addon for this plugin that lets you add colliders
  552. * to regions by creating a json file.
  553. * ============================================================================
  554. * ## Showcase
  555. * ============================================================================
  556. * This section is for user created stuff. If you created a video, game, tutorial,
  557. * or an addon for QMovement feel free to send me a link and I'll showcase it here!
  558. * ----------------------------------------------------------------------------
  559. * **Videos**
  560. * ----------------------------------------------------------------------------
  561. * Great example of using the collision map addon:
  562. *
  563. * https://www.youtube.com/watch?v=-BN4Pyr5IBo
  564. *
  565. * ============================================================================
  566. * ## Links
  567. * ============================================================================
  568. * Formated Help:
  569. *
  570. * https://quxios.github.io/plugins/QMovement
  571. *
  572. * RPGMakerWebs:
  573. *
  574. * http://forums.rpgmakerweb.com/index.php?threads/qplugins.73023/
  575. *
  576. * Terms of use:
  577. *
  578. * https://github.com/quxios/QMV-Master-Demo/blob/master/readme.md
  579. *
  580. * Like my plugins? Support me on Patreon!
  581. *
  582. * https://www.patreon.com/quxios
  583. *
  584. * @tags movement, pixel, character
  585. */
  586. /*~struct~Collider:
  587. * @param Type
  588. * @desc Set to box or circle
  589. * @type select
  590. * @option Box
  591. * @value box
  592. * @option Circle
  593. * @value circle
  594. * @default box
  595. *
  596. * @param Width
  597. * @desc Set to the width of the collider.
  598. * @type Number
  599. * @default 36
  600. *
  601. * @param Height
  602. * @desc Set to the height of the collider.
  603. * @type Number
  604. * @default 24
  605. *
  606. * @param Offset X
  607. * @desc Set to the x offset of the collider.
  608. * @type Number
  609. * @min -9999
  610. * @default 6
  611. *
  612. * @param Offset Y
  613. * @desc Set to the y offset of the collider.
  614. * @type Number
  615. * @min -9999
  616. * @default 24
  617. */
  618. /*~struct~ColliderPreset:
  619. * @param ID
  620. * @desc The ID of this preset, needs to be unique!
  621. * @default
  622. *
  623. * @param Type
  624. * @desc Set to box or circle
  625. * @type select
  626. * @option Box
  627. * @value box
  628. * @option Circle
  629. * @value circle
  630. * @default box
  631. *
  632. * @param Width
  633. * @desc Set to the width of the collider.
  634. * @type Number
  635. * @default 36
  636. *
  637. * @param Height
  638. * @desc Set to the height of the collider.
  639. * @type Number
  640. * @default 24
  641. *
  642. * @param Offset X
  643. * @desc Set to the x offset of the collider.
  644. * @type Number
  645. * @default 6
  646. *
  647. * @param Offset Y
  648. * @desc Set to the y offset of the collider.
  649. * @type Number
  650. * @default 24
  651. */
  652. //=============================================================================
  653. //=============================================================================
  654. // QMovement Static Class
  655.  
  656. function QMovement() {
  657. throw new Error('This is a static class');
  658. }
  659.  
  660. (function() {
  661. var _PARAMS = QPlus.getParams('<QMovement>', {
  662. 'Player Collider': {
  663. "Type": "box", "Width": 36,"Height":24 ,"Offset X": 6,"Offset Y": 24
  664. },
  665. 'Event Collider': {
  666. "Type": "box", "Width": 36,"Height":24 ,"Offset X": 6,"Offset Y": 24
  667. },
  668. 'Presets': []
  669. });
  670.  
  671. QMovement.grid = _PARAMS['Grid'];
  672. QMovement.tileSize = _PARAMS['Tile Size'];
  673. QMovement.offGrid = _PARAMS['Off Grid'];
  674. QMovement.smartMove = _PARAMS['Smart Move'];
  675. QMovement.midPass = _PARAMS['Mid Pass'];
  676. QMovement.moveOnClick = _PARAMS['Move on click'];
  677. QMovement.diagonal = _PARAMS['Diagonal'];
  678. QMovement.collision = '#FF0000'; // will be changable in a separate addon
  679. QMovement.water1 = '#00FF00'; // will be changable in a separate addon
  680. QMovement.water2 = '#0000FF'; // will be changable in a separate addon
  681. QMovement.water1Tag = 1; // will be changable in a separate addon
  682. QMovement.water2Tag = 2; // will be changable in a separate addon
  683. QMovement.playerCollider = convertColliderStruct(_PARAMS['Player Collider']);
  684. QMovement.eventCollider = convertColliderStruct(_PARAMS['Event Collider']);
  685. QMovement.presets = {};
  686. _PARAMS['Presets'].forEach(function(preset) {
  687. QMovement.presets[preset.ID] = convertColliderStruct(preset);
  688. });
  689. QMovement.showColliders = _PARAMS['Show Colliders'];
  690. QMovement.tileBoxes = {
  691. 1537: [48, 6, 0, 42],
  692. 1538: [6, 48],
  693. 1539: [[48, 6, 0, 42], [6, 48]],
  694. 1540: [6, 48, 42],
  695. 1541: [[48, 6, 0, 42], [6, 48, 42]],
  696. 1542: [[6, 48], [6, 48, 42]],
  697. 1543: [[48, 6, 0, 42], [6, 48], [6, 48, 42]],
  698. 1544: [48, 6],
  699. 1545: [[48, 6], [48, 6, 0, 42]],
  700. 1546: [[48, 6], [6, 48]],
  701. 1547: [[48, 6], [48, 6, 0, 42], [6, 48]],
  702. 1548: [[48, 6], [6, 48, 42]],
  703. 1549: [[48, 6], [48, 6, 0, 42], [6, 48, 42]],
  704. 1550: [[48, 6], [6, 48], [6, 48, 42]],
  705. 1551: [48, 48], // Impassable A5, B
  706. 2063: [48, 48], // Impassable A1
  707. 2575: [48, 48],
  708. 3586: [6, 48],
  709. 3588: [6, 48, 42],
  710. 3590: [[6, 48], [6, 48, 42]],
  711. 3592: [48, 6],
  712. 3594: [[48, 6], [6, 48]],
  713. 3596: [[48, 6], [6, 48, 42]],
  714. 3598: [[48, 6], [6, 48], [6, 48, 42]],
  715. 3599: [48, 48], // Impassable A2, A3, A4
  716. 3727: [48, 48]
  717. };
  718. var rs = QMovement.tileSize / 48;
  719. for (var key in QMovement.tileBoxes) {
  720. if (QMovement.tileBoxes.hasOwnProperty(key)) {
  721. for (var i = 0; i < QMovement.tileBoxes[key].length; i++) {
  722. if (QMovement.tileBoxes[key][i].constructor === Array) {
  723. for (var j = 0; j < QMovement.tileBoxes[key][i].length; j++) {
  724. QMovement.tileBoxes[key][i][j] *= rs;
  725. }
  726. } else {
  727. QMovement.tileBoxes[key][i] *= rs;
  728. }
  729. }
  730. }
  731. }
  732. // following will be changable in a separate addon
  733. QMovement.regionColliders = {};
  734. QMovement.colliderMap = {};
  735.  
  736. function convertColliderStruct(struct) {
  737. return [
  738. struct.Type,
  739. struct.Width,
  740. struct.Height,
  741. struct['Offset X'],
  742. struct['Offset Y']
  743. ]
  744. }
  745. })();
  746.  
  747. //=============================================================================
  748. // Colliders
  749.  
  750. //-----------------------------------------------------------------------------
  751. // Polygon_Collider
  752.  
  753. function Polygon_Collider() {
  754. this.initialize.apply(this, arguments);
  755. }
  756.  
  757. (function() {
  758. Polygon_Collider._counter = 0;
  759.  
  760. Polygon_Collider.prototype.initialize = function(points) {
  761. var args = [];
  762. for (var i = 1; i < arguments.length; i++) {
  763. args.push(arguments[i]);
  764. }
  765. this.initMembers.apply(this, args);
  766. this.makeVertices(points);
  767. };
  768.  
  769. Polygon_Collider.prototype.initMembers = function(x, y) {
  770. x = x !== undefined ? x : 0;
  771. y = y !== undefined ? y : 0;
  772. this._position = new Point(x, y);
  773. this._scale = new Point(1, 1);
  774. this._offset = new Point(0, 0);
  775. this._pivot = new Point(0, 0);
  776. this._radian = 0;
  777. this._note = '';
  778. this.meta = {};
  779. this.id = Polygon_Collider._counter++;
  780. };
  781.  
  782. Object.defineProperty(Polygon_Collider.prototype, 'note', {
  783. get() {
  784. return this._note;
  785. },
  786. set(note) {
  787. this._note = note;
  788. this.meta = QPlus.getMeta(note);
  789. }
  790. });
  791.  
  792. Object.defineProperty(Polygon_Collider.prototype, 'x', {
  793. get() {
  794. return this._position.x;
  795. },
  796. set(x) {
  797. this._position.x = x;
  798. }
  799. });
  800.  
  801. Object.defineProperty(Polygon_Collider.prototype, 'y', {
  802. get() {
  803. return this._position.y;
  804. },
  805. set(y) {
  806. this._position.y = y;
  807. }
  808. });
  809.  
  810. Object.defineProperty(Polygon_Collider.prototype, 'ox', {
  811. get() {
  812. return this._offset.x + this._pivot.x;
  813. },
  814. set(value) {
  815. this._offset.x = value;
  816. this.refreshVertices();
  817. }
  818. });
  819.  
  820. Object.defineProperty(Polygon_Collider.prototype, 'oy', {
  821. get() {
  822. return this._offset.y + this._pivot.y;
  823. },
  824. set(value) {
  825. this._offset.y = value - this._pivot.y;
  826. this.refreshVertices();
  827. }
  828. });
  829.  
  830. Polygon_Collider.prototype.isPolygon = function() {
  831. return true;
  832. };
  833.  
  834. Polygon_Collider.prototype.isBox = function() {
  835. return true;
  836. };
  837.  
  838. Polygon_Collider.prototype.isCircle = function() {
  839. return false;
  840. };
  841.  
  842. Polygon_Collider.prototype.makeVertices = function(points) {
  843. this._vertices = [];
  844. this._baseVertices = [];
  845. this._edges = [];
  846. this._vectors = [];
  847. this._xMin = null;
  848. this._xMax = null;
  849. this._yMin = null;
  850. this._yMax = null;
  851. for (var i = 0; i < points.length; i++) {
  852. var x = points[i].x - this._pivot.x;
  853. var y = points[i].y - this._pivot.y;
  854. var x2 = x + this.x + this.ox;
  855. var y2 = y + this.y + this.oy;
  856. this._vertices.push(new Point(x2, y2));
  857. this._baseVertices.push(new Point(x, y));
  858. if (i !== 0) {
  859. var prev = this._vertices[i - 1];
  860. this._edges.push({
  861. x1: prev.x, x2: x2,
  862. y1: prev.y, y2: y2
  863. })
  864. }
  865. if (i === points.length - 1) {
  866. var first = this._vertices[0];
  867. this._edges.push({
  868. x1: x2, x2: first.x,
  869. y1: y2, y2: first.y
  870. })
  871. }
  872. var radian = Math.atan2(y, x);
  873. radian += radian < 0 ? Math.PI * 2 : 0;
  874. var dist = Math.sqrt(x * x + y * y);
  875. this._vectors.push({ radian, dist });
  876. if (this._xMin === null || this._xMin > x) {
  877. this._xMin = x;
  878. }
  879. if (this._xMax === null || this._xMax < x) {
  880. this._xMax = x;
  881. }
  882. if (this._yMin === null || this._yMin > y) {
  883. this._yMin = y;
  884. }
  885. if (this._yMax === null || this._yMax < y) {
  886. this._yMax = y;
  887. }
  888. }
  889. this.width = Math.abs(this._xMax - this._xMin);
  890. this.height = Math.abs(this._yMax - this._yMin);
  891. var x1 = this._xMin + this.x + this.ox;
  892. var y1 = this._yMin + this.y + this.oy;
  893. this.center = new Point(x1 + this.width / 2, y1 + this.height / 2);
  894. };
  895.  
  896. Polygon_Collider.prototype.makeVectors = function() {
  897. this._vectors = this._baseVertices.map((function(vertex) {
  898. var dx = vertex.x - this._pivot.x;
  899. var dy = vertex.y - this._pivot.y;
  900. var radian = Math.atan2(dy, dx);
  901. radian += radian < 0 ? Math.PI * 2 : 0;
  902. var dist = Math.sqrt(dx * dx + dy * dy);
  903. return { radian, dist };
  904. }).bind(this));
  905. };
  906.  
  907. Polygon_Collider.prototype.setBounds = function() {
  908. this._xMin = null;
  909. this._xMax = null;
  910. this._yMin = null;
  911. this._yMax = null;
  912. for (var i = 0; i < this._baseVertices.length; i++) {
  913. var x = this._baseVertices[i].x;
  914. var y = this._baseVertices[i].y;
  915. if (this._xMin === null || this._xMin > x) {
  916. this._xMin = x;
  917. }
  918. if (this._xMax === null || this._xMax < x) {
  919. this._xMax = x;
  920. }
  921. if (this._yMin === null || this._yMin > y) {
  922. this._yMin = y;
  923. }
  924. if (this._yMax === null || this._yMax < y) {
  925. this._yMax = y;
  926. }
  927. }
  928. this.width = Math.abs(this._xMax - this._xMin);
  929. this.height = Math.abs(this._yMax - this._yMin);
  930. var x1 = this._xMin + this.x + this.ox;
  931. var y1 = this._yMin + this.y + this.oy;
  932. this.center = new Point(x1 + this.width / 2, y1 + this.height / 2);
  933. };
  934.  
  935. Polygon_Collider.prototype.refreshVertices = function() {
  936. this._edges = [];
  937. var i, j;
  938. for (i = 0, j = this._vertices.length; i < j; i++) {
  939. var vertex = this._vertices[i];
  940. vertex.x = this.x + this._baseVertices[i].x + this.ox;
  941. vertex.y = this.y + this._baseVertices[i].y + this.oy;
  942. if (i !== 0) {
  943. var prev = this._vertices[i - 1];
  944. this._edges.push({
  945. x1: prev.x, x2: vertex.x,
  946. y1: prev.y, y2: vertex.y
  947. })
  948. }
  949. if (i === j - 1) {
  950. var first = this._vertices[0];
  951. this._edges.push({
  952. x1: vertex.x, x2: first.x,
  953. y1: vertex.y, y2: first.y
  954. })
  955. }
  956. }
  957. this.setBounds();
  958. };
  959.  
  960. Polygon_Collider.prototype.sectorEdge = function() {
  961. var x1 = this._xMin + this.x + this.ox;
  962. var x2 = this._xMax + this.x + this.ox - 1;
  963. var y1 = this._yMin + this.y + this.oy;
  964. var y2 = this._yMax + this.y + this.oy - 1;
  965. x1 = Math.floor(x1 / ColliderManager._sectorSize);
  966. x2 = Math.floor(x2 / ColliderManager._sectorSize);
  967. y1 = Math.floor(y1 / ColliderManager._sectorSize);
  968. y2 = Math.floor(y2 / ColliderManager._sectorSize);
  969. return {
  970. x1: x1, x2: x2,
  971. y1: y1, y2: y2
  972. }
  973. };
  974.  
  975. Polygon_Collider.prototype.gridEdge = function() {
  976. var x1 = this._xMin + this.x + this.ox;
  977. var x2 = this._xMax + this.x + this.ox - 1;
  978. var y1 = this._yMin + this.y + this.oy;
  979. var y2 = this._yMax + this.y + this.oy - 1;
  980. x1 = Math.floor(x1 / QMovement.tileSize);
  981. x2 = Math.floor(x2 / QMovement.tileSize);
  982. y1 = Math.floor(y1 / QMovement.tileSize);
  983. y2 = Math.floor(y2 / QMovement.tileSize);
  984. return {
  985. x1: x1, x2: x2,
  986. y1: y1, y2: y2
  987. }
  988. };
  989.  
  990. Polygon_Collider.prototype.edge = function() {
  991. var x1 = this._xMin + this.x + this.ox;
  992. var x2 = this._xMax + this.x + this.ox - 1;
  993. var y1 = this._yMin + this.y + this.oy;
  994. var y2 = this._yMax + this.y + this.oy - 1;
  995. return {
  996. x1: x1, x2: x2,
  997. y1: y1, y2: y2
  998. }
  999. };
  1000.  
  1001. Polygon_Collider.prototype.setPivot = function(x, y) {
  1002. this._pivot.x = x;
  1003. this._pivot.y = y;
  1004. this.makeVectors();
  1005. this.rotate(0); // Resets base vertices
  1006. };
  1007.  
  1008. Polygon_Collider.prototype.centerPivot = function() {
  1009. this._pivot.x = this.width / 2;
  1010. this._pivot.y = this.height / 2;
  1011. this.makeVectors();
  1012. this.rotate(0); // Resets base vertices
  1013. };
  1014.  
  1015. Polygon_Collider.prototype.setRadian = function(radian) {
  1016. radian = radian !== undefined ? radian : 0;
  1017. this.rotate(radian - this._radian);
  1018. };
  1019.  
  1020. Polygon_Collider.prototype.rotate = function(radian) {
  1021. this._radian += radian;
  1022. for (var i = 0; i < this._vectors.length; i++) {
  1023. var vector = this._vectors[i];
  1024. vector.radian += radian;
  1025. var x = vector.dist * Math.cos(vector.radian);
  1026. var y = vector.dist * Math.sin(vector.radian);
  1027. this._baseVertices[i].x = Math.round(x);
  1028. this._baseVertices[i].y = Math.round(y);
  1029. }
  1030. this.refreshVertices();
  1031. };
  1032.  
  1033. Polygon_Collider.prototype.setScale = function(zX, zY) {
  1034. zX = zX !== undefined ? zX : 1;
  1035. zY = zY !== undefined ? zY : 1;
  1036. this.scale(zX / this._scale.x, zY / this._scale.y);
  1037. };
  1038.  
  1039. Polygon_Collider.prototype.scale = function(zX, zY) {
  1040. this._scale.x *= zX;
  1041. this._scale.y *= zY;
  1042. for (var i = 0; i < this._vectors.length; i++) {
  1043. var vector = this._vectors[i];
  1044. var x = vector.dist * Math.cos(vector.radian);
  1045. var y = vector.dist * Math.sin(vector.radian);
  1046. x *= zX;
  1047. y *= zY;
  1048. vector.radian = Math.atan2(y, x);
  1049. vector.radian += vector.radian < 0 ? Math.PI * 2 : 0;
  1050. vector.dist = Math.sqrt(x * x + y * y);
  1051. this._baseVertices[i].x = Math.round(x);
  1052. this._baseVertices[i].y = Math.round(y);
  1053. }
  1054. this.refreshVertices();
  1055. };
  1056.  
  1057. Polygon_Collider.prototype.moveTo = function(x, y) {
  1058. if (x !== this.x || y !== this.y) {
  1059. this.x = x;
  1060. this.y = y;
  1061. this.refreshVertices();
  1062. }
  1063. };
  1064.  
  1065. Polygon_Collider.prototype.intersects = function(other) {
  1066. if (this.height === 0 || this.width === 0) return false;
  1067. if (other.height === 0 || other.width === 0) return false;
  1068. if (!other.isPolygon()) {
  1069. if (this.containsPoint(other.center.x, other.center.y)) return true;
  1070. }
  1071. if (!this.isPolygon()) {
  1072. if (other.containsPoint(this.center.x, this.center.y)) return true;
  1073. }
  1074. var i, j, x, y;
  1075. for (i = 0, j = other._vertices.length; i < j; i++) {
  1076. x = other._vertices[i].x;
  1077. y = other._vertices[i].y;
  1078. if (this.containsPoint(x, y)) return true;
  1079. }
  1080. for (i = 0, j = this._vertices.length; i < j; i++) {
  1081. x = this._vertices[i].x;
  1082. y = this._vertices[i].y;
  1083. if (other.containsPoint(x, y)) return true;
  1084. }
  1085. // TODO add edge checking
  1086. /*
  1087. for (i = 0; i < this._edges.length; i++) {
  1088. for (j = 0; j < other._edges.length; j++) {
  1089.  
  1090. }
  1091. }*/
  1092. return false;
  1093. };
  1094.  
  1095. Polygon_Collider.prototype.inside = function(other) {
  1096. if (this.height === 0 || this.width === 0) return false;
  1097. if (other.height === 0 || other.width === 0) return false;
  1098. var i, j, x, y;
  1099. for (i = 0, j = other._vertices.length; i < j; i++) {
  1100. x = other._vertices[i].x;
  1101. y = other._vertices[i].y;
  1102. if (!this.containsPoint(x, y)) {
  1103. return false;
  1104. }
  1105. }
  1106. return true;
  1107. };
  1108.  
  1109. Polygon_Collider.prototype.containsPoint = function(x, y) {
  1110. var i;
  1111. var j = this._vertices.length - 1;
  1112. var odd = false;
  1113. var poly = this._vertices;
  1114. for (i = 0; i < this._vertices.length; i++) {
  1115. if (poly[i].y < y && poly[j].y >= y || poly[j].y < y && poly[i].y >= y) {
  1116. if (poly[i].x + (y - poly[i].y) / (poly[j].y - poly[i].y) * (poly[j].x - poly[i].x) < x) {
  1117. odd = !odd;
  1118. }
  1119. }
  1120. j = i;
  1121. }
  1122. return odd;
  1123. };
  1124.  
  1125. Polygon_Collider.prototype.lineIntersection = function(lineA, lineB) {
  1126. var a1 = lineA.y1 - lineA.y2;
  1127. var b1 = lineA.x2 - lineA.x1;
  1128. var a2 = lineB.y1 - lineB.y2;
  1129. var b2 = lineB.x2 - lineB.x1;
  1130. var det = a1 * b2 - a2 * b1;
  1131. if (det == 0) {
  1132. return false;
  1133. }
  1134. var c1 = a1 * lineA.x1 + b1 * lineA.y1;
  1135. var c2 = a2 * lineB.x1 + b2 * lineB.y1;
  1136. var x = (b2 * c1 - b1 * c2) / det;
  1137. var y = (a1 * c2 - a2 * c1) / det;
  1138. // incomplete
  1139. // returns false if lines don't intersect
  1140. // x/y will return where or when they will intersect
  1141. return new Point(x, y);
  1142. };
  1143.  
  1144. // TODO Optimize this
  1145. // Compaire other methods, example atan2 - atan2 or a dot product
  1146. Polygon_Collider.prototype.bestPairFrom = function(point) {
  1147. var vertices = this._vertices;
  1148. var radians = [];
  1149. var points = [];
  1150. for (var i = 0; i < vertices.length; i++) {
  1151. var radian = Math.atan2(vertices[i].y - point.y, vertices[i].x - point.x);
  1152. radian += radian < 0 ? 2 * Math.PI : 0;
  1153. radians.push(radian);
  1154. points.push(new Point(vertices[i].x, vertices[i].y));
  1155. }
  1156. var bestPair = [];
  1157. var currI = 0;
  1158. var max = -Math.PI * 2;
  1159. while (points.length > 0) {
  1160. var curr = points.shift();
  1161. for (var i = 0; i < points.length; i++) {
  1162. var dr = radians[currI] - radians[currI + i + 1];
  1163. if (Math.abs(dr) > max) {
  1164. max = Math.abs(dr);
  1165. bestPair = [currI, currI + i + 1];
  1166. }
  1167. }
  1168. currI++;
  1169. }
  1170. return bestPair;
  1171. };
  1172.  
  1173. // returns a new polygon
  1174. Polygon_Collider.prototype.stretchedPoly = function(radian, dist) {
  1175. var dist2 = dist + Math.max(this.width, this.height);
  1176. var xComponent = Math.cos(radian) * dist;
  1177. var yComponent = Math.sin(radian) * dist;
  1178. var x1 = this.center.x + Math.cos(radian) * dist2;
  1179. var y1 = this.center.y + Math.sin(radian) * dist2;
  1180. var bestPair = this.bestPairFrom(new Point(x1, y1));
  1181. var vertices = this._vertices;
  1182. var pointsA = [];
  1183. var pointsB = [];
  1184. var i;
  1185. for (i = 0; i < vertices.length; i++) {
  1186. var x2 = vertices[i].x - this.x;
  1187. var y2 = vertices[i].y - this.y;
  1188. pointsA.push(new Point(x2, y2));
  1189. pointsB.push(new Point(x2 + xComponent, y2 + yComponent));
  1190. }
  1191. // TODO add the other vertices from collider
  1192. var points = [];
  1193. points.push(pointsA[bestPair[0]]);
  1194. points.push(pointsB[bestPair[0]]);
  1195. points.push(pointsB[bestPair[1]]);
  1196. points.push(pointsA[bestPair[1]]);
  1197. return new Polygon_Collider(points, this.x, this.y);
  1198. };
  1199. })();
  1200.  
  1201. //-----------------------------------------------------------------------------
  1202. // Box_Collider
  1203.  
  1204. function Box_Collider() {
  1205. this.initialize.apply(this, arguments);
  1206. }
  1207.  
  1208. (function() {
  1209. Box_Collider.prototype = Object.create(Polygon_Collider.prototype);
  1210. Box_Collider.prototype.constructor = Box_Collider;
  1211.  
  1212. Box_Collider.prototype.initialize = function(width, height, ox, oy, options) {
  1213. var points = [
  1214. new Point(0, 0),
  1215. new Point(width, 0),
  1216. new Point(width, height),
  1217. new Point(0, height)
  1218. ];
  1219. Polygon_Collider.prototype.initialize.call(this, points, width, height, ox, oy, options);
  1220. };
  1221.  
  1222. Box_Collider.prototype.initMembers = function(width, height, ox, oy, options) {
  1223. Polygon_Collider.prototype.initMembers.call(this, 0, 0);
  1224. ox = ox === undefined ? 0 : ox;
  1225. oy = oy === undefined ? 0 : oy;
  1226. options = options === undefined ? {} : options;
  1227. this._offset = new Point(ox, oy);
  1228. this._pivot = options.pivot || new Point(width / 2, height / 2);
  1229. this._scale = options.scale || this._scale;
  1230. this._radian = options.radian || this._radian;
  1231. this._position = options.position || this._position;
  1232. };
  1233.  
  1234. Box_Collider.prototype.isPolygon = function() {
  1235. return false;
  1236. };
  1237.  
  1238. Box_Collider.prototype.isBox = function() {
  1239. return true;
  1240. };
  1241.  
  1242. Box_Collider.prototype.containsPoint = function(x, y) {
  1243. if (this._radian === 0) {
  1244. var xMin = this._xMin + this.x + this.ox;
  1245. var xMax = this._xMax + this.x + this.ox;
  1246. var yMin = this._yMin + this.y + this.oy;
  1247. var yMax = this._yMax + this.y + this.oy;
  1248. var insideX = x >= xMin && x <= xMax;
  1249. var insideY = y >= yMin && y <= yMax;
  1250. return insideX && insideY;
  1251. } else {
  1252. return Polygon_Collider.prototype.containsPoint.call(this, x, y);
  1253. }
  1254. };
  1255.  
  1256. })();
  1257.  
  1258. //-----------------------------------------------------------------------------
  1259. // Circle_Collider
  1260.  
  1261. function Circle_Collider() {
  1262. this.initialize.apply(this, arguments);
  1263. }
  1264.  
  1265. (function() {
  1266. Circle_Collider.prototype = Object.create(Polygon_Collider.prototype);
  1267. Circle_Collider.prototype.constructor = Circle_Collider;
  1268.  
  1269. Circle_Collider.prototype.initialize = function(width, height, ox, oy, options) {
  1270. this._radius = new Point(width / 2, height / 2);
  1271. var points = [];
  1272. for (var i = 7; i >= 0; i--) {
  1273. var rad = Math.PI / 4 * i + Math.PI;
  1274. var x = this._radius.x + this._radius.x * Math.cos(rad);
  1275. var y = this._radius.y + this._radius.y * -Math.sin(rad);
  1276. points.push(new Point(x, y));
  1277. }
  1278. Polygon_Collider.prototype.initialize.call(this, points, width, height, ox, oy, options);
  1279. };
  1280.  
  1281. Circle_Collider.prototype.initMembers = Box_Collider.prototype.initMembers;
  1282.  
  1283. Object.defineProperty(Circle_Collider.prototype, 'radiusX', {
  1284. get() {
  1285. return this._radius.x;
  1286. }
  1287. });
  1288.  
  1289. Object.defineProperty(Circle_Collider.prototype, 'radiusY', {
  1290. get() {
  1291. return this._radius.y;
  1292. }
  1293. });
  1294.  
  1295. Circle_Collider.prototype.isPolygon = function() {
  1296. return false;
  1297. };
  1298.  
  1299. Circle_Collider.prototype.isCircle = function() {
  1300. return true;
  1301. };
  1302.  
  1303. Circle_Collider.prototype.scale = function(zX, zY) {
  1304. Polygon_Collider.prototype.scale.call(this, zX, zY);
  1305. this._radius.x *= zX;
  1306. this._radius.y *= zY;
  1307. };
  1308.  
  1309. Circle_Collider.prototype.circlePosition = function(radian) {
  1310. var x = this.radiusX * Math.cos(radian);
  1311. var y = this.radiusY * -Math.sin(radian);
  1312. var dist = Math.sqrt(x * x + y * y);
  1313. radian -= this._radian;
  1314. x = dist * Math.cos(radian);
  1315. y = dist * -Math.sin(radian);
  1316. return new Point(this.center.x + x, this.center.y + y);
  1317. };
  1318.  
  1319. Circle_Collider.prototype.intersects = function(other) {
  1320. if (this.height === 0 || this.width === 0) return false;
  1321. if (other.height === 0 || other.width === 0) return false;
  1322. if (this.containsPoint(other.center.x, other.center.y)) return true;
  1323. if (other.containsPoint(this.center.x, this.center.y)) return true;
  1324. var x1 = this.center.x;
  1325. var x2 = other.center.x;
  1326. var y1 = this.center.y;
  1327. var y2 = other.center.y;
  1328. var rad = Math.atan2(y1 - y2, x2 - x1);
  1329. rad += rad < 0 ? 2 * Math.PI : 0;
  1330. var pos = this.circlePosition(rad);
  1331. if (other.containsPoint(pos.x, pos.y)) return true;
  1332. if (other.isCircle()) {
  1333. rad = Math.atan2(y2 - y1, x1 - x2);
  1334. rad += rad < 0 ? 2 * Math.PI : 0;
  1335. pos = other.circlePosition(rad);
  1336. if (this.containsPoint(pos.x, pos.y)) return true;
  1337. }
  1338. var i, j;
  1339. for (i = 0, j = other._vertices.length; i < j; i++) {
  1340. x1 = other._vertices[i].x;
  1341. y1 = other._vertices[i].y;
  1342. if (this.containsPoint(x1, y1)) return true;
  1343. }
  1344. for (i = 0, j = this._vertices.length; i < j; i++) {
  1345. x1 = this._vertices[i].x;
  1346. y1 = this._vertices[i].y;
  1347. if (other.containsPoint(x1, y1)) return true;
  1348. }
  1349. return false;
  1350. };
  1351. })();
  1352.  
  1353. //-----------------------------------------------------------------------------
  1354. // ColliderManager
  1355.  
  1356. function ColliderManager() {
  1357. throw new Error('This is a static class');
  1358. }
  1359.  
  1360. (function() {
  1361. ColliderManager._colliders = [];
  1362. ColliderManager._colliderGrid = [];
  1363. ColliderManager._characterGrid = [];
  1364. ColliderManager._sectorSize = QMovement.tileSize;
  1365. ColliderManager._needsRefresh = true;
  1366. ColliderManager.container = new Sprite();
  1367. ColliderManager.container.alpha = 0.3;
  1368. ColliderManager.containerDict = {};
  1369. ColliderManager.visible = QMovement.showColliders;
  1370.  
  1371. ColliderManager.clear = function() {
  1372. this._colliders = [];
  1373. this._colliderGrid = [];
  1374. this._characterGrid = [];
  1375. this.container.removeChildren();
  1376. this.containerDict = {};
  1377. };
  1378.  
  1379. ColliderManager.refresh = function() {
  1380. this.clear();
  1381. this._colliderGrid = new Array(this._mapWidth);
  1382. for (var x = 0; x < this._colliderGrid.length; x++) {
  1383. this._colliderGrid[x] = [];
  1384. for (var y = 0; y < this._mapHeight; y++) {
  1385. this._colliderGrid[x].push([]);
  1386. }
  1387. }
  1388. this._characterGrid = new Array(this._mapWidth);
  1389. for (var x = 0; x < this._characterGrid.length; x++) {
  1390. this._characterGrid[x] = [];
  1391. for (var y = 0; y < this._mapHeight; y++) {
  1392. this._characterGrid[x].push([]);
  1393. }
  1394. }
  1395. this._needsRefresh = false;
  1396. };
  1397.  
  1398. ColliderManager.addCollider = function(collider, duration, ignoreGrid) {
  1399. if (!$dataMap) return;
  1400. var i = this._colliders.indexOf(collider);
  1401. if (i === -1) {
  1402. this._colliders.push(collider);
  1403. if (duration > 0 || duration === -1) {
  1404. this.draw(collider, duration);
  1405. }
  1406. }
  1407. if (!ignoreGrid) {
  1408. this.updateGrid(collider);
  1409. }
  1410. };
  1411.  
  1412. ColliderManager.addCharacter = function(character, duration) {
  1413. if (!$dataMap) return;
  1414. var i = this._colliders.indexOf(character);
  1415. if (i === -1) {
  1416. this._colliders.push(character);
  1417. if (duration > 0 || duration === -1) {
  1418. this.draw(character.collider('bounds'), duration);
  1419. }
  1420. }
  1421. this.updateGrid(character);
  1422. };
  1423.  
  1424. ColliderManager.remove = function(collider) {
  1425. var i = this._colliders.indexOf(collider);
  1426. if (i < 0) return;
  1427. this.removeFromGrid(collider);
  1428. if (!collider._colliders) collider.kill = true;
  1429. this._colliders.splice(i, 1);
  1430. };
  1431.  
  1432. ColliderManager.removeSprite = function(sprite) {
  1433. this.container.removeChild(sprite);
  1434. delete this.containerDict[sprite._collider.id];
  1435. };
  1436.  
  1437. ColliderManager.updateGrid = function(collider, prevGrid) {
  1438. if (this._needsRefresh) return;
  1439. var currGrid;
  1440. var grid;
  1441. if (collider._colliders) {
  1442. grid = this._characterGrid;
  1443. currGrid = collider.collider('bounds').sectorEdge();
  1444. } else {
  1445. grid = this._colliderGrid;
  1446. currGrid = collider.sectorEdge();
  1447. }
  1448. // TODO make this into 1 single 2d loop
  1449. var x, y;
  1450. if (prevGrid) {
  1451. if (currGrid.x1 == prevGrid.x1 && currGrid.y1 === prevGrid.y1 &&
  1452. currGrid.x2 == prevGrid.x2 && currGrid.y2 === prevGrid.y2) {
  1453. return;
  1454. }
  1455. for (x = prevGrid.x1; x <= prevGrid.x2; x++) {
  1456. for (y = prevGrid.y1; y <= prevGrid.y2; y++) {
  1457. if (!grid[x] || !grid[x][y]) continue;
  1458. var i = grid[x][y].indexOf(collider);
  1459. if (i !== -1) {
  1460. grid[x][y].splice(i, 1);
  1461. }
  1462. }
  1463. }
  1464. }
  1465. for (x = currGrid.x1; x <= currGrid.x2; x++) {
  1466. for (y = currGrid.y1; y <= currGrid.y2; y++) {
  1467. if (!grid[x] || !grid[x][y]) continue;
  1468. grid[x][y].push(collider);
  1469. }
  1470. }
  1471. };
  1472.  
  1473. ColliderManager.removeFromGrid = function(collider) {
  1474. var grid;
  1475. var edge;
  1476. if (collider._colliders) { // Is a character obj
  1477. grid = this._characterGrid;
  1478. edge = collider.collider('bounds').sectorEdge();
  1479. } else { // is a collider
  1480. grid = this._colliderGrid;
  1481. edge = collider.sectorEdge();
  1482. }
  1483. for (var x = edge.x1; x <= edge.x2; x++) {
  1484. for (var y = edge.y1; y <= edge.y2; y++) {
  1485. if (!grid[x] || !grid[x][y]) continue;
  1486. var i = grid[x][y].indexOf(collider);
  1487. if (i !== -1) {
  1488. grid[x][y].splice(i, 1);
  1489. }
  1490. }
  1491. }
  1492. };
  1493.  
  1494. ColliderManager.getCharactersNear = function(collider, only) {
  1495. var grid = collider.sectorEdge();
  1496. var near = [];
  1497. var checked = {};
  1498. var x, y, i;
  1499. for (x = grid.x1; x <= grid.x2; x++) {
  1500. for (y = grid.y1; y <= grid.y2; y++) {
  1501. if (x < 0 || x >= this.sectorCols()) continue;
  1502. if (y < 0 || y >= this.sectorRows()) continue;
  1503. var charas = this._characterGrid[x][y];
  1504. for (i = 0; i < charas.length; i++) {
  1505. if (checked[charas[i].charaId()]) {
  1506. continue;
  1507. }
  1508. checked[charas[i].charaId()] = true;
  1509. if (only) {
  1510. var value = only(charas[i]);
  1511. if (value === 'break') {
  1512. near.push(charas[i]);
  1513. isBreaking = true;
  1514. return near;
  1515. } else if (value === false) {
  1516. continue;
  1517. }
  1518. }
  1519. near.push(charas[i]);
  1520. }
  1521. }
  1522. }
  1523. return near;
  1524. };
  1525.  
  1526. ColliderManager.getCollidersNear = function(collider, only, debug) {
  1527. var grid = collider.sectorEdge();
  1528. var near = [];
  1529. var checked = {};
  1530. var isBreaking = false;
  1531. var x, y, i;
  1532. for (x = grid.x1; x <= grid.x2; x++) {
  1533. for (y = grid.y1; y <= grid.y2; y++) {
  1534. if (x < 0 || x >= this.sectorCols()) continue;
  1535. if (y < 0 || y >= this.sectorRows()) continue;
  1536. var colliders = this._colliderGrid[x][y];
  1537. for (i = 0; i < colliders.length; i++) {
  1538. if (checked[colliders[i].id]) {
  1539. continue;
  1540. }
  1541. checked[colliders[i].id] = true;
  1542. if (only) {
  1543. var value = only(colliders[i]);
  1544. if (value === 'break') {
  1545. near.push(colliders[i]);
  1546. isBreaking = true;
  1547. break;
  1548. } else if (value === false) {
  1549. continue;
  1550. }
  1551. }
  1552. near.push(colliders[i]);
  1553. }
  1554. if (isBreaking) break;
  1555. }
  1556. if (isBreaking) break;
  1557. }
  1558. only = null;
  1559. return near;
  1560. };
  1561.  
  1562. ColliderManager.getAllNear = function(collider, only) {
  1563. var grid = collider.sectorEdge();
  1564. var near = [];
  1565. var checked = {};
  1566. var x, y, i;
  1567. for (x = grid.x1; x <= grid.x2; x++) {
  1568. for (y = grid.y1; y <= grid.y2; y++) {
  1569. if (x < 0 || x >= this.sectorCols()) continue;
  1570. if (y < 0 || y >= this.sectorRows()) continue;
  1571. var charas = this._characterGrid[x][y];
  1572. var colliders = this._colliderGrid[x][y];
  1573. for (i = 0; i < charas.length + colliders.length; i++) {
  1574. var type = i >= charas.length ? 'collider' : 'chara';
  1575. var obj;
  1576. if (type === 'chara') {
  1577. obj = charas[i];
  1578. if (checked[obj.charaId()]) {
  1579. continue;
  1580. }
  1581. checked[obj.charaId()] = true;
  1582. } else {
  1583. obj = colliders[i - charas.length];
  1584. if (checked[obj.id]) {
  1585. continue;
  1586. }
  1587. checked[obj.id] = true;
  1588. }
  1589. if (only) {
  1590. var value = only(type, obj);
  1591. if (value === 'break') {
  1592. near.push(obj);
  1593. return near;
  1594. } else if (value === false) {
  1595. continue;
  1596. }
  1597. }
  1598. near.push(obj);
  1599. }
  1600. }
  1601. }
  1602. return near;
  1603. };
  1604.  
  1605. ColliderManager.sectorCols = function() {
  1606. return Math.floor(this._mapWidth * QMovement.tileSize / this._sectorSize);
  1607. };
  1608.  
  1609. ColliderManager.sectorRows = function() {
  1610. return Math.floor(this._mapHeight * QMovement.tileSize / this._sectorSize);
  1611. };
  1612.  
  1613. ColliderManager.draw = function(collider, duration) {
  1614. if ($gameTemp.isPlaytest()) {
  1615. if (this.containerDict[collider.id]) {
  1616. this.containerDict[collider.id]._collider = collider;
  1617. this.containerDict[collider.id]._collider.kill = false;
  1618. this.containerDict[collider.id]._duration = duration;
  1619. this.containerDict[collider.id].checkChanges();
  1620. return;
  1621. }
  1622. collider.kill = false;
  1623. var sprite = new Sprite_Collider(collider, duration || -1);
  1624. this.container.addChild(sprite);
  1625. this.containerDict[collider.id] = sprite;
  1626. }
  1627. };
  1628.  
  1629. ColliderManager.update = function() {
  1630. if (this.visible) {
  1631. this.show();
  1632. } else {
  1633. this.hide();
  1634. }
  1635. };
  1636.  
  1637. ColliderManager.toggle = function() {
  1638. this.visible = !this.visible;
  1639. };
  1640.  
  1641. ColliderManager.show = function() {
  1642. this.container.visible = true;
  1643. };
  1644.  
  1645. ColliderManager.hide = function() {
  1646. this.container.visible = false;
  1647. };
  1648.  
  1649. ColliderManager.convertToCollider = function(arr) {
  1650. var type = arr[0].toLowerCase();
  1651. if (type === 'preset') {
  1652. var arr = QMovement.presets[arr[1]];
  1653. if (!arr) {
  1654. alert("ERROR: Tried to use a collider preset that doesn't exist: ", type);
  1655. return null;
  1656. }
  1657. type = arr[0].toLowerCase();
  1658. }
  1659. var w = arr[1] || 0;
  1660. var h = arr[2] || 0;
  1661. var ox = arr[3] || 0;
  1662. var oy = arr[4] || 0;
  1663. var collider;
  1664. if (type === 'circle' || type === 'box') {
  1665. if (type === 'circle') {
  1666. collider = new Circle_Collider(w, h, ox, oy);
  1667. } else {
  1668. collider = new Box_Collider(w, h, ox, oy);
  1669. }
  1670. } else if (type === 'poly') {
  1671. collider = new Polygon_Collider(arr.slice(1));
  1672. } else {
  1673. return null;
  1674. }
  1675. return collider;
  1676. };
  1677.  
  1678. ColliderManager.rayCast = function(origin, angle, dist, filter) {
  1679. // Incomplete
  1680. // need to finish the Polygon_Collider.prototype.lineIntersection function
  1681. var ray = new Box_Collider(dist, 1, 0, 0, {
  1682. pivot: new Point(0, 0.5),
  1683. position: origin
  1684. });
  1685. //this.draw(ray, 600);
  1686. return this.getAllNear(ray, filter);
  1687. };
  1688. })();
  1689.  
  1690. //-----------------------------------------------------------------------------
  1691. // Game_Interpreter
  1692.  
  1693. (function() {
  1694. var Alias_Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
  1695. Game_Interpreter.prototype.pluginCommand = function(command, args) {
  1696. if (command.toLowerCase() === 'qmovement') {
  1697. return this.qMovementCommand(QPlus.makeArgs(args));
  1698. }
  1699. Alias_Game_Interpreter_pluginCommand.call(this, command, args);
  1700. };
  1701.  
  1702. Game_Interpreter.prototype.qMovementCommand = function(args) {
  1703. var cmd = args.shift().toLowerCase();
  1704. if (cmd === 'changecollider') {
  1705. var chara = QPlus.getCharacter(args[0]);
  1706. if (!chara) return;
  1707. var type = args[1];
  1708. var data = args.slice(2).map(QPlus.stringToType);
  1709. chara.changeCollider(type, data);
  1710. return;
  1711. }
  1712. if (cmd === 'transfer') {
  1713. var mapId = Number(args[0]);
  1714. var x = Number(args[1]) / QMovement.tileSize;
  1715. var y = Number(args[2]) / QMovement.tileSize;
  1716. var dir = Number(QPlus.getArg(args, /^dir(\d+)$/i)) || 0;
  1717. var fade = QPlus.getArg(args, /fade(black|white)/i) || 'none';
  1718. if (fade.toLowerCase() === 'black') {
  1719. fade = 0;
  1720. } else if (fade.toLowerCase() === 'white') {
  1721. fade = 1;
  1722. } else {
  1723. fade = 3;
  1724. }
  1725. $gamePlayer.reserveTransfer(mapId, x, y, dir, fade);
  1726. return;
  1727. }
  1728. if (cmd === 'setpos') {
  1729. var chara;
  1730. if (args[0].toLowerCase() === 'this') {
  1731. chara = this.character(0);
  1732. } else {
  1733. chara = QPlus.getCharacter(args[0]);
  1734. }
  1735. if (!chara) return;
  1736. var x = Number(args[1]) / QMovement.tileSize;
  1737. var y = Number(args[2]) / QMovement.tileSize;
  1738. var dir = Number(QPlus.getArg(args, /^dir(\d+)$/i)) || 0;
  1739. chara.locate(x, y);
  1740. if (dir > 0) {
  1741. chara.setDirection(dir);
  1742. }
  1743. return;
  1744. }
  1745. };
  1746. })();
  1747.  
  1748. //-----------------------------------------------------------------------------
  1749. // Game_Temp
  1750. //
  1751. // The game object class for temporary data that is not included in save data.
  1752.  
  1753. (function() {
  1754. var Alias_Game_Temp_initialize = Game_Temp.prototype.initialize;
  1755. Game_Temp.prototype.initialize = function() {
  1756. Alias_Game_Temp_initialize.call(this);
  1757. this._destinationPX = null;
  1758. this._destinationPY = null;
  1759. };
  1760.  
  1761. Game_Temp.prototype.setPixelDestination = function(x, y) {
  1762. this._destinationPX = x;
  1763. this._destinationPY = y;
  1764. var x1 = $gameMap.roundX(Math.floor(x / $gameMap.tileWidth()));
  1765. var y1 = $gameMap.roundY(Math.floor(y / $gameMap.tileHeight()));
  1766. this.setDestination(x1, y1);
  1767. };
  1768.  
  1769. var Alias_Game_Temp_clearDestination = Game_Temp.prototype.clearDestination;
  1770. Game_Temp.prototype.clearDestination = function() {
  1771. if ($gamePlayer._movingWithMouse) return;
  1772. Alias_Game_Temp_clearDestination.call(this);
  1773. this._destinationPX = null;
  1774. this._destinationPY = null;
  1775. };
  1776.  
  1777. Game_Temp.prototype.destinationPX = function() {
  1778. return this._destinationPX;
  1779. };
  1780.  
  1781. Game_Temp.prototype.destinationPY = function() {
  1782. return this._destinationPY;
  1783. };
  1784. })();
  1785.  
  1786. //-----------------------------------------------------------------------------
  1787. // Game_System
  1788.  
  1789. (function() {
  1790. var Alias_Game_System_onBeforeSave = Game_System.prototype.onBeforeSave;
  1791. Game_System.prototype.onBeforeSave = function() {
  1792. Alias_Game_System_onBeforeSave.call(this);
  1793. $gameMap.clearColliders();
  1794. ColliderManager._needsRefresh = true;
  1795. };
  1796.  
  1797. var Alias_Game_System_onAfterLoad = Game_System.prototype.onAfterLoad;
  1798. Game_System.prototype.onAfterLoad = function() {
  1799. Alias_Game_System_onAfterLoad.call(this);
  1800. ColliderManager._needsRefresh = true;
  1801. };
  1802. })();
  1803.  
  1804. //-----------------------------------------------------------------------------
  1805. // Game_Map
  1806.  
  1807. (function() {
  1808. var Alias_Game_Map_setup = Game_Map.prototype.setup;
  1809. Game_Map.prototype.setup = function(mapId) {
  1810. if ($dataMap) {
  1811. ColliderManager._mapWidth = this.width();
  1812. ColliderManager._mapHeight = this.height();
  1813. ColliderManager.refresh();
  1814. }
  1815. Alias_Game_Map_setup.call(this, mapId);
  1816. this.reloadColliders();
  1817. };
  1818.  
  1819. Game_Map.prototype.tileWidth = function() {
  1820. return QMovement.tileSize;
  1821. };
  1822.  
  1823. Game_Map.prototype.tileHeight = function() {
  1824. return QMovement.tileSize;
  1825. };
  1826.  
  1827. Game_Map.prototype.flagAt = function(x, y) {
  1828. var x = x || $gamePlayer.x;
  1829. var y = y || $gamePlayer.y;
  1830. var flags = this.tilesetFlags();
  1831. var tiles = this.allTiles(x, y);
  1832. for (var i = 0; i < tiles.length; i++) {
  1833. var flag = flags[tiles[i]];
  1834. console.log('layer', i, ':', flag);
  1835. if (flag & 0x20) console.log('layer', i, 'is ladder');
  1836. if (flag & 0x40) console.log('layer', i, 'is bush');
  1837. if (flag & 0x80) console.log('layer', i, 'is counter');
  1838. if (flag & 0x100) console.log('layer', i, 'is damage');
  1839. }
  1840. };
  1841.  
  1842. Game_Map.prototype.gridSize = function() {
  1843. if ($dataMap && $dataMap.meta.grid !== undefined) {
  1844. return Number($dataMap.meta.grid) || QMovement.grid;
  1845. }
  1846. return QMovement.grid;
  1847. };
  1848.  
  1849. Game_Map.prototype.offGrid = function() {
  1850. if ($dataMap && $dataMap.meta.offGrid !== undefined) {
  1851. return $dataMap.meta.offGrid === 'true';
  1852. }
  1853. return QMovement.offGrid;
  1854. };
  1855.  
  1856. Game_Map.prototype.midPass = function() {
  1857. if ($dataMap && $dataMap.meta.midPass !== undefined) {
  1858. return $dataMap.meta.midPass === 'true';
  1859. }
  1860. return QMovement.midPass;
  1861. };
  1862.  
  1863. var Alias_Game_Map_refreshIfNeeded = Game_Map.prototype.refreshIfNeeded;
  1864. Game_Map.prototype.refreshIfNeeded = function() {
  1865. Alias_Game_Map_refreshIfNeeded.call(this);
  1866. if (ColliderManager._needsRefresh) {
  1867. ColliderManager._mapWidth = this.width();
  1868. ColliderManager._mapHeight = this.height();
  1869. ColliderManager.refresh();
  1870. this.reloadColliders();
  1871. }
  1872. };
  1873.  
  1874. Game_Map.prototype.reloadColliders = function() {
  1875. this.reloadTileMap();
  1876. var events = this.events();
  1877. var i, j;
  1878. for (i = 0, j = events.length; i < j; i++) {
  1879. events[i].reloadColliders();
  1880. }
  1881. var vehicles = this._vehicles;
  1882. for (i = 0, j = vehicles.length; i < j; i++) {
  1883. vehicles[i].reloadColliders();
  1884. }
  1885. $gamePlayer.reloadColliders();
  1886. var followers = $gamePlayer.followers()._data;
  1887. for (i = 0, j = followers.length; i < j; i++) {
  1888. followers[i].reloadColliders();
  1889. }
  1890. };
  1891.  
  1892. Game_Map.prototype.clearColliders = function() {
  1893. var events = this.events();
  1894. var i, j;
  1895. for (i = 0, j = events.length; i < j; i++) {
  1896. events[i].removeColliders();
  1897. }
  1898. var vehicles = this._vehicles;
  1899. for (i = 0, j = vehicles.length; i < j; i++) {
  1900. vehicles[i].removeColliders();
  1901. }
  1902. $gamePlayer.removeColliders();
  1903. var followers = $gamePlayer.followers()._data;
  1904. for (i = 0, j = followers.length; i < j; i++) {
  1905. followers[i].removeColliders();
  1906. }
  1907. };
  1908.  
  1909. Game_Map.prototype.reloadTileMap = function() {
  1910.  
  1911. if ($gameMap._collisionMap != undefined && $gameMap._collisionMap.length > 0) {
  1912. this.setupTileDMapColliders();
  1913. } else {
  1914. this.setupMapColliders();
  1915. }
  1916.  
  1917.  
  1918. // collider map is also loaded here
  1919. // collision map is also loaded here
  1920. };
  1921.  
  1922. Game_Map.prototype.setupTileDMapColliders = function() {
  1923. this._tileCounter = 0;
  1924.  
  1925. for (var y = 0; y < this.height(); y++) {
  1926. for (var x = 0; x < this.width(); x++) {
  1927. var flag = 16;
  1928. var index = (y*this.width()) + x;
  1929. if($gameMap._collisionMap[0][index] == 1) {
  1930. flag = 3599;
  1931. }
  1932.  
  1933. if (flag === 16) continue;
  1934.  
  1935. var data = this.getMapCollider(x, y, flag);
  1936. this.makeTileCollider(x, y, flag, data, 0);
  1937. }
  1938. }
  1939.  
  1940. };
  1941.  
  1942. Game_Map.prototype.setupMapColliders = function() {
  1943. this._tileCounter = 0;
  1944. for (var x = 0; x < this.width(); x++) {
  1945. for (var y = 0; y < this.height(); y++) {
  1946. var flags = this.tilesetFlags();
  1947. var tiles = this.allTiles(x, y);
  1948. var id = x + y * this.width();
  1949. for (var i = tiles.length - 1; i >= 0; i--) {
  1950. var flag = flags[tiles[i]];
  1951. if (flag === 16) continue;
  1952. var data = this.getMapCollider(x, y, flag);
  1953. if (!data) continue;
  1954. if (data[0].constructor === Array) {
  1955. for (var j = 0; j < data.length; j++) {
  1956. this.makeTileCollider(x, y, flag, data[j], j);
  1957. }
  1958. } else {
  1959. this.makeTileCollider(x, y, flag, data, 0);
  1960. }
  1961. }
  1962. }
  1963. }
  1964. };
  1965.  
  1966. Game_Map.prototype.getMapCollider = function(x, y, flag) {
  1967. var realFlag = flag;
  1968. if (flag >> 12 > 0) {
  1969. flag = flag.toString(2);
  1970. flag = flag.slice(flag.length - 12, flag.length);
  1971. flag = parseInt(flag, 2);
  1972. }
  1973. var boxData;
  1974. if (QMovement.regionColliders[this.regionId(x, y)]) {
  1975. var regionData = QMovement.regionColliders[this.regionId(x, y)];
  1976. boxData = [];
  1977. for (var i = 0; i < regionData.length; i++) {
  1978. boxData[i] = [
  1979. regionData[i].width || 0,
  1980. regionData[i].height || 0,
  1981. regionData[i].ox || 0,
  1982. regionData[i].oy || 0,
  1983. regionData[i].tag || regionData[i].note || '',
  1984. regionData[i].type || 'box'
  1985. ]
  1986. }
  1987. flag = 0;
  1988. } else {
  1989. boxData = QMovement.tileBoxes[flag];
  1990. }
  1991. if (!boxData) {
  1992. if (flag & 0x20 || flag & 0x40 || flag & 0x80 || flag & 0x100) {
  1993. boxData = [this.tileWidth(), this.tileHeight(), 0, 0];
  1994. } else {
  1995. return null;
  1996. }
  1997. }
  1998. return boxData;
  1999. };
  2000.  
  2001. Game_Map.prototype.makeTileCollider = function(x, y, flag, boxData, index) {
  2002. // boxData is array [width, height, ox, oy, note, type]
  2003. var x1 = x * this.tileWidth();
  2004. var y1 = y * this.tileHeight();
  2005. var ox = boxData[2] || 0;
  2006. var oy = boxData[3] || 0;
  2007. var w = boxData[0];
  2008. var h = boxData[1];
  2009. if (w === 0 || h === 0) return;
  2010. var type = boxData[5] || 'box';
  2011. var newBox;
  2012. if (type === 'circle') {
  2013. newBox = new Circle_Collider(w, h, ox, oy);
  2014. } else if (type === 'box') {
  2015. newBox = new Box_Collider(w, h, ox, oy);
  2016. } else {
  2017. return;
  2018. }
  2019. newBox.isTile = true;
  2020. newBox.note = boxData[4] || '';
  2021. newBox.flag = flag;
  2022. newBox.terrain = flag >> 12;
  2023. newBox.regionId = this.regionId(x, y);
  2024. newBox.isWater1 = flag >> 12 === QMovement.water1Tag || /<water1>/i.test(newBox.note);
  2025. newBox.isWater2 = flag >> 12 === QMovement.water2Tag || /<water2>/i.test(newBox.note);
  2026. newBox.isLadder = (flag & 0x20) || /<ladder>/i.test(newBox.note);
  2027. newBox.isBush = (flag & 0x40) || /<bush>/i.test(newBox.note);
  2028. newBox.isCounter = (flag & 0x80) || /<counter>/i.test(newBox.note);
  2029. newBox.isDamage = (flag & 0x100) || /<damage>/i.test(newBox.note);
  2030. newBox.moveTo(x1, y1);
  2031. var vx = x * this.height() * this.width();
  2032. var vy = y * this.height();
  2033. var vz = index;
  2034. newBox.location = vx + vy + vz;
  2035. if (newBox.isWater2) {
  2036. newBox.color = QMovement.water2.toLowerCase();
  2037. } else if (newBox.isWater1) {
  2038. newBox.color = QMovement.water1.toLowerCase();
  2039. } else if (newBox.isLadder || newBox.isBush || newBox.isDamage) {
  2040. newBox.color = '#ffffff';
  2041. } else {
  2042. newBox.color = QMovement.collision.toLowerCase();
  2043. }
  2044. ColliderManager.addCollider(newBox, -1);
  2045. return newBox;
  2046. };
  2047.  
  2048. Game_Map.prototype.adjustPX = function(x) {
  2049. return this.adjustX(x / QMovement.tileSize) * QMovement.tileSize;
  2050. };
  2051.  
  2052. Game_Map.prototype.adjustPY = function(y) {
  2053. return this.adjustY(y / QMovement.tileSize) * QMovement.tileSize;
  2054. };
  2055.  
  2056. Game_Map.prototype.roundPX = function(x) {
  2057. return this.isLoopHorizontal() ? x.mod(this.width() * QMovement.tileSize) : x;
  2058. };
  2059.  
  2060. Game_Map.prototype.roundPY = function(y) {
  2061. return this.isLoopVertical() ? y.mod(this.height() * QMovement.tileSize) : y;
  2062. };
  2063.  
  2064. Game_Map.prototype.pxWithDirection = function(x, d, dist) {
  2065. return x + (d === 6 ? dist : d === 4 ? -dist : 0);
  2066. };
  2067.  
  2068. Game_Map.prototype.pyWithDirection = function(y, d, dist) {
  2069. return y + (d === 2 ? dist : d === 8 ? -dist : 0);
  2070. };
  2071.  
  2072. Game_Map.prototype.roundPXWithDirection = function(x, d, dist) {
  2073. return this.roundPX(x + (d === 6 ? dist : d === 4 ? -dist : 0));
  2074. };
  2075.  
  2076. Game_Map.prototype.roundPYWithDirection = function(y, d, dist) {
  2077. return this.roundPY(y + (d === 2 ? dist : d === 8 ? -dist : 0));
  2078. };
  2079.  
  2080. Game_Map.prototype.deltaPX = function(x1, x2) {
  2081. var result = x1 - x2;
  2082. if (this.isLoopHorizontal() && Math.abs(result) > (this.width() * QMovement.tileSize) / 2) {
  2083. if (result < 0) {
  2084. result += this.width() * QMovement.tileSize;
  2085. } else {
  2086. result -= this.width() * QMovement.tileSize;
  2087. }
  2088. }
  2089. return result;
  2090. };
  2091.  
  2092. Game_Map.prototype.deltaPY = function(y1, y2) {
  2093. var result = y1 - y2;
  2094. if (this.isLoopVertical() && Math.abs(result) > (this.height() * QMovement.tileSize) / 2) {
  2095. if (result < 0) {
  2096. result += this.height() * QMovement.tileSize;
  2097. } else {
  2098. result -= this.height() * QMovement.tileSize;
  2099. }
  2100. }
  2101. return result;
  2102. };
  2103.  
  2104. Game_Map.prototype.canvasToMapPX = function(x) {
  2105. var tileWidth = this.tileWidth();
  2106. var originX = this.displayX() * tileWidth;
  2107. return this.roundPX(originX + x);
  2108. };
  2109.  
  2110. Game_Map.prototype.canvasToMapPY = function(y) {
  2111. var tileHeight = this.tileHeight();
  2112. var originY = this.displayY() * tileHeight;
  2113. return this.roundPY(originY + y);
  2114. };
  2115. })();
  2116.  
  2117. //-----------------------------------------------------------------------------
  2118. // Game_Party
  2119.  
  2120. (function() {
  2121. Game_Party.prototype.steps = function() {
  2122. return Math.floor(this._steps);
  2123. };
  2124.  
  2125. Game_Party.prototype.increaseSteps = function() {
  2126. this._steps += $gamePlayer.moveTiles() / QMovement.tileSize;
  2127. };
  2128. })();
  2129.  
  2130. //-----------------------------------------------------------------------------
  2131. // Game_CharacterBase
  2132.  
  2133. (function() {
  2134. Object.defineProperties(Game_CharacterBase.prototype, {
  2135. px: {
  2136. get: function() { return this._px; },
  2137. configurable: true
  2138. },
  2139. py: {
  2140. get: function() { return this._py; },
  2141. configurable: true
  2142. }
  2143. });
  2144.  
  2145. var Alias_Game_CharacterBase_initMembers = Game_CharacterBase.prototype.initMembers;
  2146. Game_CharacterBase.prototype.initMembers = function() {
  2147. Alias_Game_CharacterBase_initMembers.call(this);
  2148. this._px = 0;
  2149. this._py = 0;
  2150. this._realPX = 0;
  2151. this._realPY = 0;
  2152. this._radian = this.directionToRadian(this._direction);
  2153. this._forwardRadian = this.directionToRadian(this._direction);
  2154. this._adjustFrameSpeed = false;
  2155. this._freqCount = 0;
  2156. this._diagonal = false;
  2157. this._currentRad = 0;
  2158. this._targetRad = 0;
  2159. this._pivotX = 0;
  2160. this._pivotY = 0;
  2161. this._radiusL = 0;
  2162. this._radisuH = 0;
  2163. this._angularSpeed;
  2164. this._passabilityLevel = 0; // TODO
  2165. this._stopSkip = 4;
  2166. this._isMoving = false;
  2167. this._smartMove = 0;
  2168. this._colliders = null;
  2169. this._overrideColliders = {};
  2170. };
  2171.  
  2172. Game_CharacterBase.prototype.direction8 = function(horz, vert) {
  2173. if (horz === 4 && vert === 8) return 7;
  2174. if (horz === 4 && vert === 2) return 1;
  2175. if (horz === 6 && vert === 8) return 9;
  2176. if (horz === 6 && vert === 2) return 3;
  2177. return 5;
  2178. };
  2179.  
  2180. Game_CharacterBase.prototype.isMoving = function() {
  2181. return this._isMoving;
  2182. };
  2183.  
  2184. Game_CharacterBase.prototype.startedMoving = function() {
  2185. return this._realPX !== this._px || this._realPY !== this._py;
  2186. };
  2187.  
  2188. Game_CharacterBase.prototype.isDiagonal = function() {
  2189. return this._diagonal;
  2190. };
  2191.  
  2192. Game_CharacterBase.prototype.isArcing = function() {
  2193. return this._currentRad !== this._targetRad;
  2194. };
  2195.  
  2196. Game_CharacterBase.prototype.setPixelPosition = function(x, y) {
  2197. this.setPosition(x / QMovement.tileSize, y / QMovement.tileSize);
  2198. };
  2199.  
  2200. var Alias_Game_CharacterBase_setPosition = Game_CharacterBase.prototype.setPosition;
  2201. Game_CharacterBase.prototype.setPosition = function(x, y) {
  2202. Alias_Game_CharacterBase_setPosition.call(this, x, y);
  2203. this._px = this._realPX = x * QMovement.tileSize;
  2204. this._py = this._realPY = y * QMovement.tileSize;
  2205. if (!this._colliders) this.collider();
  2206. this.moveColliders();
  2207. };
  2208.  
  2209. var Alias_Game_CharacterBase_copyPosition = Game_CharacterBase.prototype.copyPosition;
  2210. Game_CharacterBase.prototype.copyPosition = function(character) {
  2211. Alias_Game_CharacterBase_copyPosition.call(this, character);
  2212. this._px = character._px;
  2213. this._py = character._py;
  2214. this._realPX = character._realPX;
  2215. this._realPY = character._realPY;
  2216. if (!this._colliders) this.collider();
  2217. this.moveColliders();
  2218. };
  2219.  
  2220. var Alias_Game_CharacterBase_setDirection = Game_CharacterBase.prototype.setDirection;
  2221. Game_CharacterBase.prototype.setDirection = function(d) {
  2222. if (d) this._radian = this.directionToRadian(d);
  2223. if (!this.isDirectionFixed() && d) {
  2224. if ([1, 3, 7, 9].contains(d)) {
  2225. this._diagonal = d;
  2226. var horz = [1, 7].contains(d) ? 4 : 6;
  2227. var vert = [1, 3].contains(d) ? 2 : 8;
  2228. if (this._direction === this.reverseDir(horz)) {
  2229. this._direction = horz;
  2230. }
  2231. if (this._direction === this.reverseDir(vert)) {
  2232. this._direction = vert;
  2233. }
  2234. this.resetStopCount();
  2235. return;
  2236. } else {
  2237. this._diagonal = false;
  2238. }
  2239. }
  2240. Alias_Game_CharacterBase_setDirection.call(this, d);
  2241. };
  2242.  
  2243. Game_CharacterBase.prototype.setRadian = function(radian) {
  2244. radian = QPlus.adjustRadian(radian);
  2245. this.setDirection(this.radianToDirection(radian, QMovement.diagonal));
  2246. this._radian = radian;
  2247. };
  2248.  
  2249. Game_CharacterBase.prototype.moveTiles = function() {
  2250. if ($gameMap.gridSize() < this.frameSpeed()) {
  2251. return $gameMap.offGrid() ? this.frameSpeed() : $gameMap.gridSize();
  2252. }
  2253. return $gameMap.gridSize();
  2254. };
  2255.  
  2256. Game_CharacterBase.prototype.frameSpeed = function(multi) {
  2257. var multi = multi === undefined ? 1 : Math.abs(multi);
  2258. return this.distancePerFrame() * QMovement.tileSize * multi;
  2259. };
  2260.  
  2261. Game_CharacterBase.prototype.angularSpeed = function() {
  2262. return this._angularSpeed || this.frameSpeed() / this._radiusL;
  2263. };
  2264.  
  2265. Game_CharacterBase.prototype.forwardV = function() {
  2266. return {
  2267. x: Math.cos(this._forwardRadian) * this.frameSpeed(),
  2268. y: Math.sin(this._forwardRadian) * this.frameSpeed()
  2269. }
  2270. };
  2271.  
  2272. var Alias_Game_CharacterBase_canMove = Game_CharacterBase.prototype.canMove;
  2273. Game_CharacterBase.prototype.canMove = function() {
  2274. if (this._locked) return false;
  2275. return Alias_Game_CharacterBase_canMove.call(this);
  2276. };
  2277.  
  2278. Game_CharacterBase.prototype.canPass = function(x, y, dir) {
  2279. return this.canPixelPass(x * QMovement.tileSize, y * QMovement.tileSize, dir);
  2280. };
  2281.  
  2282. Game_CharacterBase.prototype.canPixelPass = function(x, y, dir, dist, type) {
  2283. dist = dist || this.moveTiles();
  2284. type = type || 'collision';
  2285. var x1 = $gameMap.roundPXWithDirection(x, dir, dist);
  2286. var y1 = $gameMap.roundPYWithDirection(y, dir, dist);
  2287. if (!this.collisionCheck(x1, y1, dir, dist, type)) {
  2288. this.collider(type).moveTo(this._px, this._py);
  2289. return false;
  2290. }
  2291. if (type[0] !== '_') {
  2292. this.moveColliders(x1, y1);
  2293. }
  2294. return true;
  2295. };
  2296.  
  2297. Game_CharacterBase.prototype.canPassDiagonally = function(x, y, horz, vert) {
  2298. return this.canPixelPassDiagonally(x * QMovement.tileSize, y * QMovement.tileSize, horz, vert);
  2299. };
  2300.  
  2301. Game_CharacterBase.prototype.canPixelPassDiagonally = function(x, y, horz, vert, dist, type) {
  2302. dist = dist || this.moveTiles();
  2303. type = type || 'collision';
  2304. var x1 = $gameMap.roundPXWithDirection(x, horz, dist);
  2305. var y1 = $gameMap.roundPYWithDirection(y, vert, dist);
  2306. if (dist === this.moveTiles()) {
  2307. if (!this.canPixelPass(x1, y1, 5, null, type)) return false;
  2308. if ($gameMap.midPass()) {
  2309. var x2 = $gameMap.roundPXWithDirection(x, horz, dist / 2);
  2310. var y2 = $gameMap.roundPYWithDirection(y, vert, dist / 2);
  2311. if (!this.canPixelPass(x2, y2, 5, null, type)) return false;
  2312. }
  2313. } else {
  2314. return (this.canPixelPass(x, y, vert, dist, type) && this.canPixelPass(x, y1, horz, dist, type)) &&
  2315. (this.canPixelPass(x, y, horz, dist, type) && this.canPixelPass(x1, y, vert, dist, type));
  2316. }
  2317. return true;
  2318. };
  2319.  
  2320. Game_CharacterBase.prototype.collisionCheck = function(x, y, dir, dist, type) {
  2321. this.collider(type).moveTo(x, y);
  2322. if (!this.valid(type)) return false;
  2323. if (this.isThrough() || this.isDebugThrough()) return true;
  2324. if ($gameMap.midPass() && dir !== 5) {
  2325. if (!this.middlePass(x, y, dir, dist, type)) return false;
  2326. }
  2327. if (this.collidesWithAnyTile(type)) return false;
  2328. if (this.collidesWithAnyCharacter(type)) return false;
  2329. return true;
  2330. };
  2331.  
  2332. Game_CharacterBase.prototype.middlePass = function(x, y, dir, dist, type) {
  2333. var dist = dist / 2 || this.moveTiles() / 2;
  2334. var x2 = $gameMap.roundPXWithDirection(x, this.reverseDir(dir), dist);
  2335. var y2 = $gameMap.roundPYWithDirection(y, this.reverseDir(dir), dist);
  2336. this.collider(type).moveTo(x2, y2);
  2337. if (this.collidesWithAnyTile(type)) return false;
  2338. if (this.collidesWithAnyCharacter(type)) return false;
  2339. this.collider(type).moveTo(x, y);
  2340. return true;
  2341. };
  2342.  
  2343. Game_CharacterBase.prototype.collidesWithAnyTile = function(type) {
  2344. var collider = this.collider(type);
  2345. var collided = false;
  2346. ColliderManager.getCollidersNear(collider, (function(collider) {
  2347. collided = this.collidedWithTile(type, collider);
  2348. if (collided) return 'break';
  2349. }).bind(this));
  2350. return collided;
  2351. };
  2352.  
  2353. Game_CharacterBase.prototype.collidedWithTile = function(type, collider) {
  2354. if (collider.color && this.passableColors().contains(collider.color)) {
  2355. return false;
  2356. }
  2357. if (collider.type && (collider.type !== 'collision' || collider.type !== 'default')) {
  2358. return false;
  2359. }
  2360. return collider.intersects(this.collider(type));
  2361. };
  2362.  
  2363. Game_CharacterBase.prototype.collidesWithAnyCharacter = function(type) {
  2364. var collider = this.collider(type);
  2365. var collided = false;
  2366. ColliderManager.getCharactersNear(collider, function(chara) {
  2367. collided = this.collidedWithCharacter(type, chara);
  2368. if (collided) return 'break';
  2369. }.bind(this));
  2370. return collided;
  2371. };
  2372.  
  2373. Game_CharacterBase.prototype.collidedWithCharacter = function(type, chara) {
  2374. if (chara.isThrough() || chara === this || !chara.isNormalPriority()) {
  2375. return false;
  2376. }
  2377. if (this.ignoreCharacters(type).contains(chara.charaId())) {
  2378. return false;
  2379. }
  2380. return chara.collider('collision').intersects(this.collider(type));
  2381. };
  2382.  
  2383. Game_CharacterBase.prototype.ignoreCharacters = function(type) {
  2384. // This function is to be aliased by plugins to return a list
  2385. // of charaId's this character can pass through
  2386. return [];
  2387. };
  2388.  
  2389. Game_CharacterBase.prototype.valid = function(type) {
  2390. var edge = this.collider(type).gridEdge();
  2391. var maxW = $gameMap.width();
  2392. var maxH = $gameMap.height();
  2393. if (!$gameMap.isLoopHorizontal()) {
  2394. if (edge.x1 < 0 || edge.x2 >= maxW) return false;
  2395. }
  2396. if (!$gameMap.isLoopVertical()) {
  2397. if (edge.y1 < 0 || edge.y2 >= maxH) return false;
  2398. }
  2399. return true;
  2400. };
  2401.  
  2402. Game_CharacterBase.prototype.passableColors = function() {
  2403. // #00000000 is a transparent return value in collisionmap addon
  2404. var colors = ['#ffffff', '#00000000'];
  2405. switch (this._passabilityLevel) {
  2406. case 1:
  2407. case 3: {
  2408. colors.push(QMovement.water1);
  2409. break;
  2410. }
  2411. case 2:
  2412. case 4: {
  2413. colors.push(QMovement.water1);
  2414. colors.push(QMovement.water2);
  2415. break;
  2416. }
  2417. }
  2418. return colors;
  2419. };
  2420.  
  2421. Game_CharacterBase.prototype.canPassToFrom = function(xf, yf, xi, yi, type) {
  2422. xi = xi === undefined ? this._px : xi;
  2423. yi = yi === undefined ? this._py : yi;
  2424. type = type || 'collision';
  2425. // TODO remove this check by having the start and end colliders
  2426. // be included in the _stretched collider
  2427. if (!this.canPixelPass(xi, yi, 5, null, type) || !this.canPixelPass(xf, yf, 5, null, type)) {
  2428. this.collider(type).moveTo(this._px, this._py);
  2429. return false;
  2430. }
  2431. var dx = xf - xi;
  2432. var dy = yf - yi;
  2433. var radian = Math.atan2(dy, dx);
  2434. if (radian < 0) radian += Math.PI * 2;
  2435. var dist = Math.sqrt(dx * dx + dy * dy);
  2436. this._colliders['_stretched'] = this.collider(type).stretchedPoly(radian, dist);
  2437. if (!this.canPixelPass(xi, yi, 5, null, '_stretched')) {
  2438. delete this._colliders['_stretched'];
  2439. return false;
  2440. }
  2441. delete this._colliders['_stretched'];
  2442. return true;
  2443. };
  2444.  
  2445. Game_CharacterBase.prototype.checkEventTriggerTouchFront = function(d) {
  2446. var horz = vert = d;
  2447. if ([1, 3, 7, 9].contains(d)) {
  2448. horz = (d === 1 || d === 7) ? 4 : 6;
  2449. vert = (d === 1 || d === 3) ? 2 : 8;
  2450. }
  2451. var x2 = $gameMap.roundPXWithDirection(this.px, horz, this.moveTiles());
  2452. var y2 = $gameMap.roundPYWithDirection(this.py, vert, this.moveTiles());
  2453. this.checkEventTriggerTouch(x2, y2);
  2454. };
  2455.  
  2456. Game_CharacterBase.prototype.isOnLadder = function() {
  2457. if (!this.collider()) return false;
  2458. var collider = this.collider('collision');
  2459. var collided = false;
  2460. var colliders = ColliderManager.getCollidersNear(collider, function(tile) {
  2461. if (!tile.isTile) return false;
  2462. if (tile.isLadder && tile.intersects(collider)) {
  2463. collided = true;
  2464. return 'break';
  2465. }
  2466. return false;
  2467. });
  2468. return collided;
  2469. };
  2470.  
  2471. Game_CharacterBase.prototype.isOnBush = function() {
  2472. if (!this.collider()) return false;
  2473. var collider = this.collider('collision');
  2474. var collided = false;
  2475. var colliders = ColliderManager.getCollidersNear(collider, function(tile) {
  2476. if (!tile.isTile) return false;
  2477. if (tile.isBush && tile.intersects(collider)) {
  2478. collided = true;
  2479. return 'break';
  2480. }
  2481. return false;
  2482. });
  2483. return collided;
  2484. };
  2485.  
  2486. Game_CharacterBase.prototype.freqThreshold = function() {
  2487. return QMovement.tileSize;
  2488. };
  2489.  
  2490. Game_CharacterBase.prototype.terrainTag = function() {
  2491. return $gameMap.terrainTag(Math.floor(this.cx(true)), Math.floor(this.cy(true)));
  2492. };
  2493.  
  2494. Game_CharacterBase.prototype.regionId = function() {
  2495. return $gameMap.regionId(Math.floor(this.cx(true)), Math.floor(this.cy(true)));
  2496. };
  2497.  
  2498. var Alias_Game_CharacterBase_update = Game_CharacterBase.prototype.update;
  2499. Game_CharacterBase.prototype.update = function() {
  2500. var prevX = this._realPX;
  2501. var prevY = this._realPY;
  2502. if (this.startedMoving()) {
  2503. this._isMoving = true;
  2504. } else {
  2505. this.updateStop();
  2506. }
  2507. if (this.isArcing()) {
  2508. this.updateArc();
  2509. } else if (this.isJumping()) {
  2510. this.updateJump();
  2511. } else if (this.isMoving()) {
  2512. this.updateMove();
  2513. }
  2514. this.updateAnimation();
  2515. this.updateColliders();
  2516.  
  2517. if ((prevX !== this._realPX || prevY !== this._realPY)) {
  2518. this.onPositionChange();
  2519. this._stopSkip = 4;
  2520. } else {
  2521.  
  2522. if(this._stopSkip > 0) {
  2523. this._stopSkip--;
  2524. return;
  2525. }
  2526.  
  2527. this._isMoving = false;
  2528. }
  2529. };
  2530.  
  2531. Game_CharacterBase.prototype.updateMove = function() {
  2532. var xSpeed = 1;
  2533. var ySpeed = 1;
  2534. if (this._adjustFrameSpeed) {
  2535. xSpeed = Math.cos(this._radian);
  2536. ySpeed = Math.sin(this._radian);
  2537. }
  2538. if (this._px < this._realPX) {
  2539. this._realPX = Math.max(this._realPX - this.frameSpeed(xSpeed), this._px);
  2540. }
  2541. if (this._px > this._realPX) {
  2542. this._realPX = Math.min(this._realPX + this.frameSpeed(xSpeed), this._px);
  2543. }
  2544. if (this._py < this._realPY) {
  2545. this._realPY = Math.max(this._realPY - this.frameSpeed(ySpeed), this._py);
  2546. }
  2547. if (this._py > this._realPY) {
  2548. this._realPY = Math.min(this._realPY + this.frameSpeed(ySpeed), this._py);
  2549. }
  2550. this._x = this._realX = this._realPX / QMovement.tileSize;
  2551. this._y = this._realY = this._realPY / QMovement.tileSize;
  2552. this._freqCount += this.frameSpeed();
  2553. };
  2554.  
  2555. Game_CharacterBase.prototype.updateArc = function() {
  2556. if (this._currentRad < this._targetRad) {
  2557. var newRad = Math.min(this._currentRad + this.angularSpeed(), this._targetRad);
  2558. }
  2559. if (this._currentRad > this._targetRad) {
  2560. var newRad = Math.max(this._currentRad - this.angularSpeed(), this._targetRad);
  2561. }
  2562. var x1 = this._pivotX + this._radiusL * Math.cos(newRad);
  2563. var y1 = this._pivotY + this._radiusH * Math.sin(newRad);
  2564. this._currentRad = newRad;
  2565. this._px = this._realPX = x1;
  2566. this._py = this._realPY = y1;
  2567. this._x = this._realX = this._realPX / QMovement.tileSize;
  2568. this._y = this._realY = this._realPY / QMovement.tileSize;
  2569. this.moveColliders(x1, y1);
  2570. this.checkEventTriggerTouchFront(this._direction);
  2571. };
  2572.  
  2573. var Alias_Game_CharacterBase_updateJump = Game_CharacterBase.prototype.updateJump;
  2574. Game_CharacterBase.prototype.updateJump = function() {
  2575. Alias_Game_CharacterBase_updateJump.call(this);
  2576. this._px = this._realPX = this._x * QMovement.tileSize;
  2577. this._py = this._realPY = this._y * QMovement.tileSize;
  2578. this.moveColliders(this._px, this._py);
  2579. };
  2580.  
  2581. Game_CharacterBase.prototype.updateColliders = function() {
  2582. var colliders = this._colliders;
  2583. if (!colliders) return;
  2584. var hidden = false;
  2585. hidden = this.isTransparent() || this._erased;
  2586. if (!hidden && this.isVisible) {
  2587. hidden = !this.isVisible();
  2588. }
  2589. for (var type in colliders) {
  2590. if (colliders.hasOwnProperty(type)) {
  2591. colliders[type]._isHidden = !!hidden;
  2592. }
  2593. }
  2594. };
  2595.  
  2596. Game_CharacterBase.prototype.onPositionChange = function() {
  2597. this.refreshBushDepth();
  2598. };
  2599.  
  2600. Game_CharacterBase.prototype.refreshBushDepth = function() {
  2601. if (this.isNormalPriority() && !this.isObjectCharacter() &&
  2602. this.isOnBush() && !this.isJumping()) {
  2603. if (!this.startedMoving()) this._bushDepth = 12;
  2604. } else {
  2605. this._bushDepth = 0;
  2606. }
  2607. };
  2608.  
  2609. Game_CharacterBase.prototype.pixelJump = function(xPlus, yPlus) {
  2610. return this.jump(xPlus / QMovement.tileSize, yPlus / QMovement.tileSize);
  2611. };
  2612.  
  2613. Game_CharacterBase.prototype.pixelJumpForward = function(dist, dir) {
  2614. dir = dir || this._direction;
  2615. dist = dist / QMovement.tileSize;
  2616. var x = dir === 6 ? dist : dir === 4 ? -dist : 0;
  2617. var y = dir === 2 ? dist : dir === 8 ? -dist : 0;
  2618. this.jump(x, y);
  2619. };
  2620.  
  2621. Game_CharacterBase.prototype.pixelJumpBackward = function(dist) {
  2622. this.pixelJumpFixed(this.reverseDir(this.direction()), dist);
  2623. };
  2624.  
  2625. Game_CharacterBase.prototype.pixelJumpFixed = function(dir, dist) {
  2626. var lastDirectionFix = this.isDirectionFixed();
  2627. this.setDirectionFix(true);
  2628. this.pixelJumpForward(dist, dir);
  2629. this.setDirectionFix(lastDirectionFix);
  2630. };
  2631.  
  2632. Game_CharacterBase.prototype.moveStraight = function(dir, dist) {
  2633. dist = dist || this.moveTiles();
  2634. this.setMovementSuccess(this.canPixelPass(this._px, this._py, dir, dist));
  2635. var originalSpeed = this._moveSpeed;
  2636. if (this.smartMove() === 1 || this.smartMove() > 2) {
  2637. this.smartMoveSpeed(dir);
  2638. }
  2639. this.setDirection(dir);
  2640. if (this.isMovementSucceeded()) {
  2641. this._forwardRadian = this.directionToRadian(dir);
  2642. this._diagonal = false;
  2643. this._adjustFrameSpeed = false;
  2644. this._px = $gameMap.roundPXWithDirection(this._px, dir, dist);
  2645. this._py = $gameMap.roundPYWithDirection(this._py, dir, dist);
  2646. this._realPX = $gameMap.pxWithDirection(this._px, this.reverseDir(dir), dist);
  2647. this._realPY = $gameMap.pyWithDirection(this._py, this.reverseDir(dir), dist);
  2648. this.increaseSteps();
  2649. } else {
  2650. this.checkEventTriggerTouchFront(dir);
  2651. }
  2652. this._moveSpeed = originalSpeed;
  2653. if (!this.isMovementSucceeded() && this.smartMove() > 1) {
  2654. this.smartMoveDir8(dir);
  2655. }
  2656. };
  2657.  
  2658. //=============================================================================
  2659. // * Determine if Stairs
  2660. //=============================================================================
  2661. Game_Map.prototype.isStairs = function(x, y) {
  2662. if(Imported.YED_Tiled){ // Add Compatibility with Tiled
  2663. // Check if on Region
  2664. var onRegion = this._regions !== undefined && this.regionId(x, y) === 23; //TE Stairs Region = 23
  2665. return this.isValid(x, y) && onRegion;
  2666. } else {
  2667. return this.isValid(x, y) && this.regionId(x, y) === 23;
  2668. }
  2669. };
  2670.  
  2671. Game_CharacterBase.prototype.moveDiagonally = function(horz, vert, dist) {
  2672. dist = dist || this.moveTiles();
  2673. this.setMovementSuccess(this.canPixelPassDiagonally(this._px, this._py, horz, vert, dist));
  2674. var originalSpeed = this._moveSpeed;
  2675. if (this.smartMove() === 1 || this.smartMove() > 2) {
  2676. this.smartMoveSpeed([horz, vert]);
  2677. }
  2678. this.setDirection(this.direction8(horz, vert));
  2679. if (this.isMovementSucceeded()) {
  2680. this._forwardRadian = this.directionToRadian(this.direction8(horz, vert));
  2681.  
  2682. if($gameMap.isStairs(Math.floor(this._x), Math.floor(this._y))) {
  2683. this._forwardRadianIso = this.directionToRadianStairs(this.direction8(horz, vert));
  2684. } else {
  2685. this._forwardRadianIso = this.directionToRadianIso(this.direction8(horz, vert));
  2686. }
  2687.  
  2688. this._adjustFrameSpeed = false;
  2689.  
  2690. xdist = Math.abs(Math.cos(this._forwardRadianIso)) * dist;
  2691. ydist = Math.abs(Math.sin(this._forwardRadianIso)) * dist;
  2692. this._px = $gameMap.roundPXWithDirection(this._px, horz, xdist);
  2693. this._py = $gameMap.roundPYWithDirection(this._py, vert, ydist);
  2694. this._realPX = $gameMap.pxWithDirection(this._px, this.reverseDir(horz), xdist);
  2695. this._realPY = $gameMap.pyWithDirection(this._py, this.reverseDir(vert), ydist);
  2696. this.increaseSteps();
  2697. } else {
  2698. this.checkEventTriggerTouchFront(this.direction8(horz, vert));
  2699. }
  2700. this._moveSpeed = originalSpeed;
  2701. if (!this.isMovementSucceeded() && this.smartMove() > 1) {
  2702. if (this.canPixelPass(this._px, this._py, horz)) {
  2703. this.moveStraight(horz);
  2704. } else if (this.canPixelPass(this._px, this._py, vert)) {
  2705. this.moveStraight(vert);
  2706. }
  2707. }
  2708. };
  2709.  
  2710. Game_CharacterBase.prototype.moveRadian = function(radian, dist) {
  2711. dist = dist || this.moveTiles();
  2712. this.fixedRadianMove(radian, dist);
  2713. if (!this.isMovementSucceeded() && this.smartMove() > 1) {
  2714. var realDir = this.radianToDirection(radian, true);
  2715. var xAxis = Math.cos(radian);
  2716. var yAxis = Math.sin(radian);
  2717. var horz = xAxis > 0 ? 6 : xAxis < 0 ? 4 : 0;
  2718. var vert = yAxis > 0 ? 2 : yAxis < 0 ? 8 : 0;
  2719. if ([1, 3, 7, 9].contains(realDir)) {
  2720. if (this.canPixelPass(this._px, this._py, horz, dist)) {
  2721. this.moveStraight(horz, dist);
  2722. } else if (this.canPixelPass(this._px, this._py, vert, dist)) {
  2723. this.moveStraight(vert, dist);
  2724. }
  2725. } else {
  2726. var dir = this.radianToDirection(radian);
  2727. this.smartMoveDir8(dir);
  2728. }
  2729. }
  2730. };
  2731.  
  2732. Game_CharacterBase.prototype.fixedMove = function(dir, dist) {
  2733. dist = dist || this.moveTiles();
  2734. dir = dir === 5 ? this.direction() : dir;
  2735. if ([1, 3, 7, 9].contains(dir)) {
  2736. var horz = (dir === 1 || dir === 7) ? 4 : 6;
  2737. var vert = (dir === 1 || dir === 3) ? 2 : 8;
  2738. return this.fixedDiagMove(horz, vert, dist);
  2739. }
  2740. this.setMovementSuccess(this.canPixelPass(this._px, this._py, dir, dist));
  2741. this.setDirection(dir);
  2742. if (this.isMovementSucceeded()) {
  2743. this._forwardRadian = this.directionToRadian(dir);
  2744. this._adjustFrameSpeed = false;
  2745. this._px = $gameMap.roundPXWithDirection(this._px, dir, dist);
  2746. this._py = $gameMap.roundPYWithDirection(this._py, dir, dist);
  2747. this._realPX = $gameMap.pxWithDirection(this._px, this.reverseDir(dir), dist);
  2748. this._realPY = $gameMap.pyWithDirection(this._py, this.reverseDir(dir), dist);
  2749. this.increaseSteps();
  2750. } else {
  2751. this.checkEventTriggerTouchFront(dir);
  2752. }
  2753. };
  2754.  
  2755. Game_CharacterBase.prototype.fixedDiagMove = function(horz, vert, dist) {
  2756. dist = dist || this.moveTiles();
  2757. this.setMovementSuccess(this.canPixelPassDiagonally(this._px, this._py, horz, vert));
  2758. this.setDirection(this.direction8(horz, vert));
  2759. if (this.isMovementSucceeded()) {
  2760. this._forwardRadian = this.directionToRadian(this.direction8(horz, vert));
  2761. this._adjustFrameSpeed = false;
  2762. this._px = $gameMap.roundPXWithDirection(this._px, horz, dist);
  2763. this._py = $gameMap.roundPYWithDirection(this._py, vert, dist);
  2764. this._realPX = $gameMap.pxWithDirection(this._px, this.reverseDir(horz), dist);
  2765. this._realPY = $gameMap.pyWithDirection(this._py, this.reverseDir(vert), dist);
  2766. this.increaseSteps();
  2767. } else {
  2768. this.checkEventTriggerTouchFront(this.direction8(horz, vert));
  2769. }
  2770. };
  2771.  
  2772. Game_CharacterBase.prototype.fixedRadianMove = function(radian, dist) {
  2773. dist = dist || this.moveTiles();
  2774. var dir = this.radianToDirection(radian, true);
  2775. var xAxis = Math.cos(radian);
  2776. var yAxis = Math.sin(radian);
  2777. var horzSteps = Math.abs(xAxis) * dist;
  2778. var vertSteps = Math.abs(yAxis) * dist;
  2779. var horz = xAxis > 0 ? 6 : xAxis < 0 ? 4 : 0;
  2780. var vert = yAxis > 0 ? 2 : yAxis < 0 ? 8 : 0;
  2781. var x2 = $gameMap.roundPXWithDirection(this._px, horz, horzSteps);
  2782. var y2 = $gameMap.roundPYWithDirection(this._py, vert, vertSteps);
  2783. this.setMovementSuccess(this.canPassToFrom(x2, y2, this._px, this._py));
  2784. this.setRadian(radian);
  2785. if (this.isMovementSucceeded()) {
  2786. this._forwardRadian = QPlus.adjustRadian(radian);
  2787. this._adjustFrameSpeed = true;
  2788. this._px = x2;
  2789. this._py = y2;
  2790. this._realPX = $gameMap.pxWithDirection(this._px, this.reverseDir(horz), horzSteps);
  2791. this._realPY = $gameMap.pyWithDirection(this._py, this.reverseDir(vert), vertSteps);
  2792. this.increaseSteps();
  2793. } else {
  2794. this.checkEventTriggerTouchFront(dir);
  2795. }
  2796. };
  2797.  
  2798. Game_CharacterBase.prototype.fixedMoveBackward = function(dist) {
  2799. var lastDirectionFix = this.isDirectionFixed();
  2800. this.setDirectionFix(true);
  2801. this.fixedMove(this.reverseDir(this.direction()), dist);
  2802. this.setDirectionFix(lastDirectionFix);
  2803. };
  2804.  
  2805. Game_CharacterBase.prototype.arc = function(pivotX, pivotY, radians, cc, frames) {
  2806. var cc = cc ? 1 : -1;
  2807. var dx = this._px - pivotX;
  2808. var dy = this._py - pivotY;
  2809. var rad = Math.atan2(dy, dx);
  2810. frames = frames || 1;
  2811. rad += rad < 0 ? 2 * Math.PI : 0;
  2812. this._currentRad = rad;
  2813. this._targetRad = rad + radians * cc;
  2814. this._pivotX = pivotX;
  2815. this._pivotY = pivotY;
  2816. this._radiusL = this._radiusH = Math.sqrt(dy * dy + dx * dx);
  2817. this._angularSpeed = radians / frames;
  2818. };
  2819.  
  2820. Game_CharacterBase.prototype.smartMove = function() {
  2821. return this._smartMove;
  2822. };
  2823.  
  2824. Game_CharacterBase.prototype.smartMoveDir8 = function(dir) {
  2825. var dist = this.moveTiles();
  2826. var collider = this.collider('collision');
  2827. var x1 = this._px;
  2828. var y1 = this._py;
  2829. var x2 = $gameMap.roundPXWithDirection(x1, dir, dist);
  2830. var y2 = $gameMap.roundPYWithDirection(y1, dir, dist);
  2831. collider.moveTo(x2, y2);
  2832. var collided = false;
  2833. ColliderManager.getCharactersNear(collider, (function(chara) {
  2834. if (chara.isThrough() || chara === this || !chara.isNormalPriority() ||
  2835. /<smartdir>/i.test(chara.notes())) {
  2836. return false;
  2837. }
  2838. if (chara.collider('collision').intersects(collider)) {
  2839. collided = true;
  2840. return 'break';
  2841. }
  2842. return false;
  2843. }).bind(this));
  2844. collider.moveTo(x1, y1);
  2845. if (collided) return;
  2846. var horz = [4, 6].contains(dir) ? true : false;
  2847. var steps = horz ? collider.height : collider.width;
  2848. steps /= 2;
  2849. var pass = false;
  2850. for (var i = 0; i < 2; i++) {
  2851. var sign = i === 0 ? 1 : -1;
  2852. var j = 0;
  2853. var x2 = x1;
  2854. var y2 = y1;
  2855. if (horz) {
  2856. x2 = $gameMap.roundPXWithDirection(x1, dir, dist);
  2857. } else {
  2858. y2 = $gameMap.roundPYWithDirection(y1, dir, dist);
  2859. }
  2860. while (j < steps) {
  2861. j += dist;
  2862. if (horz) {
  2863. y2 = y1 + j * sign;
  2864. } else {
  2865. x2 = x1 + j * sign;
  2866. }
  2867. pass = this.canPixelPass(x2, y2, 5);
  2868. if (pass) break;
  2869. }
  2870. if (pass) break;
  2871. }
  2872. if (!pass) return;
  2873. var radian = QPlus.adjustRadian(Math.atan2(y2 - y1, x2 - x1));
  2874. this._forwardRadian = radian;
  2875. this._px = x2;
  2876. this._py = y2;
  2877. this._realPX = x1;
  2878. this._realPY = y1;
  2879. this._adjustFrameSpeed = false;
  2880. //this.setRadian(radian);
  2881. this.increaseSteps();
  2882. };
  2883.  
  2884. Game_CharacterBase.prototype.smartMoveSpeed = function(dir) {
  2885. var diag = dir.constructor === Array;
  2886. while (!this.isMovementSucceeded()) {
  2887. // should improve by figuring out what 1 pixel is in terms of movespeed
  2888. // and subtract by that value instead
  2889. this._moveSpeed--;
  2890. if (diag) {
  2891. this.setMovementSuccess(this.canPixelPassDiagonally(this._px, this._py, dir[0], dir[1]));
  2892. } else {
  2893. this.setMovementSuccess(this.canPixelPass(this._px, this._py, dir));
  2894. }
  2895. if (this._moveSpeed < 1) break;
  2896. }
  2897. };
  2898.  
  2899. Game_CharacterBase.prototype.reloadColliders = function() {
  2900. this.removeColliders();
  2901. this.setupColliders();
  2902. };
  2903.  
  2904. Game_CharacterBase.prototype.removeColliders = function() {
  2905. ColliderManager.remove(this);
  2906. for (var collider in this._colliders) {
  2907. if (!this._colliders.hasOwnProperty(collider)) continue;
  2908. ColliderManager.remove(this._colliders[collider]);
  2909. this._colliders[collider] = null;
  2910. }
  2911. this._colliders = null;
  2912. };
  2913.  
  2914. // Can pass multiple types into args, ect:
  2915. // collider('collision', 'interaction', 'default')
  2916. // will return first one thats found
  2917. Game_CharacterBase.prototype.collider = function(type, alternative) {
  2918. if (!this._colliders) this.setupColliders();
  2919. for (var i = 0; i < arguments.length; i++) {
  2920. if (this._colliders[arguments[i]]) {
  2921. return this._colliders[arguments[i]];
  2922. }
  2923. }
  2924. return this._colliders['default'];
  2925. };
  2926.  
  2927. Game_CharacterBase.prototype.defaultColliderConfig = function() {
  2928. return 'box,0,0';
  2929. };
  2930.  
  2931. Game_CharacterBase.prototype.setupColliders = function() {
  2932. this._colliders = {};
  2933. var defaultCollider = this.defaultColliderConfig();
  2934. var notes = this.notes(true);
  2935. var configs = {};
  2936. var multi = /<colliders>([\s\S]*)<\/colliders>/i.exec(notes);
  2937. var single = /<collider[:|=](.*?)>/i.exec(notes);
  2938. if (multi) {
  2939. configs = QPlus.stringToObj(multi[1]);
  2940. }
  2941. if (single) {
  2942. configs.default = QPlus.stringToAry(single[1]);
  2943. } else if (!configs.default) {
  2944. configs.default = QPlus.stringToAry(defaultCollider);
  2945. }
  2946. Object.assign(configs, this._overrideColliders);
  2947. for (var collider in configs) {
  2948. this.makeCollider(collider, configs[collider]);
  2949. }
  2950. this.makeBounds();
  2951. this.moveColliders();
  2952. };
  2953.  
  2954. Game_CharacterBase.prototype.makeCollider = function(type, settings) {
  2955. this._colliders[type] = ColliderManager.convertToCollider(settings);
  2956. this._colliders[type].oy -= this.shiftY();
  2957. this._colliders[type]._charaId = this.charaId();
  2958. ColliderManager.addCollider(this._colliders[type], -1, true);
  2959. };
  2960.  
  2961. Game_CharacterBase.prototype.changeCollider = function(type, settings) {
  2962. this._overrideColliders[type] = settings;
  2963. this.reloadColliders();
  2964. };
  2965.  
  2966. Game_CharacterBase.prototype.makeBounds = function() {
  2967. var minX = null;
  2968. var maxX = null;
  2969. var minY = null;
  2970. var maxY = null;
  2971. for (var type in this._colliders) {
  2972. if (!this._colliders.hasOwnProperty(type)) continue;
  2973. var edge = this._colliders[type].edge();
  2974. if (minX === null || minX > edge.x1) {
  2975. minX = edge.x1;
  2976. }
  2977. if (maxX === null || maxX < edge.x2) {
  2978. maxX = edge.x2;
  2979. }
  2980. if (minY === null || minY > edge.y1) {
  2981. minY = edge.y1;
  2982. }
  2983. if (maxY === null || maxY < edge.y2) {
  2984. maxY = edge.y2;
  2985. }
  2986. }
  2987. var w = maxX - minX + 1;
  2988. var h = maxY - minY + 1;
  2989. this._colliders['bounds'] = new Box_Collider(w, h, minX, minY);
  2990. this._colliders['bounds']._charaId = String(this.charaId());
  2991. ColliderManager.addCharacter(this, 0);
  2992. };
  2993.  
  2994. Game_CharacterBase.prototype.moveColliders = function(x, y) {
  2995. x = typeof x === 'number' ? x : this.px;
  2996. y = typeof y === 'number' ? y : this.py;
  2997. var prev = this._colliders['bounds'].sectorEdge();
  2998. for (var collider in this._colliders) {
  2999. if (this._colliders.hasOwnProperty(collider)) {
  3000. this._colliders[collider].moveTo(x, y);
  3001. }
  3002. }
  3003. ColliderManager.updateGrid(this, prev);
  3004. };
  3005.  
  3006. Game_CharacterBase.prototype.cx = function(grid) {
  3007. var x = this.collider('collision').center.x;;
  3008. if (grid) x /= QMovement.tileSize;
  3009. return x;
  3010. };
  3011.  
  3012. Game_CharacterBase.prototype.cy = function(grid) {
  3013. var y = this.collider('collision').center.y;
  3014. if (grid) y /= QMovement.tileSize;
  3015. return y;
  3016. };
  3017. })();
  3018.  
  3019. //-----------------------------------------------------------------------------
  3020. // Game_Character
  3021.  
  3022. (function() {
  3023. var Alias_Game_Character_processMoveCommand = Game_Character.prototype.processMoveCommand;
  3024. Game_Character.prototype.processMoveCommand = function(command) {
  3025. this.subMVMoveCommands(command);
  3026. if (this.subQMoveCommand(command)) {
  3027. command = this._moveRoute.list[this._moveRouteIndex];
  3028. }
  3029. this.processQMoveCommands(command);
  3030. Alias_Game_Character_processMoveCommand.call(this, command);
  3031. };
  3032.  
  3033. Game_Character.prototype.subMVMoveCommands = function(command) {
  3034. var gc = Game_Character;
  3035. var params = command.parameters;
  3036. switch (command.code) {
  3037. case gc.ROUTE_MOVE_DOWN: {
  3038. this.subQMove('2, 1,' + QMovement.tileSize);
  3039. break;
  3040. }
  3041. case gc.ROUTE_MOVE_LEFT: {
  3042. this.subQMove('4, 1,' + QMovement.tileSize);
  3043. break;
  3044. }
  3045. case gc.ROUTE_MOVE_RIGHT: {
  3046. this.subQMove('6, 1,' + QMovement.tileSize);
  3047. break;
  3048. }
  3049. case gc.ROUTE_MOVE_UP: {
  3050. this.subQMove('8, 1,' + QMovement.tileSize);
  3051. break;
  3052. }
  3053. case gc.ROUTE_MOVE_LOWER_L: {
  3054. if ($gameMap.offGrid()) {
  3055. this.subQMove2('2.67789,' + QMovement.tileSize);
  3056. } else {
  3057. this.subQMove('1, 1,' + QMovement.tileSize);
  3058. }
  3059. break;
  3060. }
  3061. case gc.ROUTE_MOVE_LOWER_R: {
  3062. if ($gameMap.offGrid()) {
  3063. this.subQMove2('0.46369,' + QMovement.tileSize);
  3064. } else {
  3065. this.subQMove('3, 1,' + QMovement.tileSize);
  3066. }
  3067. break;
  3068. }
  3069. case gc.ROUTE_MOVE_UPPER_L: {
  3070. if ($gameMap.offGrid()) {
  3071. this.subQMove2('3.60529,' + QMovement.tileSize);
  3072. } else {
  3073. this.subQMove('7, 1,' + QMovement.tileSize);
  3074. }
  3075. break;
  3076. }
  3077. case gc.ROUTE_MOVE_UPPER_R: {
  3078. if ($gameMap.offGrid()) {
  3079. this.subQMove2('5.81948,' + QMovement.tileSize);
  3080. } else {
  3081. this.subQMove('9, 1,' + QMovement.tileSize);
  3082. }
  3083. break;
  3084. }
  3085. case gc.ROUTE_MOVE_FORWARD: {
  3086. this.subQMove('5, 1,' + QMovement.tileSize);
  3087. break;
  3088. }
  3089. case gc.ROUTE_MOVE_BACKWARD: {
  3090. this.subQMove('0, 1,' + QMovement.tileSize);
  3091. break;
  3092. }
  3093. case gc.ROUTE_TURN_DOWN:
  3094. case gc.ROUTE_TURN_LEFT:
  3095. case gc.ROUTE_TURN_RIGHT:
  3096. case gc.ROUTE_TURN_UP:
  3097. case gc.ROUTE_TURN_90D_R:
  3098. case gc.ROUTE_TURN_90D_L:
  3099. case gc.ROUTE_TURN_180D:
  3100. case gc.ROUTE_TURN_90D_R_L:
  3101. case gc.ROUTE_TURN_RANDOM:
  3102. case gc.ROUTE_TURN_TOWARD:
  3103. case gc.ROUTE_TURN_AWAY: {
  3104. this._freqCount = this.freqThreshold();
  3105. break;
  3106. }
  3107. }
  3108. };
  3109.  
  3110. Game_Character.prototype.subQMoveCommand = function(command) {
  3111. var gc = Game_Character;
  3112. var code = command.code;
  3113. var params = command.parameters;
  3114. if (command.code === gc.ROUTE_SCRIPT) {
  3115. var qmove = /^qmove\((.*)\)/i.exec(params[0]);
  3116. var qmove2 = /^qmove2\((.*)\)/i.exec(params[0]);
  3117. var arc = /^arc\((.*)\)/i.exec(params[0]);
  3118. var arc2 = /^arc2\((.*)\)/i.exec(params[0]);
  3119. if (qmove) return this.subQMove(qmove[1]);
  3120. if (qmove2) return this.subQMove2(qmove2[1]);
  3121. if (arc) return this.subArc(arc[1]);
  3122. if (arc2) return this.subArc2(arc2[1]);
  3123. }
  3124. return false;
  3125. };
  3126.  
  3127. Game_Character.prototype.processQMoveCommands = function(command) {
  3128. var params = command.parameters;
  3129. switch (command.code) {
  3130. case 'arc': {
  3131. this.arc(params[0], params[1], eval(params[2]), params[3], params[4]);
  3132. break;
  3133. }
  3134. case 'arc2': {
  3135. var x = params[0] + this.px;
  3136. var y = params[1] + this.py;
  3137. this.arc(x, y, eval(params[2]), params[3], params[4]);
  3138. break;
  3139. }
  3140. case 'fixedRadianMove': {
  3141. this.fixedRadianMove(params[0], params[1]);
  3142. break;
  3143. }
  3144. case 'fixedMove': {
  3145. this.fixedMove(params[0], params[1]);
  3146. break;
  3147. }
  3148. case 'fixedMoveBackward': {
  3149. this.fixedMoveBackward(params[0]);
  3150. break;
  3151. }
  3152. case 'fixedMoveForward': {
  3153. this.fixedMove(this.direction(), params[0]);
  3154. break;
  3155. }
  3156. }
  3157. };
  3158.  
  3159. Game_Character.prototype.subArc = function(settings) {
  3160. var cmd = {};
  3161. cmd.code = 'arc';
  3162. cmd.parameters = QPlus.stringToAry(settings);
  3163. this._moveRoute.list[this._moveRouteIndex] = cmd;
  3164. return true;
  3165. };
  3166.  
  3167. Game_Character.prototype.subArc2 = function(settings) {
  3168. var cmd = {};
  3169. cmd.code = 'arc2';
  3170. cmd.parameters = QPlus.stringToAry(settings);
  3171. this._moveRoute.list[this._moveRouteIndex] = cmd;
  3172. return true;
  3173. };
  3174.  
  3175. Game_Character.prototype.subQMove = function(settings) {
  3176. settings = QPlus.stringToAry(settings);
  3177. var dir = settings[0];
  3178. var amt = settings[1];
  3179. var multi = settings[2] || 1;
  3180. var tot = amt * multi;
  3181. var steps = Math.floor(tot / this.moveTiles());
  3182. var moved = 0;
  3183. var i;
  3184. for (i = 0; i < steps; i++) {
  3185. moved += this.moveTiles();
  3186. var cmd = {};
  3187. if (dir === 0) {
  3188. cmd.code = 'fixedMoveBackward';
  3189. cmd.parameters = [this.moveTiles()];
  3190. } else if (dir === 5) {
  3191. cmd.code = 'fixedMoveForward';
  3192. cmd.parameters = [this.moveTiles()];
  3193. } else {
  3194. cmd.code = 'fixedMove';
  3195. cmd.parameters = [dir, this.moveTiles()];
  3196. }
  3197. this._moveRoute.list.splice(this._moveRouteIndex + 1, 0, cmd);
  3198. }
  3199. if (moved < tot) {
  3200. var cmd = {};
  3201. if (dir === 0) {
  3202. cmd.code = 'fixedMoveBackward';
  3203. cmd.parameters = [this.moveTiles()];
  3204. } else if (dir === 5) {
  3205. cmd.code = 'fixedMoveForward';
  3206. cmd.parameters = [this.moveTiles()];
  3207. } else {
  3208. cmd.code = 'fixedMove';
  3209. cmd.parameters = [dir, this.moveTiles()];
  3210. }
  3211. this._moveRoute.list.splice(this._moveRouteIndex + 1 + i, 0, cmd);
  3212. }
  3213. this._moveRoute.list.splice(this._moveRouteIndex, 1);
  3214. return true;
  3215. };
  3216.  
  3217. Game_Character.prototype.subQMove2 = function(settings) {
  3218. settings = QPlus.stringToAry(settings);
  3219. var radian = settings[0];
  3220. var dist = settings[1];
  3221. var maxSteps = Math.floor(dist / this.moveTiles());
  3222. var steps = 0;
  3223. var i;
  3224. for (i = 0; i < maxSteps; i++) {
  3225. steps += this.moveTiles();
  3226. var cmd = {};
  3227. cmd.code = 'fixedRadianMove';
  3228. cmd.parameters = [radian, this.moveTiles()];
  3229. this._moveRoute.list.splice(this._moveRouteIndex + 1, 0, cmd);
  3230. }
  3231. if (steps < dist) {
  3232. var cmd = {};
  3233. cmd.code = 'fixedRadianMove';
  3234. cmd.parameters = [radian, dist - steps];
  3235. this._moveRoute.list.splice(this._moveRouteIndex + 1 + i, 0, cmd);
  3236. }
  3237. this._moveRoute.list.splice(this._moveRouteIndex, 1);
  3238. return true;
  3239. };
  3240.  
  3241. Game_Character.prototype.moveRandom = function() {
  3242. var d = 2 + Math.randomInt(4) * 2;
  3243. if (this.canPixelPass(this._px, this._py, d)) {
  3244. this.moveStraight(d);
  3245. }
  3246. };
  3247.  
  3248. var Alias_Game_Character_moveTowardCharacter = Game_Character.prototype.moveTowardCharacter;
  3249. Game_Character.prototype.moveTowardCharacter = function(character) {
  3250. if ($gameMap.offGrid()) {
  3251. var dx = this.deltaPXFrom(character.cx());
  3252. var dy = this.deltaPYFrom(character.cy());
  3253. var radian = Math.atan2(-dy, -dx);
  3254. if (radian < 0) radian += Math.PI * 2;
  3255. var oldSM = this._smartMove;
  3256. if (oldSM <= 1) this._smartMove = 2;
  3257. this.moveRadian(radian);
  3258. this._smartMove = oldSM;
  3259. } else {
  3260. Alias_Game_Character_moveTowardCharacter.call(this, character);
  3261. }
  3262. };
  3263.  
  3264. var Alias_Game_Character_moveAwayFromCharacter = Game_Character.prototype.moveAwayFromCharacter;
  3265. Game_Character.prototype.moveAwayFromCharacter = function(character) {
  3266. if ($gameMap.offGrid()) {
  3267. var dx = this.deltaPXFrom(character.cx());
  3268. var dy = this.deltaPYFrom(character.cy());
  3269. var radian = Math.atan2(dy, dx);
  3270. if (radian < 0) radian += Math.PI * 2;
  3271. var oldSM = this._smartMove;
  3272. if (oldSM <= 1) this._smartMove = 2;
  3273. this.moveRadian(radian);
  3274. this._smartMove = oldSM;
  3275. } else {
  3276. Alias_Game_Character_moveAwayFromCharacter.call(this, character);
  3277. }
  3278. };
  3279.  
  3280. Game_Character.prototype.turnTowardCharacter = function(character) {
  3281. var dx = this.deltaPXFrom(character.cx());
  3282. var dy = this.deltaPYFrom(character.cy());
  3283. this.setRadian(Math.atan2(-dy, -dx));
  3284. };
  3285.  
  3286. Game_Character.prototype.turnTowardCharacterForward = function(character, dt) {
  3287. if (!character.isMoving()) {
  3288. return this.turnTowardCharacter(character);
  3289. }
  3290. dt = dt || 1;
  3291. var forward = character.forwardV();
  3292. var x = character.cx() + (forward.x * dt);
  3293. var y = character.cy() + (forward.y * dt);
  3294. var dx = this.deltaPXFrom(x);
  3295. var dy = this.deltaPYFrom(y);
  3296. this.setRadian(Math.atan2(-dy, -dx));
  3297. };
  3298.  
  3299. Game_Character.prototype.turnAwayFromCharacter = function(character) {
  3300. var dx = this.deltaPXFrom(character.cx());
  3301. var dy = this.deltaPYFrom(character.cy());
  3302. this.setRadian(Math.atan2(dy, dx));
  3303. };
  3304.  
  3305. Game_Character.prototype.deltaPXFrom = function(x) {
  3306. return $gameMap.deltaPX(this.cx(), x);
  3307. };
  3308.  
  3309. Game_Character.prototype.deltaPYFrom = function(y) {
  3310. return $gameMap.deltaPY(this.cy(), y);
  3311. };
  3312.  
  3313. Game_Character.prototype.pixelDistanceFrom = function(x, y) {
  3314. return $gameMap.distance(this.cx(), this.cy(), x, y);
  3315. };
  3316.  
  3317. // Returns the px, py needed for this character to be center aligned
  3318. // with the character passed in (align is based off collision collider)
  3319. Game_Character.prototype.centerWith = function(character) {
  3320. var dx1 = this.cx() - this._px;
  3321. var dy1 = this.cy() - this._py;
  3322. var dx2 = character.cx() - character._px;
  3323. var dy2 = character.cy() - character._py;
  3324. var dx = dx2 - dx1;
  3325. var dy = dy2 - dy1;
  3326. return new Point(character._px + dx, character._py + dy);
  3327. };
  3328.  
  3329. Game_Character.prototype.centerWithCollider = function(collider) {
  3330. var dx1 = this.cx() - this._px;
  3331. var dy1 = this.cy() - this._py;
  3332. var dx2 = collider.center.x - collider.x;
  3333. var dy2 = collider.center.y - collider.y;
  3334. var dx = dx2 - dx1;
  3335. var dy = dy2 - dy1;
  3336. return new Point(collider.x + dx, collider.y + dy);
  3337. };
  3338.  
  3339. Game_Character.prototype.adjustPosition = function(xf, yf) {
  3340. var dx = xf - this._px;
  3341. var dy = yf - this._py;
  3342. var radian = Math.atan2(dy, dx);
  3343. var distX = Math.cos(radian) * this.moveTiles();
  3344. var distY = Math.sin(radian) * this.moveTiles();
  3345. var final = new Point(xf, yf);
  3346. while (!this.canPixelPass(final.x, final.y, 5, 'collision')) {
  3347. final.x -= distX;
  3348. final.y -= distY;
  3349. dx = final.x - this._px;
  3350. dy = final.y - this._py;
  3351. if (Math.atan2(dy, dx) !== radian) {
  3352. final.x = this._px;
  3353. final.y = this._py;
  3354. break;
  3355. }
  3356. }
  3357. this.moveColliders(this._px, this._py);
  3358. return final;
  3359. };
  3360. })();
  3361.  
  3362. //-----------------------------------------------------------------------------
  3363. // Game_Player
  3364.  
  3365. (function() {
  3366. var Alias_Game_Player_initMembers = Game_Player.prototype.initMembers;
  3367. Game_Player.prototype.initMembers = function() {
  3368. Alias_Game_Player_initMembers.call(this);
  3369. this._lastMouseRequested = 0;
  3370. this._requestMouseMove = false;
  3371. this._movingWithMouse = false;
  3372. this._smartMove = QMovement.smartMove;
  3373. };
  3374.  
  3375. Game_Player.prototype.defaultColliderConfig = function() {
  3376. return QMovement.playerCollider;
  3377. };
  3378.  
  3379. var Alias_Game_Player_refresh = Game_Player.prototype.refresh;
  3380. Game_Player.prototype.refresh = function() {
  3381. this.reloadColliders();
  3382. Alias_Game_Player_refresh.call(this);
  3383. };
  3384.  
  3385. Game_Player.prototype.requestMouseMove = function() {
  3386. var currFrame = Graphics.frameCount;
  3387. var dt = currFrame - this._lastMouseRequested;
  3388. if (dt >= 5) {
  3389. this._lastMouseRequested = currFrame;
  3390. this._requestMouseMove = true;
  3391. } else {
  3392. this._requestMouseMove = false;
  3393. }
  3394. };
  3395.  
  3396. Game_Player.prototype.moveByMouse = function(x, y) {
  3397. if (this.triggerTouchAction()) {
  3398. this.clearMouseMove();
  3399. return false;
  3400. }
  3401. this._movingWithMouse = true;
  3402. return true;
  3403. };
  3404.  
  3405. Game_Player.prototype.clearMouseMove = function() {
  3406. this._requestMouseMove = false;
  3407. this._movingWithMouse = false;
  3408. $gameTemp.clearDestination();
  3409. };
  3410.  
  3411. Game_Player.prototype.moveByInput = function() {
  3412. if (!this.startedMoving() && this.canMove()) {
  3413. if (this.triggerAction()) return;
  3414. var direction = QMovement.diagonal ? Input.dir8 : Input.dir4;
  3415. if (direction > 0) {
  3416. this.clearMouseMove();
  3417. } else if ($gameTemp.isDestinationValid()) {
  3418. if (!QMovement.moveOnClick) {
  3419. $gameTemp.clearDestination();
  3420. return;
  3421. }
  3422. this.requestMouseMove();
  3423. if (this._requestMouseMove) {
  3424. var x = $gameTemp.destinationPX();
  3425. var y = $gameTemp.destinationPY();
  3426. return this.moveByMouse(x, y);
  3427. }
  3428. }
  3429. if (Imported.QInput && Input.preferGamepad() && $gameMap.offGrid()) {
  3430. this.moveWithAnalog();
  3431. } else {
  3432. if ([4, 6].contains(direction)) {
  3433. this.moveInputHorizontal(direction);
  3434. } else if ([2, 8].contains(direction)) {
  3435. this.moveInputVertical(direction);
  3436. } else if ([1, 3, 7, 9].contains(direction) && QMovement.diagonal) {
  3437. this.moveInputDiagonal(direction);
  3438. }
  3439. }
  3440. }
  3441. };
  3442.  
  3443. Game_Player.prototype.moveInputHorizontal = function(dir) {
  3444. this.moveStraight(dir);
  3445. };
  3446.  
  3447. Game_Player.prototype.moveInputVertical = function(dir) {
  3448. this.moveStraight(dir);
  3449. };
  3450.  
  3451. Game_Player.prototype.moveInputDiagonal = function(dir) {
  3452. var diag = {
  3453. 1: [4, 2], 3: [6, 2],
  3454. 7: [4, 8], 9: [6, 8]
  3455. }
  3456. this.moveDiagonally(diag[dir][0], diag[dir][1]);
  3457. };
  3458.  
  3459. Game_Player.prototype.moveWithAnalog = function() {
  3460. var horz = Input._dirAxesA.x;
  3461. var vert = Input._dirAxesA.y;
  3462. if (horz === 0 && vert === 0) return;
  3463. var radian = Math.atan2(vert, horz);
  3464. radian += radian < 0 ? Math.PI * 2 : 0;
  3465. this.moveRadian(radian);
  3466. };
  3467.  
  3468. Game_Player.prototype.update = function(sceneActive) {
  3469. var lastScrolledX = this.scrolledX();
  3470. var lastScrolledY = this.scrolledY();
  3471. var wasMoving = this.isMoving();
  3472. this.updateDashing();
  3473. if (sceneActive) {
  3474. this.moveByInput();
  3475. }
  3476. Game_Character.prototype.update.call(this);
  3477. this.updateScroll(lastScrolledX, lastScrolledY);
  3478. this.updateVehicle();
  3479. if (!this.startedMoving()) this.updateNonmoving(wasMoving);
  3480. this._followers.update();
  3481. };
  3482.  
  3483. Game_Player.prototype.updateNonmoving = function(wasMoving) {
  3484. if (!$gameMap.isEventRunning()) {
  3485. if (wasMoving) {
  3486. if (this._freqCount >= this.freqThreshold()) {
  3487. $gameParty.onPlayerWalk();
  3488. }
  3489. this.checkEventTriggerHere([1, 2]);
  3490. if ($gameMap.setupStartingEvent()) return;
  3491. }
  3492. if (this.triggerAction()) return;
  3493. if (wasMoving) {
  3494. if (this._freqCount >= this.freqThreshold()) {
  3495. this.updateEncounterCount();
  3496. this._freqCount = 0;
  3497. }
  3498. } else if (!this.isMoving() && !this._movingWithMouse) {
  3499. $gameTemp.clearDestination();
  3500. }
  3501. }
  3502. };
  3503.  
  3504. Game_Player.prototype.updateDashing = function() {
  3505. if (this.startedMoving()) return;
  3506. if (this.canMove() && !this.isInVehicle() && !$gameMap.isDashDisabled()) {
  3507. this._dashing = this.isDashButtonPressed() || $gameTemp.isDestinationValid();
  3508. } else {
  3509. this._dashing = false;
  3510. }
  3511. };
  3512.  
  3513. Game_Player.prototype.startMapEvent = function(x, y, triggers, normal) {
  3514. if (!$gameMap.isEventRunning()) {
  3515. var collider = this.collider('interaction');
  3516. var x1 = this._px;
  3517. var y1 = this._py;
  3518. collider.moveTo(x, y);
  3519. var events = ColliderManager.getCharactersNear(collider, function(chara) {
  3520. return this.collidesWithEvent(chara, 'interaction');
  3521. }.bind(this))
  3522. collider.moveTo(x1, y1);
  3523. if (events.length === 0) {
  3524. events = null;
  3525. return;
  3526. }
  3527. var cx = this.cx();
  3528. var cy = this.cy();
  3529. events.sort(function(a, b) {
  3530. return a.pixelDistanceFrom(cx, cy) - b.pixelDistanceFrom(cx, cy);
  3531. })
  3532. var event = events.shift();
  3533. while (true) {
  3534. if (event.isTriggerIn(triggers) && event.isNormalPriority() === normal) {
  3535. event.start();
  3536. }
  3537. if (events.length === 0 || $gameMap.isAnyEventStarting()) {
  3538. break;
  3539. }
  3540. event = events.shift();
  3541. }
  3542. events = null;
  3543. }
  3544. };
  3545.  
  3546. Game_Player.prototype.collidesWithEvent = function(event, type) {
  3547. if (event.constructor === Game_Event && !event._erased) {
  3548. return event.collider('interaction').intersects(this.collider(type));
  3549. }
  3550. return false;
  3551. };
  3552.  
  3553. Game_Player.prototype.checkEventTriggerHere = function(triggers) {
  3554. if (this.canStartLocalEvents()) {
  3555. this.startMapEvent(this.collider('interaction').x, this.collider('interaction').y, triggers, false);
  3556. }
  3557. };
  3558.  
  3559. Game_Player.prototype.checkEventTriggerThere = function(triggers, x2, y2) {
  3560. if (this.canStartLocalEvents()) {
  3561. var direction = this.direction();
  3562. var x1 = this.collider('interaction').x;
  3563. var y1 = this.collider('interaction').y;
  3564. x2 = x2 || $gameMap.roundPXWithDirection(x1, direction, this.moveTiles());
  3565. y2 = y2 || $gameMap.roundPYWithDirection(y1, direction, this.moveTiles());
  3566. this.startMapEvent(x2, y2, triggers, true);
  3567. if (!$gameMap.isAnyEventStarting()) {
  3568. return this.checkCounter(triggers);
  3569. }
  3570. }
  3571. };
  3572.  
  3573. Game_Player.prototype.triggerTouchAction = function() {
  3574. if ($gameTemp.isDestinationValid()) {
  3575. var dist = this.pixelDistanceFrom($gameTemp.destinationPX(), $gameTemp.destinationPY());
  3576. if (dist <= QMovement.tileSize * 1.5) {
  3577. var dx = $gameTemp.destinationPX() - this.cx();
  3578. var dy = $gameTemp.destinationPY() - this.cy();
  3579. if (Math.abs(dx) < this.moveTiles() / 2 && Math.abs(dy) < this.moveTiles() / 2) {
  3580. return false;
  3581. }
  3582. var radian = Math.atan2(dy, dx);
  3583. radian += radian < 0 ? 2 * Math.PI : 0;
  3584. var dir = this.radianToDirection(radian, true);
  3585. var horz = dir;
  3586. var vert = dir;
  3587. if ([1, 3, 7, 9].contains(dir)) {
  3588. if (dir === 1 || dir === 7) horz = 4;
  3589. if (dir === 1 || dir === 3) vert = 2;
  3590. if (dir === 3 || dir === 9) horz = 6;
  3591. if (dir === 7 || dir === 9) vert = 8;
  3592. }
  3593. var x1 = $gameMap.roundPXWithDirection(this._px, horz, this.moveTiles());
  3594. var y1 = $gameMap.roundPYWithDirection(this._py, vert, this.moveTiles());
  3595. this.startMapEvent(x1, y1, [0, 1, 2], true);
  3596. if (!$gameMap.isAnyEventStarting()) {
  3597. if (this.checkCounter([0, 1, 2], $gameTemp.destinationPX(), $gameTemp.destinationPY())) {
  3598. this.clearMouseMove();
  3599. this.setDirection(dir);
  3600. return true;
  3601. }
  3602. } else {
  3603. this.clearMouseMove();
  3604. this.setDirection(dir);
  3605. return true;
  3606. }
  3607. }
  3608. }
  3609. return false;
  3610. };
  3611.  
  3612. Game_Player.prototype.checkCounter = function(triggers, x2, y2) {
  3613. var direction = this.direction();
  3614. var x1 = this._px;
  3615. var y1 = this._py;
  3616. x2 = x2 || $gameMap.roundPXWithDirection(x1, direction, this.moveTiles());
  3617. y2 = y2 || $gameMap.roundPYWithDirection(y1, direction, this.moveTiles());
  3618. var collider = this.collider('interaction');
  3619. collider.moveTo(x2, y2);
  3620. var counter;
  3621. ColliderManager.getCollidersNear(collider, function(tile) {
  3622. if (!tile.isTile) return false;
  3623. if (tile.isCounter && tile.intersects(collider)) {
  3624. counter = tile;
  3625. return 'break';
  3626. }
  3627. return false;
  3628. })
  3629. collider.moveTo(x1, y1);
  3630. if (counter) {
  3631. if ([4, 6].contains(direction)) {
  3632. var dist = Math.abs(counter.center.x - collider.center.x);
  3633. dist += collider.width;
  3634. } else if ([8, 2].contains(direction)) {
  3635. var dist = Math.abs(counter.center.y - collider.center.y);
  3636. dist += collider.height;
  3637. }
  3638. var x3 = $gameMap.roundPXWithDirection(x1, direction, dist);
  3639. var y3 = $gameMap.roundPYWithDirection(y1, direction, dist);
  3640. return this.startMapEvent(x3, y3, triggers, true);
  3641. }
  3642. return false;
  3643. };
  3644.  
  3645. Game_Player.prototype.airshipHere = function() {
  3646. // TODO
  3647. return false;
  3648. };
  3649.  
  3650. Game_Player.prototype.shipBoatThere = function(x2, y2) {
  3651. // TODO
  3652. return false;
  3653. };
  3654.  
  3655. // TODO create follower support addon
  3656. Game_Player.prototype.moveStraight = function(d, dist) {
  3657. Game_Character.prototype.moveStraight.call(this, d, dist);
  3658. };
  3659.  
  3660. Game_Player.prototype.moveDiagonally = function(horz, vert) {
  3661. Game_Character.prototype.moveDiagonally.call(this, horz, vert);
  3662. };
  3663. })();
  3664.  
  3665. //-----------------------------------------------------------------------------
  3666. // Game_Event
  3667.  
  3668. (function() {
  3669. var Alias_Game_Event_clearPageSettings = Game_Event.prototype.clearPageSettings;
  3670. Game_Event.prototype.clearPageSettings = function() {
  3671. Alias_Game_Event_clearPageSettings.call(this);
  3672. this._ignoreCharacters = [];
  3673. };
  3674.  
  3675. var Alias_Game_Event_setupPageSettings = Game_Event.prototype.setupPageSettings;
  3676. Game_Event.prototype.setupPageSettings = function() {
  3677. Alias_Game_Event_setupPageSettings.call(this);
  3678. this.reloadColliders();
  3679. this.initialPosition();
  3680. this._typeRandomDir = null;
  3681. this._typeTowardPlayer = null;
  3682. var notes = this.notes(true);
  3683. var ignore = /<ignoreCharas:(.*?)>/i.exec(notes);
  3684. this._ignoreCharacters = [];
  3685. if (ignore) {
  3686. this._ignoreCharacters = ignore[1].split(',').map(function(s) {
  3687. return QPlus.charaIdToId(s);
  3688. })
  3689. }
  3690. };
  3691.  
  3692. Game_Event.prototype.initialPosition = function() {
  3693. var ox = /<ox[=|:](-?[0-9]+)>/i.exec(this.comments(true)) || 0;
  3694. var oy = /<oy[=|:](-?[0-9]+)>/i.exec(this.comments(true)) || 0;
  3695. if (ox) ox = Number(ox[1]) || 0;
  3696. if (oy) oy = Number(oy[1]) || 0;
  3697. var nextOffset = new Point(ox, oy);
  3698. if (this._initialOffset) {
  3699. ox -= this._initialOffset.x;
  3700. oy -= this._initialOffset.y;
  3701. }
  3702. this._initialOffset = nextOffset;
  3703. this.setPixelPosition(this.px + ox, this.py + oy);
  3704. };
  3705.  
  3706. Game_Event.prototype.defaultColliderConfig = function() {
  3707. return QMovement.eventCollider;
  3708. };
  3709.  
  3710. Game_Event.prototype.ignoreCharacters = function(type) {
  3711. var ignores = Game_CharacterBase.prototype.ignoreCharacters.call(this, type);
  3712. return ignores.concat(this._ignoreCharacters);
  3713. };
  3714.  
  3715. Game_Event.prototype.updateStop = function() {
  3716. if (this._locked) {
  3717. this._freqCount = this.freqThreshold();
  3718. this.resetStopCount();
  3719. }
  3720. Game_Character.prototype.updateStop.call(this);
  3721. if (!this.isMoveRouteForcing()) {
  3722. this.updateSelfMovement();
  3723. }
  3724. };
  3725.  
  3726. Game_Event.prototype.updateSelfMovement = function() {
  3727. if (!this._locked && this.isNearTheScreen()) {
  3728. if (this._freqCount < this.freqThreshold()) {
  3729. switch (this._moveType) {
  3730. case 1:
  3731. this.moveTypeRandom();
  3732. break;
  3733. case 2:
  3734. this.moveTypeTowardPlayer();
  3735. break;
  3736. case 3:
  3737. this.moveTypeCustom();
  3738. break;
  3739. }
  3740. } else if (this.checkStop(this.stopCountThreshold())) {
  3741. this._freqCount = 0;
  3742. }
  3743. }
  3744. };
  3745.  
  3746. // TODO stop random dir from reseting every frame if event can't move
  3747. Game_Event.prototype.moveTypeRandom = function() {
  3748. if (this._freqCount === 0 || this._typeRandomDir === null) {
  3749. this._typeRandomDir = 2 * (Math.randomInt(4) + 1);
  3750. }
  3751. if (!this.canPixelPass(this._px, this._py, this._typeRandomDir)) {
  3752. this._typeRandomDir = 2 * (Math.randomInt(4) + 1);
  3753. }
  3754. this.moveStraight(this._typeRandomDir);
  3755. };
  3756.  
  3757. Game_Event.prototype.moveTypeTowardPlayer = function() {
  3758. if (this.isNearThePlayer()) {
  3759. if (this._freqCount === 0 || this._typeTowardPlayer === null) {
  3760. this._typeTowardPlayer = Math.randomInt(6);
  3761. }
  3762. switch (this._typeTowardPlayer) {
  3763. case 0: case 1: case 2: case 3: {
  3764. this.moveTowardPlayer();
  3765. break;
  3766. }
  3767. case 4: {
  3768. this.moveTypeRandom();
  3769. break;
  3770. }
  3771. case 5: {
  3772. this.moveForward();
  3773. break;
  3774. }
  3775. }
  3776. } else {
  3777. this.moveTypeRandom();
  3778. }
  3779. };
  3780.  
  3781. Game_Event.prototype.checkEventTriggerTouch = function(x, y) {
  3782. if (!$gameMap.isEventRunning()) {
  3783. if (this._trigger === 2 && !this.isJumping() && this.isNormalPriority()) {
  3784. var collider = this.collider('collision');
  3785. var prevX = collider.x;
  3786. var prevY = collider.y;
  3787. collider.moveTo(x, y);
  3788. var collided = false;
  3789. ColliderManager.getCharactersNear(collider, (function(chara) {
  3790. if (chara.constructor !== Game_Player) return false;
  3791. collided = chara.collider('collision').intersects(collider);
  3792. return 'break';
  3793. }).bind(this));
  3794. collider.moveTo(prevX, prevY);
  3795. if (collided) {
  3796. this._stopCount = 0;
  3797. this._freqCount = this.freqThreshold();
  3798. this.start();
  3799. }
  3800. }
  3801. }
  3802. };
  3803. })();
  3804.  
  3805. //-----------------------------------------------------------------------------
  3806. // Scene_Map
  3807.  
  3808. (function() {
  3809. Input.keyMapper[121] = 'f10';
  3810.  
  3811. var Alias_Scene_Map_updateMain = Scene_Map.prototype.updateMain;
  3812. Scene_Map.prototype.updateMain = function() {
  3813. Alias_Scene_Map_updateMain.call(this);
  3814. var key = Imported.QInput ? '#f10' : 'f10';
  3815. if ($gameTemp.isPlaytest() && Input.isTriggered(key)) {
  3816. ColliderManager.toggle();
  3817. }
  3818. ColliderManager.update();
  3819. };
  3820.  
  3821. Scene_Map.prototype.processMapTouch = function() {
  3822. if (TouchInput.isTriggered() || this._touchCount > 0) {
  3823. if (TouchInput.isPressed()) {
  3824. if (this._touchCount === 0 || this._touchCount >= 20) {
  3825. var x = $gameMap.canvasToMapPX(TouchInput.x);
  3826. var y = $gameMap.canvasToMapPY(TouchInput.y);
  3827. if (!$gameMap.offGrid()) {
  3828. var ox = x % QMovement.tileSize;
  3829. var oy = y % QMovement.tileSize;
  3830. x += QMovement.tileSize / 2 - ox;
  3831. y += QMovement.tileSize / 2 - oy;
  3832. }
  3833. $gameTemp.setPixelDestination(x, y);
  3834. }
  3835. this._touchCount++;
  3836. } else {
  3837. this._touchCount = 0;
  3838. }
  3839. }
  3840. };
  3841.  
  3842. Scene_Map.prototype.updateCallMenu = function() {
  3843. if (this.isMenuEnabled()) {
  3844. if (this.isMenuCalled()) {
  3845. this.menuCalling = true;
  3846. }
  3847. if (this.menuCalling && !$gamePlayer.startedMoving()) {
  3848. $gameScreen.erasePicture(7);
  3849. this.callMenu();
  3850. }
  3851. } else {
  3852. this.menuCalling = false;
  3853. }
  3854. };
  3855. })();
  3856.  
  3857. //-----------------------------------------------------------------------------
  3858. // Sprite_Collider
  3859.  
  3860. function Sprite_Collider() {
  3861. this.initialize.apply(this, arguments);
  3862. }
  3863.  
  3864. (function() {
  3865. Sprite_Collider.prototype = Object.create(Sprite.prototype);
  3866. Sprite_Collider.prototype.constructor = Sprite_Collider;
  3867.  
  3868. Sprite_Collider.prototype.initialize = function(collider, duration) {
  3869. Sprite.prototype.initialize.call(this);
  3870. this.z = 7;
  3871. this._duration = duration || 0;
  3872. this._cache = {};
  3873. this.setupCollider(collider);
  3874. this.checkChanges();
  3875. };
  3876.  
  3877. Sprite_Collider.prototype.setCache = function() {
  3878. this._cache = {
  3879. color: this._collider.color,
  3880. width: this._collider.width,
  3881. height: this._collider.height,
  3882. radian: this._collider._radian
  3883. }
  3884. };
  3885.  
  3886. Sprite_Collider.prototype.needsRedraw = function() {
  3887. return this._cache.width !== this._collider.width ||
  3888. this._cache.height !== this._collider.height ||
  3889. this._cache.color !== this._collider.color ||
  3890. this._cache.radian !== this._collider._radian
  3891. };
  3892.  
  3893. Sprite_Collider.prototype.setupCollider = function(collider) {
  3894. this._collider = collider;
  3895. var isNew = false;
  3896. if (!this._colliderSprite) {
  3897. this._colliderSprite = new PIXI.Graphics();
  3898. isNew = true;
  3899. }
  3900. this.drawCollider();
  3901. if (isNew) {
  3902. this.addChild(this._colliderSprite);
  3903. }
  3904. };
  3905.  
  3906. Sprite_Collider.prototype.drawCollider = function() {
  3907. var collider = this._collider;
  3908. this._colliderSprite.clear();
  3909. var color = (collider.color || '#ff0000').replace('#', '');
  3910. color = parseInt(color, 16);
  3911. this._colliderSprite.beginFill(color);
  3912. if (collider.isCircle()) {
  3913. var radiusX = collider.radiusX;
  3914. var radiusY = collider.radiusY;
  3915. this._colliderSprite.drawEllipse(0, 0, radiusX, radiusY);
  3916. this._colliderSprite.rotation = collider._radian;
  3917. } else {
  3918. this._colliderSprite.drawPolygon(collider._baseVertices);
  3919. }
  3920. this._colliderSprite.endFill();
  3921. };
  3922.  
  3923. Sprite_Collider.prototype.update = function() {
  3924. Sprite.prototype.update.call(this);
  3925. this.checkChanges();
  3926. if (this._duration >= 0 || this._collider.kill) {
  3927. this.updateDecay();
  3928. }
  3929. };
  3930.  
  3931. Sprite_Collider.prototype.checkChanges = function() {
  3932. this.visible = !this._collider._isHidden;
  3933. this.x = this._collider.x + this._collider.ox;
  3934. this.x -= $gameMap.displayX() * QMovement.tileSize;
  3935. this.y = this._collider.y + this._collider.oy;
  3936. this.y -= $gameMap.displayY() * QMovement.tileSize;
  3937. if (this.x < -this._collider.width || this.x > Graphics.width) {
  3938. if (this.y < -this._collider.height || this.y > Graphics.height) {
  3939. this.visible = false;
  3940. }
  3941. }
  3942. this._colliderSprite.z = this.z;
  3943. this._colliderSprite.visible = this.visible;
  3944. if (this.needsRedraw()) {
  3945. this.drawCollider();
  3946. this.setCache();
  3947. }
  3948. };
  3949.  
  3950. Sprite_Collider.prototype.updateDecay = function() {
  3951. this._duration--;
  3952. if (this._duration <= 0 || this._collider.kill) {
  3953. ColliderManager.removeSprite(this);
  3954. this._collider = null;
  3955. }
  3956. };
  3957. })();
  3958.  
  3959. //-----------------------------------------------------------------------------
  3960. // Sprite_Destination
  3961. //
  3962. // The sprite for displaying the destination place of the touch input.
  3963.  
  3964. (function() {
  3965. Sprite_Destination.prototype.updatePosition = function() {
  3966. var tileWidth = $gameMap.tileWidth();
  3967. var tileHeight = $gameMap.tileHeight();
  3968. var x = $gameTemp.destinationPX();
  3969. var y = $gameTemp.destinationPY();
  3970. this.x = $gameMap.adjustPX(x);
  3971. this.y = $gameMap.adjustPY(y);
  3972. };
  3973. })();
  3974.  
  3975. //-----------------------------------------------------------------------------
  3976. // Spriteset_Map
  3977.  
  3978. (function() {
  3979. var Alias_Spriteset_Map_createLowerLayer = Spriteset_Map.prototype.createLowerLayer;
  3980. Spriteset_Map.prototype.createLowerLayer = function() {
  3981. Alias_Spriteset_Map_createLowerLayer.call(this);
  3982. if ($gameTemp.isPlaytest()) {
  3983. this.createColliders();
  3984. }
  3985. };
  3986.  
  3987. Spriteset_Map.prototype.createColliders = function() {
  3988. this.addChild(ColliderManager.container);
  3989. // also get collision map here
  3990. };
  3991. })();
  3992.  
  3993.  
Tags: rpg maker mv
Advertisement
Add Comment
Please, Sign In to add comment