Advertisement
Guest User

Pixel Movement Extra Options

a guest
Aug 25th, 2014
587
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 78.47 KB | None | 0 0
  1. #==============================================================================
  2. #
  3. # GaryCXJk - Free Movement v0.86
  4. # * Last Updated: 2013.08.02
  5. # * Level: Medium
  6. # * Requires: N/A
  7. # * Optional: CXJ - AnimEx v1.01+
  8. #
  9. #==============================================================================
  10.  
  11. $imported = {} if $imported.nil?
  12. $imported["CXJ-FreeMovement"] = true
  13.  
  14. #==============================================================================
  15. #
  16. # Changelog:
  17. #
  18. #------------------------------------------------------------------------------
  19. # 2013.08.02 - v0.86
  20. #
  21. # * Added: Follow types
  22. # * Fixed: Jumping not going in the right direction
  23. #
  24. #------------------------------------------------------------------------------
  25. # 2013.07.06 - v0.85
  26. #
  27. # * Fixed: Touch events get triggered when moving after transfers
  28. #
  29. #------------------------------------------------------------------------------
  30. # 2013.06.09 - v0.84
  31. #
  32. # * Added: Capabilities to disable Free Movement per map
  33. #
  34. #------------------------------------------------------------------------------
  35. # 2013.01.12 - v0.83
  36. #
  37. # * Added: Option to only let the closest event get triggered
  38. # * Added: Event comment tags for event collision boxes
  39. #
  40. #------------------------------------------------------------------------------
  41. # 2013.01.12 - v0.82
  42. #
  43. # * Added: Map notetags for event collision boxes
  44. # * Fixed: In case the initializor of Game_CharacterBase gets overridden, the
  45. #          script would fail on a certain check
  46. #
  47. #------------------------------------------------------------------------------
  48. # 2013.01.11 - v0.81
  49. #
  50. # * Fixed: Vehicles could be boarded even if not on the map
  51. #
  52. #------------------------------------------------------------------------------
  53. # 2013.01.11 - v0.80
  54. #
  55. # * Initial release
  56. #
  57. #==============================================================================
  58. #
  59. # RPG Maker VX Ace is mainly constrained to the grid. Luckily there are quite
  60. # some scripts that add off-the-grid movement, mainly called "pixel movement".
  61. # As that's kind of a BS term for something like that (it implies you can only
  62. # travel per pixel, and most of the time it skips a few pixels anyway), I just
  63. # give it a more general term.
  64. #
  65. # Free Movement gives you freedom of movement in eight directions. I'd love to
  66. # implement free movement in three dimensions, but the engine isn't built on
  67. # 3D. Yet.
  68. #
  69. #==============================================================================
  70. #
  71. # Installation:
  72. #
  73. # Make sure to put this below Materials, but above Main Process.
  74. #
  75. # This script overrides several methods. If you are sure no method that is
  76. # used by other scripts get overridden, you can place it anywhere, otherwise,
  77. # make sure this script is loaded first. Do know that there is a possibility
  78. # that this script will stop working due to that.
  79. #
  80. # This script adds aliases for several methods. If you are sure no method that
  81. # is used by other scripts get overridden, you can place it anywhere,
  82. # otherwise, make sure this script is loaded after any other script overriding
  83. # these methods, otherwise this script stops working.
  84. #
  85. # This script has additional functionality and / or compatibility with other
  86. # scripts. In order to benefit the most out of it, it is advised to place this
  87. # script after the others.
  88. #
  89. #------------------------------------------------------------------------------
  90. # Overridden functions:
  91. #
  92. # * class Game_Player
  93. #   - move_by_input
  94. #
  95. #------------------------------------------------------------------------------
  96. # Aliased methods:
  97. #
  98. # * class Game_Map
  99. #   - setup(map_id)
  100. #   - check_passage(x, y, bit)
  101. #   - refresh setup_events
  102. #   - round_x_with_direction(x, d)
  103. #   - round_y_with_direction(y, d)
  104. # * class Game_CharacterBase
  105. #   - initialize
  106. #   - update
  107. #   - check_event_trigger_touch_front
  108. #   - passable?(x, y, d)
  109. #   - diagonal_passable?(x, y, horz, vert)
  110. #   - set_direction(d)
  111. #   - move_straight(d, turn_ok = true)
  112. #   - move_diagonal(horz, vert)
  113. #   - collide_with_events?(x, y)
  114. #   - collide_with_vehicles?(x, y)
  115. #   - update_jump
  116. #   - jump_height
  117. # * class Game_Character
  118. #   - process_move_command(command)
  119. #   - move_random
  120. #   - move_toward_character(character)
  121. #   - move_away_from_character(character)
  122. #   - move_forward
  123. #   - move_backward
  124. #   - jump(x_plus, y_plus)
  125. # * class Game_Player
  126. #   - initialize
  127. #   - refresh
  128. #   - perform_transfer
  129. #   - make_encounter_count
  130. #   - update_nonmoving(last_moving)
  131. #   - start_map_event(x, y, triggers, normal, rect = collision_rect)
  132. #   - check_event_trigger_there(triggers)
  133. #   - get_on_vehicle
  134. #   - get_off_vehicle
  135. #   - map_passable_rect?(x, y, d, rect)
  136. #   - move_diagonal(horz, vert)
  137. #   - collide_with_vehicles?(x, y)
  138. # * class Game_Event
  139. #   - init_public_members
  140. #   - update
  141. #   - refresh
  142. #   - collide_with_player_characters?(x, y)
  143. #   - check_event_trigger_touch(x, y)
  144. # * class Game_Followers
  145. #   - move
  146. # * class Game_Follower
  147. #   - initialize(member_index, preceding_character)
  148. #   - refresh
  149. #   - chase_preceding_character
  150. # * class Game_Vehicle
  151. #   - land_ok?(x, y, d)
  152. # * class Spriteset_Map (When debug is enabled)
  153. #   - create_characters
  154. #   - update_characters
  155. #
  156. #==============================================================================
  157. #
  158. # Usage:
  159. #
  160. # In essence, this script is plug-and-play, however, one can make minor to
  161. # big tweaks to this script without having to touch the actual script. Most of
  162. # the settings in the script are self-explanatory, however, there are two
  163. # things that need explaining.
  164. #
  165. # This script uses collision boxes to determine collisions. As not every sprite
  166. # is of the same size, and even events have different shapes, I wanted to add
  167. # a way to allow for these differences in size. At the moment there are only
  168. # collision boxes for characters and events.
  169. #
  170. # There are two kinds of collision boxes, the regular collision boxes and the
  171. # interaction boxes, the latter being reserved for active player characters.
  172. #
  173. # Collision boxes are for the regular collisions, like passability on terrain,
  174. # or just regular touch events. There are four ways you can define a collsion
  175. # box.
  176. #
  177. # The first is using this script, and by either altering the default settings
  178. # or creating a new collision list. This same collision list is used for the
  179. # vehicles. To actually be able to use this list, you'll need to call it by
  180. # using the following notetag on the actor:
  181. #
  182. # <collisionbox: string>
  183. #
  184. # You can also directly set the collision box on the actor:
  185. #
  186. # <collisionbox: x, y, width, height>
  187. #
  188. # Finally, since events don't use notetags, you can set the collisions using
  189. # either a script, notetags placed on the map itself or comment tags on the
  190. # event itself. For the script method I've added a method to the interpreter,
  191. # so you can just run it directly from the event without having to find the
  192. # event itself. There are  two ways you can use the method.
  193. #
  194. # set_collision_rect(string)
  195. # set_collision_rect(x, y, width, height)
  196. #
  197. # The first way calls the collision box from the collision list. The second
  198. # directly sets the collision. Do note that collision boxes set this way aren't
  199. # persistent, so when the map is reloaded, the script must be run again.
  200. #
  201. # You can also use notetags on the map to define the collision box of the
  202. # event. You'll also need to supply the event name so that it can identify
  203. # which event should get the new collision box.
  204. #
  205. # <collisionbox eventname: string>
  206. # <collisionbox eventname: x, y, width, height>
  207. #
  208. # To make it even more easy to implement collision boxes, you can use the
  209. # following comment tags on the comment blocks in the event itself:
  210. #
  211. # <collisionbox: string>
  212. # <collisionbox: x, y, width, height>
  213. #
  214. # You can use this in two ways. When placed on the first page, it acts as the
  215. # default collision box. This can still be overridden by the map notetag or
  216. # a script, but it's used as the default. However, when placed on a different
  217. # page, it will use that comment page whenever that page is available. That
  218. # means that you can actually use switches or variables to dynamically set
  219. # the collision box without having to use scripts.
  220. #
  221. # There are two ways to set an interaction box. One is by using the interaction
  222. # list, just like how you set a collision list. Do note that each interaction
  223. # entry contains eight values, each representing a direction. Note that the
  224. # collisions are relative to the origin position plus 32 in the direction the
  225. # interaction box is set, so you don't have to correct for that. To use a
  226. # certain list, you can use the following notetag on the actor:
  227. #
  228. # <interactionbox: string>
  229. #
  230. # You can also directly set the collision box on the actor:
  231. #
  232. # <interactionbox d: x, y, width, height>
  233. #
  234. # Note that d is a number, representing a direction.
  235. #
  236. # As it is sometimes hard to see if the collisions work as expected, you can
  237. # enable debugging, which actually shows the collision boxes. Green boxes
  238. # represent collision boxes, while the red box represents the interaction box.
  239. #
  240. # Finally, there might be reasons to disable this script on certain maps. You
  241. # can do so by changing the settings for auto-enable to false, or by using the
  242. # following notetag in the map:
  243. #
  244. # <free-movement-enabled true|false>
  245. #
  246. # This setting has precedence over the global settings.
  247. #
  248. #==============================================================================
  249. #
  250. # License:
  251. #
  252. # Creative Commons Attribution 3.0 Unported
  253. #
  254. # The complete license can be read here:
  255. # http://creativecommons.org/licenses/by/3.0/legalcode
  256. #
  257. # The license as it is described below can be read here:
  258. # http://creativecommons.org/licenses/by/3.0/deed
  259. #
  260. # You are free:
  261. #
  262. # to Share — to copy, distribute and transmit the work
  263. # to Remix — to adapt the work
  264. # to make commercial use of the work
  265. #
  266. # Under the following conditions:
  267. #
  268. # Attribution — You must attribute the work in the manner specified by the
  269. # author or licensor (but not in any way that suggests that they endorse you or
  270. # your use of the work).
  271. #
  272. # With the understanding that:
  273. #
  274. # Waiver — Any of the above conditions can be waived if you get permission from
  275. # the copyright holder.
  276. #
  277. # Public Domain — Where the work or any of its elements is in the public domain
  278. # under applicable law, that status is in no way affected by the license.
  279. #
  280. # Other Rights — In no way are any of the following rights affected by the
  281. # license:
  282. #
  283. # * Your fair dealing or fair use rights, or other applicable copyright
  284. #   exceptions and limitations;
  285. # * The author's moral rights;
  286. # * Rights other persons may have either in the work itself or in how the work
  287. #   is used, such as publicity or privacy rights.
  288. #
  289. # Notice — For any reuse or distribution, you must make clear to others the
  290. # license terms of this work. The best way to do this is with a link to this
  291. # web page.
  292. #
  293. #------------------------------------------------------------------------------
  294. # Extra notes:
  295. #
  296. # Despite what the license tells you, I will not hunt down anybody who doesn't
  297. # follow the license in regards to giving credits. However, as it is common
  298. # courtesy to actually do give credits, it is recommended that you do.
  299. #
  300. # As I picked this license, you are free to share this script through any
  301. # means, which includes hosting it on your own website, selling it on eBay and
  302. # hang it in the bathroom as toilet paper. Well, not selling it on eBay, that's
  303. # a dick move, but you are still free to redistribute the work.
  304. #
  305. # Yes, this license means that you can use it for both non-commercial as well
  306. # as commercial software.
  307. #
  308. # You are free to pick the following names when you give credit:
  309. #
  310. # * GaryCXJk
  311. # * Gary A.M. Kertopermono
  312. # * G.A.M. Kertopermono
  313. # * GARYCXJK
  314. #
  315. # Personally, when used in commercial games, I prefer you would use the second
  316. # option. Not only will it actually give me more name recognition in real
  317. # life, which also works well for my portfolio, it will also look more
  318. # professional. Also, do note that I actually care about capitalization if you
  319. # decide to use my username, meaning, capital C, capital X, capital J, lower
  320. # case k. Yes, it might seem stupid, but it's one thing I absolutely care
  321. # about.
  322. #
  323. # Finally, if you want my endorsement for your product, if it's good enough
  324. # and I have the game in my posession, I might endorse it. Do note that if you
  325. # give me the game for free, it will not affect my opinion of the game. It
  326. # would be nice, but if I really did care for the game I'd actually purchase
  327. # it. Remember, the best way to get any satisfaction is if you get people to
  328. # purchase the game, so in a way, I prefer it if you don't actually give me
  329. # a free copy.
  330. #
  331. # This script was originally hosted on:
  332. # http://area91.multiverseworks.com
  333. #
  334. #==============================================================================
  335. #
  336. # The code below defines the settings of this script, and are there to be
  337. # modified.
  338. #
  339. #==============================================================================
  340. module Euphoria
  341.   module EventCollisionFix
  342.    
  343.     EVENT_COLL_BOX_X = 8   #X-position of the events collision box, 0 will
  344.                            #probably start it at the very left of the event 32
  345.                            #will set it on the far right.
  346.    
  347.     EVENT_COLL_BOX_Y = 8   #Y-position of the events collision box, 0 will
  348.                            #probably start it at the very top of the event 32
  349.                            #will set it at the bottom.
  350.    
  351.     EVENT_COLL_BOX_W = 16  #Width of the events collision box, self-explanatory
  352.    
  353.     EVENT_COLL_BOX_H = 16  #Height of the events collision box, self-explanatory
  354.    
  355.   end
  356. end
  357. module CXJ
  358.   module FREE_MOVEMENT
  359.    
  360.     # Auto-enable Free Movement
  361.     AUTO_ENABLE = true
  362.    
  363.     # Enables diagonal movement.
  364.     ENABLE_DIAGONAL = true
  365.    
  366.     #------------------------------------------------------------------------
  367.     # The collision box for actors and vehicles.
  368.     # The key defines the name of the list. The values themselves represent
  369.     # the x and y of the starting position, and the width and height of the
  370.     # box.
  371.     #------------------------------------------------------------------------
  372.     COLLISION = {}
  373.     COLLISION["DEFAULT"] = [8, 12, 16, 20]
  374.     COLLISION["BOAT"] = [4, 4, 24, 24]
  375.     COLLISION["SHIP"] = [2, 2, 28, 28]
  376.     COLLISION["AIRSHIP"] = [4, 4, 24, 24]
  377.    
  378.     #------------------------------------------------------------------------
  379.     # The interaction boxes for player characters.
  380.     # The key defines the name of the list. Each list contains eight values,
  381.     # each being separate key-value pairs, where the key is a direction and
  382.     # the values the x and y of the starting position, and the width and
  383.     # height of the box.
  384.     #------------------------------------------------------------------------
  385.     INTERACTION = {}
  386.     INTERACTION["DEFAULT"] = {
  387.     1 => [24, -8, 24, 24],
  388.     2 => [4, 0, 24, 24],
  389.     3 => [-16, -8, 24, 24],
  390.     4 => [16, 10, 24, 24],
  391.     6 => [-8, 10, 24, 24],
  392.     7 => [24, 28, 24, 24],
  393.     8 => [4, 20, 24, 24],
  394.     9 => [-16, 28, 24, 24],
  395.     }
  396.    
  397.     # The amount of pixels per step the character can move.
  398.     PIXELS_PER_STEP = 2
  399.    
  400.     # The distance between followers.
  401.     FOLLOWERS_DISTANCE = 32
  402.    
  403.     # The margin between which followers try to correct their distance.
  404.     FOLLOWERS_DISTANCE_MARGIN = 2
  405.  
  406.     # The speed of the jump animation, in relationship to the original jump
  407.     # speed.
  408.     JUMP_SPEED = 0.5
  409.    
  410.     # Jump height. Set to 0 to let the jump height be dependent on the jump
  411.     # length. In pixels.
  412.     MAX_JUMP_HEIGHT = 32
  413.  
  414.     # Determines if only the closest event is triggered.
  415.     ONLY_TRIGGER_CLOSEST = true
  416.  
  417.     # Allows you to enable or disable follower collision.
  418.     FOLLOWER_THROUGH = false
  419.    
  420.     # The way followers follow. Set to nil or a non-existent type to make
  421.     # followers use the shortest distance.
  422.     # :trace    - Followers always retrace your steps
  423.     FOLLOW_TYPE = :trace
  424.    
  425.     # Debug variables.
  426.     SHOW_COLLISION_BOXES = false
  427.   end
  428. end
  429. #==============================================================================
  430. #
  431. # The code below should not be altered unless you know what you're doing.
  432. #
  433. #==============================================================================
  434.  
  435. #==============================================================================
  436. # ** Game_Map
  437. #------------------------------------------------------------------------------
  438. #  This class handles maps. It includes scrolling and passage determination
  439. # functions. The instance of this class is referenced by $game_map.
  440. #==============================================================================
  441.  
  442. class Game_Map
  443.   #--------------------------------------------------------------------------
  444.   # * Override: Setup
  445.   #--------------------------------------------------------------------------
  446.   alias game_map_setup_fm setup
  447.   def setup(map_id)
  448.     game_map_setup_fm(map_id)
  449.     fm_enabled = 0
  450.     @map.note.split(/[\r\n]+/).each { |line|
  451.       if line =~ /\s*<free[ -]movement[ -]enabled (true|false)>\s*/i
  452.         fm_enabled = ($1 == "true" ? 1 : -1);
  453.       end
  454.     }
  455.    
  456.     if(fm_enabled == 0)
  457.       @free_movement_enabled = CXJ::FREE_MOVEMENT::AUTO_ENABLE
  458.     else
  459.       @free_movement_enabled = (fm_enabled > 0 ? true : false)
  460.     end
  461.   end
  462.  
  463.   #--------------------------------------------------------------------------
  464.   # * New: Check if it's the Free Movement map class
  465.   #--------------------------------------------------------------------------
  466.   def free_movement_enabled?
  467.     return @free_movement_enabled
  468.   end
  469.  
  470.   #--------------------------------------------------------------------------
  471.   # * New: Determine Valid Coordinates
  472.   #--------------------------------------------------------------------------
  473.   def valid_rect?(x, y, rect)
  474.     x2 = x + (rect.x / 32.0)
  475.     y2 = y + (rect.y / 32.0)
  476.     x3 = x2 + ((rect.width - 1) / 32.0)
  477.     y3 = y2 + ((rect.height - 1) / 32.0)
  478.     round_x(x2) >= 0 && round_x(x3) < width && round_y(y2) >= 0 && round_y(y3) < height
  479.   end
  480.   #--------------------------------------------------------------------------
  481.   # * Alias: Check Passage
  482.   #     bit:  Inhibit passage check bit
  483.   #--------------------------------------------------------------------------
  484.   alias game_map_check_passage_cxj_fm check_passage
  485.   def check_passage(x, y, bit)
  486.     if(free_movement_enabled?)
  487.       x = round_x(x)
  488.       y = round_y(y)
  489.       all_tiles(x.floor, y.floor).each do |tile_id|
  490.         flag = tileset.flags[tile_id]
  491.         next if flag & 0x10 != 0            # [☆]: No effect on passage
  492.         return true  if flag & bit == 0     # [○] : Passable
  493.         return false if flag & bit == bit   # [×] : Impassable
  494.       end
  495.       return false                          # Impassable
  496.     else
  497.       return game_map_check_passage_cxj_fm(x, y, bit)
  498.     end
  499.   end
  500.   #--------------------------------------------------------------------------
  501.   # * New: Determine Passability of Normal Character
  502.   #     d:  direction (2,4,6,8)
  503.   #    Determines whether the tile at the specified coordinates is passable
  504.   #    in the specified direction.
  505.   #--------------------------------------------------------------------------
  506.   def passable_rect?(x, y, d, rect)
  507.     x2 = x + (rect.x / 32.0)
  508.     y2 = y + (rect.y / 32.0)
  509.     x3 = x2 + ((rect.width - 1) / 32.0)
  510.     y3 = y2 + ((rect.height - 1) / 32.0)
  511.     x4 = (x2 + x3) / 2.0
  512.     y4 = (y2 + y3) / 2.0
  513.     if((x2.floor != x3.floor && [1, 3, 4, 6, 7, 9].include?(d)) || (y2.floor != y3.floor && [1, 2, 3, 7, 8, 9].include?(d)))
  514.       return false if ([1, 2, 3].include?(d) && !check_passage(x2, y2, 1)) || ([3, 6, 9].include?(d) && !check_passage(x2, y2, 4))
  515.       return false if ([3, 6, 9].include?(d) && !check_passage(x2, y3, 4)) || ([7, 8, 9].include?(d) && !check_passage(x2, y3, 8))
  516.       return false if ([1, 2, 3].include?(d) && !check_passage(x3, y2, 1)) || ([1, 4, 7].include?(d) && !check_passage(x3, y2, 2))
  517.       return false if ([1, 4, 7].include?(d) && !check_passage(x3, y3, 2)) || ([7, 8, 9].include?(d) && !check_passage(x3, y3, 8))
  518.     end
  519.     return true
  520.   end
  521.   #--------------------------------------------------------------------------
  522.   # * New: Determine if Passable by Boat
  523.   #--------------------------------------------------------------------------
  524.   def boat_passable_rect?(x, y, rect)
  525.     x2 = x + (rect.x / 32.0)
  526.     y2 = y + (rect.y / 32.0)
  527.     x3 = x2 + ((rect.width - 1) / 32.0)
  528.     y3 = y2 + ((rect.height - 1) / 32.0)
  529.     return false unless check_passage(x2, y2, 0x0200)
  530.     return false unless check_passage(x2, y3, 0x0200)
  531.     return false unless check_passage(x3, y2, 0x0200)
  532.     return check_passage(x3, y3, 0x0200)
  533.   end
  534.   #--------------------------------------------------------------------------
  535.   # * New: Determine if Passable by Ship
  536.   #--------------------------------------------------------------------------
  537.   def ship_passable_rect?(x, y, rect)
  538.     x2 = x + (rect.x / 32.0)
  539.     y2 = y + (rect.y / 32.0)
  540.     x3 = x2 + ((rect.width - 1) / 32.0)
  541.     y3 = y2 + ((rect.height - 1) / 32.0)
  542.     return false unless check_passage(x2, y2, 0x0400)
  543.     return false unless check_passage(x2, y3, 0x0400)
  544.     return false unless check_passage(x3, y2, 0x0400)
  545.     return check_passage(x3, y3, 0x0400)
  546.   end
  547.   #--------------------------------------------------------------------------
  548.   # * New: Determine if Airship can Land
  549.   #--------------------------------------------------------------------------
  550.   def airship_land_ok_rect?(x, y, rect)
  551.     x2 = x + (rect.x / 32.0)
  552.     y2 = y + (rect.y / 32.0)
  553.     x3 = x2 + ((rect.width - 1) / 32.0)
  554.     y3 = y2 + ((rect.height - 1) / 32.0)
  555.     return false unless check_passage(x2, y2, 0x0800) && check_passage(x2, y2, 0x0f)
  556.     return false unless check_passage(x2, y3, 0x0800) && check_passage(x2, y3, 0x0f)
  557.     return false unless check_passage(x3, y2, 0x0800) && check_passage(x3, y2, 0x0f)
  558.     return check_passage(x3, y3, 0x0800) && check_passage(x3, y3, 0x0f)
  559.   end
  560.  
  561.   #--------------------------------------------------------------------------
  562.   # * Alias: Refresh
  563.   #--------------------------------------------------------------------------
  564.   alias game_map_refresh_cxj_fm refresh
  565.   def refresh
  566.     game_map_refresh_cxj_fm
  567.     refresh_event_collision
  568.   end
  569.  
  570.   #--------------------------------------------------------------------------
  571.   # * Alias: Event Setup
  572.   #--------------------------------------------------------------------------
  573.   alias game_map_setup_events_cxj_fm setup_events
  574.   def setup_events
  575.     game_map_setup_events_cxj_fm
  576.     refresh_event_collision
  577.   end
  578.  
  579.   #--------------------------------------------------------------------------
  580.   # * New: Refresh Event Collision
  581.   #--------------------------------------------------------------------------
  582.   def refresh_event_collision
  583.     if(free_movement_enabled?)
  584.       temp_list = {}
  585.       @map.note.split(/[\r\n]+/).each { |line|
  586.         collision = []
  587.         event_name = ''
  588.         case line
  589.         when /<collisionbox (.+?):[ ]*(\d+),[ ]*(\d+),[ ]*(\d+),[ ]*(\d+)>/i
  590.           collision = [$2, $3, $4, $5]
  591.           event_name = $1
  592.         when /<collisionbox (.+?):[ ]*(.+?)>/i
  593.           collision = CXJ::FREE_MOVEMENT::COLLISION[$2] if !CXJ::FREE_MOVEMENT::COLLISION[$2].nil?
  594.           event_name = $1
  595.         end
  596.         if !event_name.empty? && !collision.empty?
  597.           temp_list[event_name] = collision
  598.         end
  599.       }
  600.       @events.each_value {|event|
  601.         if temp_list.has_key?(event.name)
  602.           collision = temp_list[event.name]
  603.           event.set_collision_rect(collision[0], collision[1], collision[2], collision[3])
  604.         end
  605.       }
  606.     end
  607.   end
  608.  
  609.   #--------------------------------------------------------------------------
  610.   # * New: Get Array of Events at Designated Coordinates
  611.   #--------------------------------------------------------------------------
  612.   def events_xy_rect(x, y, rect)
  613.     @events.values.select {|event| event.pos_rect?(x, y, rect) }
  614.   end
  615.   #--------------------------------------------------------------------------
  616.   # * New: Get Array of Events at Designated Coordinates (Except Pass-Through)
  617.   #--------------------------------------------------------------------------
  618.   def events_xy_rect_nt(x, y, rect)
  619.     @events.values.select {|event| event.pos_rect_nt?(x, y, rect) }
  620.   end
  621.   #--------------------------------------------------------------------------
  622.   # * New: Get Array of Tile-Handling Events at Designated Coordinates
  623.   #   (Except Pass-Through)
  624.   #--------------------------------------------------------------------------
  625.   def tile_events_xy_rect(x, y, rect)
  626.     @tile_events.select {|event| event.pos_rect_nt?(x, y, rect) }
  627.   end
  628.   #--------------------------------------------------------------------------
  629.   # * Alias: Calculate X Coordinate Shifted One Tile in Specific Direction
  630.   #   (With Loop Adjustment)
  631.   #--------------------------------------------------------------------------
  632.   alias game_map_round_x_with_direction_cxj_fm round_x_with_direction
  633.   def round_x_with_direction(x, d)
  634.     if(free_movement_enabled?)
  635.       round_x(x + ((d - 1) % 3 - 1))
  636.     else
  637.       game_map_round_x_with_direction_cxj_fm(x, d)
  638.     end
  639.   end
  640.   #--------------------------------------------------------------------------
  641.   # * Alias: Calculate Y Coordinate Shifted One Tile in Specific Direction
  642.   #   (With Loop Adjustment)
  643.   #--------------------------------------------------------------------------
  644.   alias game_map_round_y_with_direction_cxj_fm round_y_with_direction
  645.   def round_y_with_direction(y, d)
  646.     if(free_movement_enabled?)
  647.       round_y(y + (1 - ((d - 1) / 3)))
  648.     else
  649.       game_map_round_y_with_direction_cxj_fm(y, d)
  650.     end
  651.   end
  652. end
  653.  
  654. #==============================================================================
  655. # ** Game_CharacterBase
  656. #------------------------------------------------------------------------------
  657. #  This base class handles characters. It retains basic information, such as
  658. # coordinates and graphics, shared by all characters.
  659. #==============================================================================
  660.  
  661. class Game_CharacterBase
  662.   attr_accessor :move_poll
  663.   #--------------------------------------------------------------------------
  664.   # * Alias: Object Initialization
  665.   #--------------------------------------------------------------------------
  666.   alias game_characterbase_initialize_cxj_fm initialize
  667.   def initialize
  668.     game_characterbase_initialize_cxj_fm
  669.     @old_x = @real_x
  670.     @old_y = @real_y
  671.     @pos_list = []
  672.     @move_poll = []
  673.   end
  674.   #--------------------------------------------------------------------------
  675.   # * Alias: Frame Update
  676.   #
  677.   # Added processing of movement being polled.
  678.   #--------------------------------------------------------------------------
  679.   alias game_characterbase_update_cxj_fm update
  680.   def update
  681.     @old_x = @real_x
  682.     @old_y = @real_y
  683.     if($game_map.free_movement_enabled?)
  684.       interpret_move unless moving?
  685.     end
  686.     game_characterbase_update_cxj_fm
  687.   end
  688.   #--------------------------------------------------------------------------
  689.   # * New: Get Pos List Length
  690.   #--------------------------------------------------------------------------
  691.   def pos_list_size
  692.     @pos_list.size
  693.   end
  694.   #--------------------------------------------------------------------------
  695.   # * New: Get Coordinates From Pos List
  696.   #--------------------------------------------------------------------------
  697.   def get_coords_from_pos_list
  698.     return @pos_list.shift
  699.   end
  700.   #--------------------------------------------------------------------------
  701.   # * New: Clear Pos List
  702.   #--------------------------------------------------------------------------
  703.   def clear_pos_list
  704.     @pos_list.clear
  705.   end
  706.   #--------------------------------------------------------------------------
  707.   # * New: Movement Interpreting
  708.   #     Interprets the polled movement.
  709.   #--------------------------------------------------------------------------
  710.   def interpret_move(step_left = distance_per_frame)
  711.     @move_poll = [] if @move_poll.nil?
  712.     if @move_poll.size > 0
  713.       current_move = @move_poll.shift()
  714.       d = current_move[0]
  715.       horz = (d - 1) % 3 - 1
  716.       vert = 1 - ((d - 1) / 3)
  717.       turn_ok = current_move[1]
  718.       set_direction(d) if turn_ok
  719.       check_event_trigger_touch_front
  720.       processed = false
  721.       if (d % 2 == 0 && passable?(@x, @y, d)) || (d % 2 != 0 && diagonal_passable?(@x, @y, horz, vert))
  722.         process_move(horz, vert)
  723.         processed = true
  724.       elsif d % 2 != 0 && !diagonal_passable?(@x, @y, horz, vert)
  725.         if passable?(@x, @y, horz + 5)
  726.           set_direction(horz + 5) if turn_ok
  727.           process_move(horz, 0)
  728.           processed = true
  729.         end
  730.         if passable?(@x, @y, 5 - vert * 3)
  731.           set_direction(5 - vert * 3) if turn_ok
  732.           process_move(0, vert)
  733.           processed = true
  734.         end
  735.       end
  736.       if(processed)
  737.         pixelstep = CXJ::FREE_MOVEMENT::PIXELS_PER_STEP / 32.0
  738.         if(step_left > pixelstep && !@move_poll.empty?)
  739.           interpret_move(step_left - pixelstep)
  740.         elsif(jumping? && !@move_poll.empty?)
  741.           interpret_move(0)
  742.         end
  743.       else
  744.         @move_poll.clear
  745.       end
  746.       current_move
  747.     end
  748.   end
  749.  
  750.   #--------------------------------------------------------------------------
  751.   # * New: Processes Movement
  752.   #--------------------------------------------------------------------------
  753.   def process_move(horz, vert)
  754.     pixelstep = CXJ::FREE_MOVEMENT::PIXELS_PER_STEP / 32.0
  755.     @x = @x + horz * pixelstep
  756.     @y = @y + vert * pixelstep
  757.     @pos_list.push({:x => @real_x, :y => @real_y})
  758.     @pos_list.shift if @pos_list.size > CXJ::FREE_MOVEMENT::FOLLOWERS_DISTANCE * 2
  759.     if(!jumping?)
  760.       @x = $game_map.round_x(@x)
  761.       @y = $game_map.round_y(@y)
  762.       @real_x = @x - horz * pixelstep
  763.       @real_y = @y - vert * pixelstep
  764.       increase_steps
  765.     end
  766.   end
  767.   #--------------------------------------------------------------------------
  768.   # * Alias: Determine Triggering of Frontal Touch Event
  769.   #--------------------------------------------------------------------------
  770.   alias game_characterbase_check_event_trigger_touch_front_cxj_fm check_event_trigger_touch_front
  771.   def check_event_trigger_touch_front
  772.     if $game_map.free_movement_enabled?
  773.       d = @direction
  774.       horz = (d - 1) % 3 - 1
  775.       vert = 1 - ((d - 1) / 3)
  776.       pixelstep = CXJ::FREE_MOVEMENT::PIXELS_PER_STEP / 32.0
  777.       x2 = $game_map.round_x(x + horz * pixelstep)
  778.       y2 = $game_map.round_y(y + vert * pixelstep)
  779.       check_event_trigger_touch(x2, y2)
  780.     else
  781.       game_characterbase_check_event_trigger_touch_front_cxj_fm
  782.     end
  783.   end
  784.   #--------------------------------------------------------------------------
  785.   # * New: Collision Rectangle
  786.   #     Gets the collision rectangle.
  787.   #--------------------------------------------------------------------------
  788.   def collision_rect
  789.     collision = CXJ::FREE_MOVEMENT::COLLISION["DEFAULT"]
  790.     return Rect.new(collision[0], collision[1], collision[2], collision[3])
  791.   end
  792.   #--------------------------------------------------------------------------
  793.   # * Alias: Determine if Passable
  794.   #     d : Direction (2,4,6,8)
  795.   #--------------------------------------------------------------------------
  796.   alias game_characterbase_passable_cxj_fm? passable?
  797.   def passable?(x, y, d)
  798.     if $game_map.free_movement_enabled?
  799.       horz = (d - 1) % 3 - 1
  800.       vert = 1 - ((d - 1) / 3)
  801.       pixelstep = CXJ::FREE_MOVEMENT::PIXELS_PER_STEP / 32.0
  802.       x2 = $game_map.round_x(x + horz * pixelstep)
  803.       y2 = $game_map.round_y(y + vert * pixelstep)
  804.       return false unless $game_map.valid_rect?(x2, y2, collision_rect)
  805.       return true if @through || debug_through?
  806.       return false unless map_passable_rect?(x, y, d, collision_rect)
  807.       return false unless map_passable_rect?(x2, y2, reverse_dir(d), collision_rect)
  808.       return false if collide_with_characters?(x2, y2)
  809.       return true
  810.     else
  811.       return game_characterbase_passable_cxj_fm?(x, y, d)
  812.     end
  813.   end
  814.   #--------------------------------------------------------------------------
  815.   # * Alias: Determine Diagonal Passability
  816.   #     horz : Horizontal (4 or 6)
  817.   #     vert : Vertical (2 or 8)
  818.   #--------------------------------------------------------------------------
  819.   alias game_characterbase_diagonal_passable_cxj_fm? diagonal_passable?
  820.   def diagonal_passable?(x, y, horz, vert)
  821.     if $game_map.free_movement_enabled?
  822.       pixelstep = CXJ::FREE_MOVEMENT::PIXELS_PER_STEP / 32.0
  823.       x2 = $game_map.round_x(x + horz * pixelstep)
  824.       y2 = $game_map.round_y(y + vert * pixelstep)
  825.       d = (horz == 4 ? -1 : 1) + (vert == 2 ? -3 : 3) + 5
  826.       return passable?(x2, y2, d) && passable?(x2, y2, horz) && passable?(x2, y2, vert)
  827.     else
  828.       return game_characterbase_diagonal_passable_cxj_fm?(x, y, horz, vert)
  829.     end
  830.   end
  831.   #--------------------------------------------------------------------------
  832.   # * New: Determine if Map is Passable
  833.   #     d : Direction (2,4,6,8)
  834.   #--------------------------------------------------------------------------
  835.   def map_passable_rect?(x, y, d, rect)
  836.     $game_map.passable_rect?(x, y, d, rect)
  837.   end
  838.   #--------------------------------------------------------------------------
  839.   # * Alias: Change Direction to Designated Direction
  840.   #     d : Direction (2,4,6,8)
  841.   #
  842.   # Fix for diagonal movement.
  843.   #--------------------------------------------------------------------------
  844.   alias game_characterbase_set_direction_cxj_fm set_direction
  845.   def set_direction(d)
  846.     if $game_map.free_movement_enabled?
  847.       if !@direction_fix && d != 0
  848.         @direction = d
  849.         if d % 2 != 0 && (!$imported["CXJ-AnimEx"] || !@has_diagonal)
  850.           @direction+= 1
  851.           @direction-= 2 if d > 5
  852.           @direction = 10 - direction if d > 2 && d < 8
  853.         end
  854.       end
  855.       @stop_count = 0
  856.     else
  857.       game_characterbase_set_direction_cxj_fm(d)
  858.     end
  859.   end
  860.   #--------------------------------------------------------------------------
  861.   # * Alias: Move Straight
  862.   #     d:        Direction (2,4,6,8)
  863.   #     turn_ok : Allows change of direction on the spot
  864.   #
  865.   # Polls the movement instead of processing them immediately.
  866.   #--------------------------------------------------------------------------
  867.   alias game_characterbase_move_straight_cxj_fm move_straight
  868.   def move_straight(d, turn_ok = true)
  869.     if $game_map.free_movement_enabled?
  870.       pixelstep = CXJ::FREE_MOVEMENT::PIXELS_PER_STEP / 32.0
  871.       @move_poll+= [[d, turn_ok]] * (distance_per_frame / pixelstep).ceil
  872.     else
  873.       game_characterbase_move_straight_cxj_fm(d, turn_ok)
  874.     end
  875.   end
  876.   #--------------------------------------------------------------------------
  877.   # * Alias: Move Diagonally
  878.   #     horz:  Horizontal (4 or 6)
  879.   #     vert:  Vertical (2 or 8)
  880.   #
  881.   # Polls the movement instead of processing them immediately.
  882.   #--------------------------------------------------------------------------
  883.   alias game_characterbase_move_diagonal_cxj_fm move_diagonal
  884.   def move_diagonal(horz, vert)
  885.     if $game_map.free_movement_enabled?
  886.       pixelstep = CXJ::FREE_MOVEMENT::PIXELS_PER_STEP / 32.0
  887.       @move_poll+= [[vert + (horz > 5 ? 1 : -1), true]] * (distance_per_frame / pixelstep).ceil
  888.     else
  889.       game_characterbase_move_diagonal_cxj_fm(horz, vert)
  890.     end
  891.   end
  892.   #--------------------------------------------------------------------------
  893.   # * New: Determine Coordinate Match
  894.   #--------------------------------------------------------------------------
  895.   def pos_rect?(x, y, rect)
  896.     main_left = @x + collision_rect.x / 32.0
  897.     main_top = @y + collision_rect.y / 32.0
  898.     main_right = main_left + (collision_rect.width - 1) / 32.0
  899.     main_bottom = main_top + (collision_rect.height - 1) / 32.0
  900.     other_left = x + rect.x / 32.0
  901.     other_top = y + rect.y / 32.0
  902.     other_right = other_left + (rect.width - 1) / 32.0
  903.     other_bottom = other_top + (rect.height - 1) / 32.0
  904.     coltest = true
  905.     coltest = false if main_right < other_left
  906.     coltest = false if main_left > other_right
  907.     coltest = false if main_bottom < other_top
  908.     coltest = false if main_top > other_bottom
  909.     if coltest == false && ($game_map.loop_horizontal? || $game_map.loop_vertical?) && x <= $game_map.width && y <= $game_map.height
  910.       return true if $game_map.loop_horizontal? && pos_rect?(x + $game_map.width, y, rect)
  911.       return true if $game_map.loop_vertical? && pos_rect?(x, y + $game_map.height, rect)
  912.     end
  913.     return coltest
  914.   end
  915.   #--------------------------------------------------------------------------
  916.   # * New: Determine if Coordinates Match and Pass-Through Is Off (nt = No Through)
  917.   #--------------------------------------------------------------------------
  918.   def pos_rect_nt?(x, y, rect)
  919.     pos_rect?(x, y, rect) && !@through
  920.   end
  921.   #--------------------------------------------------------------------------
  922.   # * Alias: Detect Collision with Event
  923.   #--------------------------------------------------------------------------
  924.   alias game_characterbase_collide_with_events_cxj_fm? collide_with_events?
  925.   def collide_with_events?(x, y)
  926.     if $game_map.free_movement_enabled?
  927.       $game_map.events_xy_rect_nt(x, y, collision_rect).any? do |event|
  928.         (event.normal_priority? || self.is_a?(Game_Event)) && event != self
  929.       end
  930.     else
  931.       game_characterbase_collide_with_events_cxj_fm?(x, y)
  932.     end
  933.   end
  934.   #--------------------------------------------------------------------------
  935.   # * Alias: Detect Collision with Vehicle
  936.   #--------------------------------------------------------------------------
  937.   alias game_characterbase_collide_with_vehicles_cxj_fm? collide_with_vehicles?
  938.   def collide_with_vehicles?(x, y)
  939.     if $game_map.free_movement_enabled?
  940.       $game_map.boat.pos_rect_nt?(x, y, collision_rect) || $game_map.ship.pos_rect_nt?(x, y, collision_rect)
  941.     else
  942.       game_characterbase_collide_with_vehicles_cxj_fm?(x, y)
  943.     end
  944.   end
  945.   #--------------------------------------------------------------------------
  946.   # * Alias: Update While Jumping
  947.   #--------------------------------------------------------------------------
  948.   alias game_characterbase_update_jump_cxj_fm update_jump
  949.   def update_jump
  950.     if $game_map.free_movement_enabled?
  951.       @jump_count -= 1
  952.       diff_x = @real_x
  953.       @real_x = (@real_x * @jump_count + @x) / (@jump_count + 1.0)
  954.       @real_y = (@real_y * @jump_count + @y) / (@jump_count + 1.0)
  955.       update_bush_depth
  956.       if @jump_count == 0
  957.         @real_x = @x = $game_map.round_x(@x)
  958.         @real_y = @y = $game_map.round_y(@y)
  959.       end
  960.     else
  961.       game_characterbase_update_jump_cxj_fm
  962.     end
  963.   end
  964.   #--------------------------------------------------------------------------
  965.   # * Alias: Calculate Jump Height
  966.   #--------------------------------------------------------------------------
  967.   alias game_characterbase_jump_height_cxj_fm jump_height
  968.   def jump_height
  969.     if $game_map.free_movement_enabled?
  970.       ((@jump_peak * @jump_peak - (@jump_count * CXJ::FREE_MOVEMENT::JUMP_SPEED - @jump_peak).abs ** 2) / 2) * (CXJ::FREE_MOVEMENT::MAX_JUMP_HEIGHT > 0 && @jump_peak > 0 ? (CXJ::FREE_MOVEMENT::MAX_JUMP_HEIGHT * 2.0) / (@jump_peak ** 2) : 1)
  971.     else
  972.       game_characterbase_jump_height_cxj_fm
  973.     end
  974.   end
  975. end
  976. #==============================================================================
  977. # ** Game_Character
  978. #------------------------------------------------------------------------------
  979. #  A character class with mainly movement route and other such processing
  980. # added. It is used as a super class of Game_Player, Game_Follower,
  981. # GameVehicle, and Game_Event.
  982. #==============================================================================
  983.  
  984. class Game_Character < Game_CharacterBase
  985.   #--------------------------------------------------------------------------
  986.   # * Alias: Move at Random
  987.   #--------------------------------------------------------------------------
  988.   alias game_character_move_random_cxj_fm move_random
  989.   def move_random
  990.     if $game_map.free_movement_enabled?
  991.       @move_poll+= [[2 + rand(4) * 2, true]] * ((24.0 + (rand(160) / 10) ) / CXJ::FREE_MOVEMENT::PIXELS_PER_STEP).ceil
  992.     else
  993.       game_character_move_random_cxj_fm
  994.     end
  995.   end
  996.   #--------------------------------------------------------------------------
  997.   # * Alias: Move Toward Character
  998.   #--------------------------------------------------------------------------
  999.   alias game_character_move_toward_character_cxj_fm move_toward_character
  1000.   def move_toward_character(character)
  1001.     if $game_map.free_movement_enabled?
  1002.       sx = distance_x_from(character.x)
  1003.       sy = distance_y_from(character.y)
  1004.       if sx.abs > sy.abs
  1005.         if passable?(@x, @y, (sx > 0 ? 4 : 6))
  1006.           @move_poll+= [[sx > 0 ? 4 : 6, true]] * (32.0 / CXJ::FREE_MOVEMENT::PIXELS_PER_STEP).ceil
  1007.         else
  1008.           @move_poll+= [[sy > 0 ? 8 : 2, true]] * (32.0 / CXJ::FREE_MOVEMENT::PIXELS_PER_STEP).ceil
  1009.         end
  1010.       elsif sy != 0
  1011.         if passable?(@x, @y, (sy > 0 ? 8 : 2))
  1012.           @move_poll+= [[sy > 0 ? 8 : 2, true]] * (32.0 / CXJ::FREE_MOVEMENT::PIXELS_PER_STEP).ceil
  1013.         else
  1014.           @move_poll+= [[sx > 0 ? 4 : 6, true]] * (32.0 / CXJ::FREE_MOVEMENT::PIXELS_PER_STEP).ceil
  1015.         end
  1016.       end
  1017.     else
  1018.       game_character_move_toward_character_cxj_fm(character)
  1019.     end
  1020.   end
  1021.   #--------------------------------------------------------------------------
  1022.   # * Alias: Move Away from Character
  1023.   #--------------------------------------------------------------------------
  1024.   alias game_character_move_away_from_character_cxj_fm move_away_from_character
  1025.   def move_away_from_character(character)
  1026.     if $game_map.free_movement_enabled?
  1027.       sx = distance_x_from(character.x)
  1028.       sy = distance_y_from(character.y)
  1029.       if sx.abs > sy.abs
  1030.         if passable?(@x, @y, (sx > 0 ? 6 : 4))
  1031.           @move_poll+= [[sx > 0 ? 6 : 4, true]] * (32.0 / CXJ::FREE_MOVEMENT::PIXELS_PER_STEP).ceil
  1032.         else
  1033.           @move_poll+= [[sy > 0 ? 2 : 8, true]] * (32.0 / CXJ::FREE_MOVEMENT::PIXELS_PER_STEP).ceil
  1034.         end
  1035.       elsif sy != 0
  1036.         if passable?(@x, @y, (sy > 0 ? 2 : 8))
  1037.           @move_poll+= [[sy > 0 ? 2 : 8, true]] * (32.0 / CXJ::FREE_MOVEMENT::PIXELS_PER_STEP).ceil
  1038.         else
  1039.           @move_poll+= [[sx > 0 ? 6 : 4, true]] * (32.0 / CXJ::FREE_MOVEMENT::PIXELS_PER_STEP).ceil
  1040.         end
  1041.       end
  1042.     else
  1043.       game_character_move_away_from_character_cxj_fm(character)
  1044.     end
  1045.   end
  1046.   #--------------------------------------------------------------------------
  1047.   # * Alias: 1 Step Forward
  1048.   #--------------------------------------------------------------------------
  1049.   alias game_character_move_forward_cxj_fm move_forward
  1050.   def move_forward
  1051.     if $game_map.free_movement_enabled?
  1052.       @move_poll+= [[@direction, true]] * (32.0 / CXJ::FREE_MOVEMENT::PIXELS_PER_STEP).ceil
  1053.     else
  1054.       game_character_move_forward_cxj_fm
  1055.     end
  1056.   end
  1057.   #--------------------------------------------------------------------------
  1058.   # * Alias: 1 Step Backward
  1059.   #--------------------------------------------------------------------------
  1060.   alias game_character_move_backward_cxj_fm move_backward
  1061.   def move_backward
  1062.     if $game_map.free_movement_enabled?
  1063.       last_direction_fix = @direction_fix
  1064.       @direction_fix = true
  1065.       @move_poll+= [[reverse_dir(@direction), false]] * (32.0 / CXJ::FREE_MOVEMENT::PIXELS_PER_STEP).ceil
  1066.       @direction_fix = last_direction_fix
  1067.     else
  1068.       game_character_move_backward_cxj_fm
  1069.     end
  1070.   end
  1071.   #--------------------------------------------------------------------------
  1072.   # * Alias: Jump
  1073.   #     x_plus : x-coordinate plus value
  1074.   #     y_plus : y-coordinate plus value
  1075.   #--------------------------------------------------------------------------
  1076.   alias game_character_jump_cxj_fm jump
  1077.   def jump(x_plus, y_plus)
  1078.     if $game_map.free_movement_enabled?
  1079.       #if x_plus.abs > y_plus.abs
  1080.       #  set_direction(x_plus < 0 ? 4 : 6) if x_plus != 0
  1081.       #else
  1082.       #  set_direction(y_plus < 0 ? 8 : 2) if y_plus != 0
  1083.       #end
  1084.       distance = Math.sqrt(x_plus * x_plus + y_plus * y_plus).round
  1085.       pollcount = distance * (32.0 / CXJ::FREE_MOVEMENT::PIXELS_PER_STEP).ceil
  1086.       #@move_poll+= [[(x_plus < 0 ? -1 : x_plus > 0 ? 1 : 0) + (y_plus < 0 ? 8 : y_plus > 0 ? 2 : 5), false]] * pollcount
  1087.       @x+= x_plus
  1088.       @y+= y_plus
  1089.       @jump_peak = 10 + distance - @move_speed
  1090.       @jump_count = @jump_peak / CXJ::FREE_MOVEMENT::JUMP_SPEED * 2
  1091.       @stop_count = 0
  1092.       straighten
  1093.     else
  1094.       game_character_jump_cxj_fm
  1095.     end
  1096.   end
  1097.   #--------------------------------------------------------------------------
  1098.   # * Alias: Process Move Command
  1099.   #--------------------------------------------------------------------------
  1100.   alias game_character_process_move_command_cxj_fm process_move_command
  1101.   def process_move_command(command)
  1102.     if $game_map.free_movement_enabled?
  1103.       case command.code
  1104.       when ROUTE_MOVE_DOWN;         @move_poll+= [[2, true]] * (32.0 / CXJ::FREE_MOVEMENT::PIXELS_PER_STEP).ceil
  1105.       when ROUTE_MOVE_LEFT;         @move_poll+= [[4, true]] * (32.0 / CXJ::FREE_MOVEMENT::PIXELS_PER_STEP).ceil
  1106.       when ROUTE_MOVE_RIGHT;        @move_poll+= [[6, true]] * (32.0 / CXJ::FREE_MOVEMENT::PIXELS_PER_STEP).ceil
  1107.       when ROUTE_MOVE_UP;           @move_poll+= [[8, true]] * (32.0 / CXJ::FREE_MOVEMENT::PIXELS_PER_STEP).ceil
  1108.       when ROUTE_MOVE_LOWER_L;      @move_poll+= [[1, true]] * (32.0 / CXJ::FREE_MOVEMENT::PIXELS_PER_STEP).ceil
  1109.       when ROUTE_MOVE_LOWER_R;      @move_poll+= [[3, true]] * (32.0 / CXJ::FREE_MOVEMENT::PIXELS_PER_STEP).ceil
  1110.       when ROUTE_MOVE_UPPER_L;      @move_poll+= [[7, true]] * (32.0 / CXJ::FREE_MOVEMENT::PIXELS_PER_STEP).ceil
  1111.       when ROUTE_MOVE_UPPER_R;      @move_poll+= [[9, true]] * (32.0 / CXJ::FREE_MOVEMENT::PIXELS_PER_STEP).ceil
  1112.       else;                         game_character_process_move_command_cxj_fm(command)
  1113.       end
  1114.     else
  1115.       game_character_process_move_command_cxj_fm(command)
  1116.     end
  1117.   end
  1118. end
  1119. #==============================================================================
  1120. # ** Game_Player
  1121. #------------------------------------------------------------------------------
  1122. #  This class handles the player. It includes event starting determinants and
  1123. # map scrolling functions. The instance of this class is referenced by
  1124. # $game_player.
  1125. #==============================================================================
  1126.  
  1127. class Game_Player < Game_Character
  1128.   #--------------------------------------------------------------------------
  1129.   # * Alias: Object Initialization
  1130.   #--------------------------------------------------------------------------
  1131.   alias game_player_initialize_cxj_fm initialize
  1132.   def initialize
  1133.     @last_poll = []
  1134.     game_player_initialize_cxj_fm
  1135.     @custom_collision = nil
  1136.     @interaction = CXJ::FREE_MOVEMENT::INTERACTION["DEFAULT"]
  1137.   end
  1138.   #--------------------------------------------------------------------------
  1139.   # * Alias: Refresh
  1140.   #--------------------------------------------------------------------------
  1141.   alias game_player_refresh_cxj_fm refresh
  1142.   def refresh
  1143.     game_player_refresh_cxj_fm
  1144.     return if actor.nil? || !$game_map.free_movement_enabled?
  1145.     @custom_collision = nil
  1146.     @interaction = CXJ::FREE_MOVEMENT::INTERACTION["DEFAULT"]
  1147.     actor.actor.note.split(/[\r\n]+/).each { |line|
  1148.       case line
  1149.       when /<collisionbox:[ ]*(\d+),[ ]*(\d+),[ ]*(\d+),[ ]*(\d+)>/i
  1150.         @custom_collision = Rect.new($1, $2, $3, $4)
  1151.       when /<collisionbox:[ ]*(.+?)>/i
  1152.         collision = CXJ::FREE_MOVEMENT::COLLISION[$1] if !CXJ::FREE_MOVEMENT::COLLISION[$1].nil?
  1153.         @custom_collision = Rect.new(collision[0], collision[1], collision[2], collision[3])
  1154.       when /<interactionbox (\d+):[ ]*(\d+),[ ]*(\d+),[ ]*(\d+),[ ]*(\d+)>/i
  1155.         @interaction[$1] = [$2, $3, $4, $5] if $1 > 0 && $1 < 10
  1156.       when /<interactionbox:[ ]*(.+?)>/i
  1157.         @interaction = CXJ::FREE_MOVEMENT::INTERACTION[$1] if !CXJ::FREE_MOVEMENT::INTERACTION[$1].nil?
  1158.       end
  1159.     }
  1160.   end
  1161.   #--------------------------------------------------------------------------
  1162.   # * Alias: Execute Player Transfer
  1163.   #--------------------------------------------------------------------------
  1164.   alias game_player_perform_transfer_cxj_fm perform_transfer
  1165.   def perform_transfer
  1166.     is_transfer = transfer?
  1167.     game_player_perform_transfer_cxj_fm
  1168.     if is_transfer && $game_map.free_movement_enabled?
  1169.       @pos_list.clear
  1170.         @followers.clear_pos_list
  1171.       $game_map.events_xy_rect(x, y, collision_rect).each do |event|
  1172.         if event.trigger_in?([1,2]) && event.normal_priority? == false
  1173.           event.add_touch(self)
  1174.         end
  1175.       end
  1176.     end
  1177.   end
  1178.   #--------------------------------------------------------------------------
  1179.   # * New: Movement Interpreting
  1180.   #     Interprets the polled movement.
  1181.   #--------------------------------------------------------------------------
  1182.   def interpret_move(step_left = distance_per_frame)
  1183.     current_move = super(step_left)
  1184.     @last_poll.push(current_move) if !current_move.nil?
  1185.   end
  1186.   #--------------------------------------------------------------------------
  1187.   # * New: Collision Rectangle
  1188.   #     Gets the collision rectangle.
  1189.   #--------------------------------------------------------------------------
  1190.   def collision_rect
  1191.     key = @vehicle_type.id2name.upcase
  1192.     if @vehicle_type != :walk && !CXJ::FREE_MOVEMENT::COLLISION[key].nil?
  1193.       collision = CXJ::FREE_MOVEMENT::COLLISION[key]
  1194.       return Rect.new(collision[0], collision[1], collision[2] - 1, collision[3] - 1)
  1195.     end
  1196.     return @custom_collision if !@custom_collision.nil?
  1197.     return super
  1198.   end
  1199.   #--------------------------------------------------------------------------
  1200.   # * New: Interaction Rectangle
  1201.   #     Gets the interaction rectangle.
  1202.   #--------------------------------------------------------------------------
  1203.   def interaction_rect
  1204.     collision = @interaction[@direction]
  1205.     if collision.nil?
  1206.       return collision_rect
  1207.     end
  1208.     return Rect.new(collision[0], collision[1], collision[2], collision[3])
  1209.   end
  1210.   #--------------------------------------------------------------------------
  1211.   # * Override: Processing of Movement via Input from Directional Buttons
  1212.   #
  1213.   # Added diagonal movement.
  1214.   #--------------------------------------------------------------------------
  1215.   def move_by_input
  1216.     return if !movable? || $game_map.interpreter.running?
  1217.     if CXJ::FREE_MOVEMENT::ENABLE_DIAGONAL && Input.dir8 > 0 && Input.dir8 % 2 != 0
  1218.       d = Input.dir8
  1219.       horz = (d == 1 || d == 7 ? 4 : 6)
  1220.       vert = (d == 1 || d == 3 ? 2 : 8)
  1221.       move_diagonal(horz, vert)
  1222.     elsif Input.dir4 > 0
  1223.       move_straight(Input.dir4)
  1224.     end
  1225.   end
  1226.   #--------------------------------------------------------------------------
  1227.   # * New: Detect Collision (Including Followers)
  1228.   #--------------------------------------------------------------------------
  1229.   def collide_rect?(x, y, rect)
  1230.     !@through && (pos_rect?(x, y, rect) || followers.collide_rect?(x, y, rect))
  1231.   end
  1232.   #--------------------------------------------------------------------------
  1233.   # * Alias: Trigger Map Event
  1234.   #     triggers : Trigger array
  1235.   #     normal   : Is priority set to [Same as Characters] ?
  1236.   #--------------------------------------------------------------------------
  1237.   alias game_player_start_map_event_cxj_fm start_map_event
  1238.   def start_map_event(x, y, triggers, normal, rect = collision_rect)
  1239.     if $game_map.free_movement_enabled?
  1240.       return if $game_map.interpreter.running?
  1241.       event_list = {}
  1242.       $game_map.events_xy_rect(x, y, rect).each do |event|
  1243.         if event.trigger_in?(triggers) && event.normal_priority? == normal
  1244.           if !CXJ::FREE_MOVEMENT::ONLY_TRIGGER_CLOSEST
  1245.             event.start unless event.is_touching?(self)
  1246.             event.add_touch(self)
  1247.           else
  1248.             dist_x = event.distance_x_from(@x)
  1249.             dist_y = event.distance_y_from(@y)
  1250.             event_list[event] = Math.hypot(dist_x, dist_y) unless event.is_touching?(self)
  1251.           end
  1252.         end
  1253.       end
  1254.       if !event_list.empty?
  1255.         current_event = nil
  1256.         current_dist = -1
  1257.         event_list.each do |event, dist|
  1258.           if current_event == nil || current_dist > dist
  1259.             current_event = event
  1260.             current_dist = dist
  1261.           end
  1262.         end
  1263.         current_event.start
  1264.         current_event.add_touch(self)
  1265.       end
  1266.     else
  1267.       game_player_start_map_event_cxj_fm(x, y, triggers, normal)
  1268.     end
  1269.   end
  1270.   #--------------------------------------------------------------------------
  1271.   # * Alias: Determine if Front Event is Triggered
  1272.   #--------------------------------------------------------------------------
  1273.   alias game_player_check_event_trigger_there_cxj_fm check_event_trigger_there
  1274.   def check_event_trigger_there(triggers)
  1275.     if $game_map.free_movement_enabled?
  1276.       x2 = $game_map.round_x_with_direction(@x, @direction)
  1277.       y2 = $game_map.round_y_with_direction(@y, @direction)
  1278.       start_map_event(x2, y2, triggers, true, interaction_rect)
  1279.       return if $game_map.any_event_starting?
  1280.       return unless $game_map.counter?(x2, y2)
  1281.       x3 = $game_map.round_x_with_direction(x2, @direction)
  1282.       y3 = $game_map.round_y_with_direction(y2, @direction)
  1283.       start_map_event(x3, y3, triggers, true, interaction_rect)
  1284.     else
  1285.       game_player_check_event_trigger_there_cxj_fm(triggers)
  1286.     end
  1287.   end
  1288.   #--------------------------------------------------------------------------
  1289.   # * Override: Board Vehicle
  1290.   #    Assumes that the player is not currently in a vehicle.
  1291.   #--------------------------------------------------------------------------
  1292.   alias game_player_get_on_vehicle_cxj_fm get_on_vehicle
  1293.   def get_on_vehicle
  1294.     if $game_map.free_movement_enabled?
  1295.       front_x = $game_map.round_x_with_direction(@x, @direction)
  1296.       front_y = $game_map.round_y_with_direction(@y, @direction)
  1297.       @vehicle_type = :boat    if $game_map.boat.pos_rect?(front_x, front_y, interaction_rect)
  1298.       @vehicle_type = :ship    if $game_map.ship.pos_rect?(front_x, front_y, interaction_rect)
  1299.       @vehicle_type = :airship if $game_map.airship.pos_rect?(@x, @y, collision_rect)
  1300.       if vehicle
  1301.         @vehicle_getting_on = true
  1302.         horz = (@x > vehicle.x ? -1 : @x < vehicle.x ? 1 : 0)
  1303.         vert = (@y > vehicle.y ? -3 : @y < vehicle.y ? 3 : 0)
  1304.         d = 5 + horz - vert
  1305.         set_direction(d)
  1306.         @x = vehicle.x
  1307.         @y = vehicle.y
  1308.         @followers.gather
  1309.         @pos_list.clear
  1310.         @followers.clear_pos_list
  1311.       end
  1312.       @vehicle_getting_on
  1313.     else
  1314.       game_player_get_on_vehicle_cxj_fm
  1315.     end
  1316.   end
  1317.   #--------------------------------------------------------------------------
  1318.   # * Override: Get Off Vehicle
  1319.   #    Assumes that the player is currently riding in a vehicle.
  1320.   #--------------------------------------------------------------------------
  1321.   alias game_player_get_off_vehicle_cxj_fm get_off_vehicle
  1322.   def get_off_vehicle
  1323.     if $game_map.free_movement_enabled?
  1324.       if vehicle.land_ok?(@x, @y, @direction)
  1325.         set_direction(2) if in_airship?
  1326.         @followers.synchronize(@x, @y, @direction)
  1327.         vehicle.get_off
  1328.         unless in_airship?
  1329.           @x = $game_map.round_x_with_direction(@x, @direction)
  1330.           @y = $game_map.round_y_with_direction(@y, @direction)
  1331.           @transparent = false
  1332.         end
  1333.         @vehicle_getting_off = true
  1334.         @move_speed = 4
  1335.         @through = false
  1336.         make_encounter_count
  1337.         @followers.gather
  1338.         @pos_list.clear
  1339.         @followers.clear_pos_list
  1340.       end
  1341.       @vehicle_getting_off
  1342.     else
  1343.       game_player_get_off_vehicle_cxj_fm
  1344.     end
  1345.   end
  1346.   #--------------------------------------------------------------------------
  1347.   # * New: Determine if Map is Passable
  1348.   #     d:  Direction (2,4,6,8)
  1349.   #--------------------------------------------------------------------------
  1350.   def map_passable_rect?(x, y, d, rect)
  1351.     case @vehicle_type
  1352.     when :boat
  1353.       $game_map.boat_passable_rect?(x, y, vehicle.collision_rect)
  1354.     when :ship
  1355.       $game_map.ship_passable_rect?(x, y, vehicle.collision_rect)
  1356.     when :airship
  1357.       true
  1358.     else
  1359.       super
  1360.     end
  1361.   end
  1362.   #--------------------------------------------------------------------------
  1363.   # * Alias: Move Diagonally
  1364.   #--------------------------------------------------------------------------
  1365.   alias game_player_move_diagonal_cxj_fm move_diagonal
  1366.   def move_diagonal(horz, vert)
  1367.     if $game_map.free_movement_enabled?
  1368.       @followers.move if diagonal_passable?(@x, @y, horz, vert) || passable?(@x, @y, horz + 5) || passable?(@x, @y, 5 - vert * 3)
  1369.       super
  1370.     else
  1371.       game_player_move_diagonal_cxj_fm(horz, vert)
  1372.     end
  1373.   end
  1374.   #--------------------------------------------------------------------------
  1375.   # * Alias: Create Encounter Count
  1376.   #--------------------------------------------------------------------------
  1377.   alias game_player_make_encounter_count_cxj_fm make_encounter_count
  1378.   def make_encounter_count
  1379.     game_player_make_encounter_count_cxj_fm
  1380.     @encounter_count*= (32 / CXJ::FREE_MOVEMENT::PIXELS_PER_STEP) + (32 / 2 < CXJ::FREE_MOVEMENT::PIXELS_PER_STEP ? 1 : 0) if $game_map.free_movement_enabled?
  1381.   end
  1382.   #--------------------------------------------------------------------------
  1383.   # * Alias: Detect Collision with Vehicle
  1384.   #--------------------------------------------------------------------------
  1385.   alias game_player_collide_with_vehicles_cxj_fm? collide_with_vehicles?
  1386.   def collide_with_vehicles?(x, y)
  1387.     return (@vehicle_type != :boat && $game_map.boat.pos_rect_nt?(x, y, collision_rect)) || (@vehicle_type != :ship && $game_map.ship.pos_rect_nt?(x, y, collision_rect)) if $game_map.free_movement_enabled?
  1388.     return game_player_collide_with_vehicles_cxj_fm?(x, y)
  1389.   end
  1390.   #--------------------------------------------------------------------------
  1391.   # * Alias: Processing When Not Moving
  1392.   #     last_moving : Was it moving previously?
  1393.   #--------------------------------------------------------------------------
  1394.   alias game_player_update_nonmoving_cxj_fm update_nonmoving
  1395.   def update_nonmoving(last_moving)
  1396.     game_player_update_nonmoving_cxj_fm(last_moving || @old_x != @real_x || @old_y != @real_y)
  1397.     return if $game_map.free_movement_enabled?
  1398.     update_encounter if !last_moving && !@last_poll.empty?
  1399.     @last_poll.clear
  1400.   end
  1401. end
  1402. #==============================================================================
  1403. # ** Game_Followers
  1404. #------------------------------------------------------------------------------
  1405. #  This is a wrapper for a follower array. This class is used internally for
  1406. # the Game_Player class.
  1407. #==============================================================================
  1408.  
  1409. class Game_Followers
  1410.   #--------------------------------------------------------------------------
  1411.   # * New: Detect Collision
  1412.   #--------------------------------------------------------------------------
  1413.   def collide_rect?(x, y, rect)
  1414.     visible_folloers.any? {|follower| follower.pos_rect?(x, y, rect) }
  1415.   end
  1416.   #--------------------------------------------------------------------------
  1417.   # * New: Clear Pos List
  1418.   #--------------------------------------------------------------------------
  1419.   def clear_pos_list
  1420.     reverse_each do |follower|
  1421.       follower.clear_pos_list
  1422.     end
  1423.   end
  1424.   #--------------------------------------------------------------------------
  1425.   # * Alias: Movement
  1426.   #--------------------------------------------------------------------------
  1427.   alias game_followers_move_cxj_fm move
  1428.   def move
  1429.     if $game_map.free_movement_enabled?
  1430.       reverse_each do |follower|
  1431.         if gathering?
  1432.           follower.board
  1433.         end
  1434.         follower.chase_preceding_character
  1435.       end
  1436.     else
  1437.       game_followers_move_cxj_fm
  1438.     end
  1439.   end
  1440. end
  1441. #==============================================================================
  1442. # ** Game_Vehicle
  1443. #------------------------------------------------------------------------------
  1444. #  This class handles vehicles. It's used within the Game_Map class. If there
  1445. # are no vehicles on the current map, the coordinates are set to (-1,-1).
  1446. #==============================================================================
  1447.  
  1448. class Game_Vehicle < Game_Character
  1449.   #--------------------------------------------------------------------------
  1450.   # * New: Collision Rectangle
  1451.   #     Gets the collision rectangle.
  1452.   #--------------------------------------------------------------------------
  1453.   def collision_rect
  1454.     collision = CXJ::FREE_MOVEMENT::COLLISION["DEFAULT"]
  1455.     key = @type.id2name.upcase
  1456.     collision = CXJ::FREE_MOVEMENT::COLLISION[key] if !CXJ::FREE_MOVEMENT::COLLISION[key].nil?
  1457.     return Rect.new(collision[0], collision[1], collision[2], collision[3])
  1458.   end
  1459.   #--------------------------------------------------------------------------
  1460.   # * New: Determine Coordinate Match
  1461.   #--------------------------------------------------------------------------
  1462.   def pos_rect?(x, y, rect)
  1463.     on_map? && super(x, y, rect)
  1464.   end
  1465.   #--------------------------------------------------------------------------
  1466.   # * New: Determine If On Map
  1467.   #--------------------------------------------------------------------------
  1468.   def on_map?
  1469.     @map_id == $game_map.map_id
  1470.   end
  1471.   #--------------------------------------------------------------------------
  1472.   # * Alias: Determine if Docking/Landing Is Possible
  1473.   #     d:  Direction (2,4,6,8)
  1474.   #--------------------------------------------------------------------------
  1475.   alias game_vehicle_land_ok_cxj_fm? land_ok?
  1476.   def land_ok?(x, y, d)
  1477.     return game_vehicle_land_ok_cxj_fm?(x, y, d) if !$game_map.free_movement_enabled?
  1478.     if @type == :airship
  1479.       return false unless $game_map.airship_land_ok_rect?(x, y, collision_rect)
  1480.       return false unless $game_map.events_xy_rect(x, y, collision_rect).empty?
  1481.     else
  1482.       x2 = $game_map.round_x_with_direction(x, d)
  1483.       y2 = $game_map.round_y_with_direction(y, d)
  1484.       return false unless $game_map.valid_rect?(x2, y2, collision_rect)
  1485.       return false unless $game_map.passable_rect?(x2, y2, reverse_dir(d), collision_rect)
  1486.       return false if collide_with_characters?(x2, y2)
  1487.     end
  1488.     return true
  1489.   end
  1490. end
  1491.  
  1492. #==============================================================================
  1493. # ** Game_Event
  1494. #------------------------------------------------------------------------------
  1495. #  This class handles events. Functions include event page switching via
  1496. # condition determinants and running parallel process events. Used within the
  1497. # Game_Map class.
  1498. #==============================================================================
  1499.  
  1500. class Game_Event < Game_Character
  1501.   #--------------------------------------------------------------------------
  1502.   # * Alias: Initialize Public Member Variables
  1503.   #--------------------------------------------------------------------------
  1504.   alias game_event_init_public_members_cxj_fm init_public_members
  1505.   def init_public_members
  1506.     game_event_init_public_members_cxj_fm
  1507.     @collisionbox = Rect.new(Euphoria::EventCollisionFix::EVENT_COLL_BOX_X,
  1508.       Euphoria::EventCollisionFix::EVENT_COLL_BOX_Y, Euphoria::EventCollisionFix::EVENT_COLL_BOX_W,
  1509.       Euphoria::EventCollisionFix::EVENT_COLL_BOX_H)
  1510.     @touch_chars = []
  1511.   end
  1512.   #--------------------------------------------------------------------------
  1513.   # * Alias: Frame Update
  1514.   #--------------------------------------------------------------------------
  1515.   alias game_event_update_cxj_fm update
  1516.   def update
  1517.     if $game_map.free_movement_enabled?
  1518.       temp_chars = []
  1519.       @touch_chars.each do |character|
  1520.         temp_chars.push(character) if character.pos_rect?(@x, @y, collision_rect)
  1521.       end
  1522.       @touch_chars = temp_chars
  1523.     end
  1524.     game_event_update_cxj_fm
  1525.   end
  1526.   #--------------------------------------------------------------------------
  1527.   # * Alias: Refresh
  1528.   #--------------------------------------------------------------------------
  1529.   alias game_event_refresh_cxj_fm refresh
  1530.   def refresh
  1531.     if !@event.pages.empty? && $game_map.free_movement_enabled?
  1532.       get_collision_from_comment(@event.pages[0].list)
  1533.     end
  1534.     game_event_refresh_cxj_fm
  1535.     set_current_collision if $game_map.free_movement_enabled?
  1536.   end
  1537.   #--------------------------------------------------------------------------
  1538.   # * New: Set Current Collision
  1539.   #--------------------------------------------------------------------------
  1540.   def set_current_collision
  1541.     @event.pages.each do |page|
  1542.       if conditions_met?(page)
  1543.         get_collision_from_comment(page.list)
  1544.       end
  1545.     end
  1546.   end
  1547.   #--------------------------------------------------------------------------
  1548.   # * New: Set Collision From Comment Tags
  1549.   #--------------------------------------------------------------------------
  1550.   def get_collision_from_comment(list)
  1551.     list.each do |command|
  1552.       if command.code == 108 || command.code == 408
  1553.         case command.parameters[0]
  1554.         when /<collisionbox:[ ]*(\d+),[ ]*(\d+),[ ]*(\d+),[ ]*(\d+)>/i
  1555.           @collisionbox = Rect.new($1, $2, $3, $4)
  1556.         when /<collisionbox:[ ]*(.+?)>/i
  1557.           collision = CXJ::FREE_MOVEMENT::COLLISION[$1] if !CXJ::FREE_MOVEMENT::COLLISION[$1].nil?
  1558.           @collisionbox = Rect.new(collision[0], collision[1], collision[2], collision[3])
  1559.         end
  1560.       end
  1561.     end
  1562.   end
  1563.   #--------------------------------------------------------------------------
  1564.   # * New: Initialize Public Member Variables
  1565.   #--------------------------------------------------------------------------
  1566.   def set_collision_rect(*args)
  1567.     return if args.empty?
  1568.     x = 0
  1569.     y = 0
  1570.     width = 32
  1571.     height = 32
  1572.     if args[0].instance_of?(String)
  1573.       collision = CXJ::FREE_MOVEMENT::COLLISION[args[0]]
  1574.       if !collision.nil? && !collision.empty?
  1575.         x = collision[0]
  1576.         y = collision[1]
  1577.         width = collision[2]
  1578.         height = collision[3]
  1579.       end
  1580.     else
  1581.       x = args[0]
  1582.       y = args[1] if args.size >=2
  1583.       width = args[2] if args.size >= 3
  1584.       height = args[3] if args.size >= 4
  1585.     end
  1586.     @collisionbox = Rect.new(x, y, width, height)
  1587.   end
  1588.   #--------------------------------------------------------------------------
  1589.   # * New: Collision Rectangle
  1590.   #     Gets the collision rectangle.
  1591.   #--------------------------------------------------------------------------
  1592.   def collision_rect
  1593.     return @collisionbox
  1594.   end
  1595.   #--------------------------------------------------------------------------
  1596.   # * Alias: Detect Collision with Player (Including Followers)
  1597.   #--------------------------------------------------------------------------
  1598.   alias game_event_collide_with_player_characters_cxj_fm? collide_with_player_characters?
  1599.   def collide_with_player_characters?(x, y)
  1600.     return game_event_collide_with_player_characters_cxj_fm?(x, y) if !$game_map.free_movement_enabled?
  1601.     normal_priority? && $game_player.collide_rect?(x, y, collision_rect)
  1602.   end
  1603.   #--------------------------------------------------------------------------
  1604.   # * Alias: Determine if Touch Event is Triggered
  1605.   #--------------------------------------------------------------------------
  1606.   alias game_event_check_event_trigger_touch_cxj_fm check_event_trigger_touch
  1607.   def check_event_trigger_touch(x, y)
  1608.     if $game_map.free_movement_enabled?
  1609.       return if $game_map.interpreter.running?
  1610.       if @trigger == 2 && $game_player.pos_rect?(x, y, $game_player.collision_rect)
  1611.         start if !jumping? && normal_priority?
  1612.       end
  1613.     else
  1614.       game_event_check_event_trigger_touch_cxj_fm(x, y)
  1615.     end
  1616.   end
  1617.  
  1618.   #--------------------------------------------------------------------------
  1619.   # * New: Add Character to Touch List
  1620.   #     Keeps track of characters already touching this event.
  1621.   #--------------------------------------------------------------------------
  1622.   def add_touch(character)
  1623.     @touch_chars.push(character) unless is_touching?(character)
  1624.   end
  1625.  
  1626.   #--------------------------------------------------------------------------
  1627.   # * New: Checks if the current event is touching.
  1628.   #--------------------------------------------------------------------------
  1629.   def is_touching?(character)
  1630.     @touch_chars.include?(character)
  1631.   end
  1632.  
  1633.   #--------------------------------------------------------------------------
  1634.   # * New: Event Name
  1635.   #--------------------------------------------------------------------------
  1636.   def name
  1637.     @event.name
  1638.   end
  1639. end
  1640. #==============================================================================
  1641. # ** Game_Follower
  1642. #------------------------------------------------------------------------------
  1643. #  This class handles followers. A follower is an allied character, other than
  1644. # the front character, displayed in the party. It is referenced within the
  1645. # Game_Followers class.
  1646. #==============================================================================
  1647.  
  1648. class Game_Follower < Game_Character
  1649.   #--------------------------------------------------------------------------
  1650.   # * Alias: Object Initialization
  1651.   #--------------------------------------------------------------------------
  1652.   alias game_follower_initialize_cxj_fm initialize
  1653.   def initialize(member_index, preceding_character)
  1654.     game_follower_initialize_cxj_fm(member_index, preceding_character)
  1655.     @force_chase = false
  1656.     @board = false
  1657.     @through = CXJ::FREE_MOVEMENT::FOLLOWER_THROUGH
  1658.     @custom_collision = nil
  1659.   end
  1660.   #--------------------------------------------------------------------------
  1661.   # * Alias: Refresh
  1662.   #--------------------------------------------------------------------------
  1663.   alias game_follower_refresh_cxj_fm refresh
  1664.   def refresh
  1665.     game_follower_refresh_cxj_fm
  1666.     return if actor.nil? || !$game_map.free_movement_enabled?
  1667.     @custom_collision = nil
  1668.     @interaction = CXJ::FREE_MOVEMENT::INTERACTION["DEFAULT"]
  1669.     actor.actor.note.split(/[\r\n]+/).each { |line|
  1670.       case line
  1671.       when /<collisionbox:[ ]*(\d+),[ ]*(\d+),[ ]*(\d+),[ ]*(\d+)>/i
  1672.         @custom_collision = Rect.new($1, $2, $3, $4)
  1673.       when /<collisionbox:[ ]*(.+?)>/i
  1674.         collision = CXJ::FREE_MOVEMENT::COLLISION[$1] if !CXJ::FREE_MOVEMENT::COLLISION[$1].nil?
  1675.         @custom_collision = Rect.new(collision[0], collision[1], collision[2], collision[3])
  1676.       end
  1677.     }
  1678.   end
  1679.   #--------------------------------------------------------------------------
  1680.   # * New: Collision Rectangle
  1681.   #     Gets the collision rectangle.
  1682.   #--------------------------------------------------------------------------
  1683.   def collision_rect
  1684.     return @custom_collision if !@custom_collision.nil?
  1685.     return super
  1686.   end
  1687.   #--------------------------------------------------------------------------
  1688.   # * Alias: Pursue Preceding Character
  1689.   #--------------------------------------------------------------------------
  1690.   alias game_follower_chase_preceding_character_cxj_fm chase_preceding_character
  1691.   def chase_preceding_character
  1692.     if $game_map.free_movement_enabled?
  1693.       unless moving?
  1694.         if @board
  1695.           @x = @preceding_character.x
  1696.           @y = @preceding_character.y
  1697.           @board = false
  1698.         elsif CXJ::FREE_MOVEMENT::FOLLOW_TYPE == :trace && !@force_chase
  1699.           max_list_size = CXJ::FREE_MOVEMENT::FOLLOWERS_DISTANCE / CXJ::FREE_MOVEMENT::PIXELS_PER_STEP
  1700.           if(@preceding_character.pos_list_size > max_list_size)
  1701.             while @preceding_character.pos_list_size > max_list_size
  1702.               pos = @preceding_character.get_coords_from_pos_list
  1703.               unless pos.nil?
  1704.                 sx = distance_x_from(pos[:x])
  1705.                 sy = distance_y_from(pos[:y])
  1706.                 horz = (sx > 0 ? -1 : sx < 0 ? 1 : 0)
  1707.                 vert = (sy > 0 ? -1 : sy < 0 ? 1 : 0)
  1708.                 d = horz + (vert == 0 && horz == 0 ? 0 : 5 - vert * 3)
  1709.                 set_direction(d)
  1710.                 pixelstep = CXJ::FREE_MOVEMENT::PIXELS_PER_STEP / 32.0
  1711.                 @x = @x + horz * pixelstep
  1712.                 @y = @y + vert * pixelstep
  1713.                 @pos_list.push({:x => @real_x, :y => @real_y})
  1714.                 @pos_list.shift if @pos_list.size > CXJ::FREE_MOVEMENT::FOLLOWERS_DISTANCE * 2
  1715.                 if(!jumping?)
  1716.                   @x = $game_map.round_x(@x)
  1717.                   @y = $game_map.round_y(@y)
  1718.                   @real_x = @x - horz * pixelstep
  1719.                   @real_y = @y - vert * pixelstep
  1720.                   increase_steps
  1721.                 end
  1722.               end
  1723.             end
  1724.           end
  1725.         elsif @force_chase
  1726.           dist = CXJ::FREE_MOVEMENT::FOLLOWERS_DISTANCE / 32.0
  1727.           mrgn = CXJ::FREE_MOVEMENT::FOLLOWERS_DISTANCE_MARGIN / 32.0
  1728.           sx = distance_x_from(@preceding_character.x)
  1729.           sy = distance_y_from(@preceding_character.y)
  1730.           sd = Math.hypot(sx, sy)
  1731.           if(sd > dist && sx.abs > mrgn && sy.abs > mrgn)
  1732.             @move_poll+=[[(sx > 0 ? -1 : 1) + (sy > 0 ? 8 : 2), true]]
  1733.           elsif sx.abs > dist && sx.abs > sy.abs
  1734.             @move_poll+=[[sx > 0 ? 4 : 6, true]]
  1735.           elsif sy.abs > dist && sx.abs < sy.abs
  1736.             @move_poll+=[[sy > 0 ? 8 : 2, true]]
  1737.           end
  1738.         end
  1739.       end
  1740.     else
  1741.       game_follower_chase_preceding_character_cxj_fm
  1742.     end
  1743.   end
  1744.  
  1745.   #--------------------------------------------------------------------------
  1746.   # * New: The Distance To Preceding Character
  1747.   #--------------------------------------------------------------------------
  1748.   def distance_preceding_character
  1749.     sx = distance_x_from(@preceding_character.x)
  1750.     sy = distance_y_from(@preceding_character.y)
  1751.     return Math.hypot(sx, sy)
  1752.   end
  1753.  
  1754.   #--------------------------------------------------------------------------
  1755.   # * New: Processes Movement
  1756.   #--------------------------------------------------------------------------
  1757.   def process_move(horz, vert)
  1758.     super(horz, vert)
  1759.     dist = CXJ::FREE_MOVEMENT::FOLLOWERS_DISTANCE / 32.0
  1760.     if distance_preceding_character > dist && @move_poll.size == 0
  1761.       @force_chase = true
  1762.       chase_preceding_character
  1763.       @force_chase = false
  1764.     end
  1765.   end
  1766.  
  1767.   #--------------------------------------------------------------------------
  1768.   # * New: Sets the Character To Board
  1769.   #--------------------------------------------------------------------------
  1770.   def board
  1771.     @board = true
  1772.   end
  1773. end
  1774.  
  1775. #==============================================================================
  1776. # ** Game_Interpreter
  1777. #------------------------------------------------------------------------------
  1778. #  An interpreter for executing event commands. This class is used within the
  1779. # Game_Map, Game_Troop, and Game_Event classes.
  1780. #==============================================================================
  1781.  
  1782. class Game_Interpreter
  1783.   #--------------------------------------------------------------------------
  1784.   # * New: Set Collision Rectangle From Event Script
  1785.   #--------------------------------------------------------------------------
  1786.   def set_collision_rect(*args)
  1787.     $game_map.events[@event_id].set_collision_rect(*args)
  1788.   end
  1789. end
  1790.  
  1791. if(CXJ::FREE_MOVEMENT::SHOW_COLLISION_BOXES)
  1792.   #============================================================================
  1793.   # ** Sprite_CollisionBox
  1794.   #----------------------------------------------------------------------------
  1795.   #  This sprite is used to display collision boxes. It's mainly used for
  1796.   # debugging purposes.
  1797.   #============================================================================
  1798.  
  1799.   class Sprite_CollisionBox < Sprite
  1800.    
  1801.     #------------------------------------------------------------------------
  1802.     # * New: Initialization
  1803.     #------------------------------------------------------------------------
  1804.     def initialize(viewport, parent_sprite = nil)
  1805.       super(viewport)
  1806.       @color = Color.new(0, 255, 0, 128)
  1807.       @icolor = Color.new(255, 0, 0, 128)
  1808.       @parent_sprite = parent_sprite
  1809.       self.bitmap = Bitmap.new(96, 96)
  1810.       update
  1811.     end
  1812.    
  1813.     #------------------------------------------------------------------------
  1814.     # * New: Update Per Frame
  1815.     #------------------------------------------------------------------------
  1816.     def update
  1817.       self.x = @parent_sprite.x
  1818.       self.y = @parent_sprite.y
  1819.       draw_box
  1820.     end
  1821.    
  1822.     #------------------------------------------------------------------------
  1823.     # * New: Draw Collision Box
  1824.     #------------------------------------------------------------------------
  1825.     def draw_box
  1826.       self.ox = 48
  1827.       self.oy = 60
  1828.       self.bitmap.clear
  1829.       return if @parent_sprite.character.through && @parent_sprite.character.transparent
  1830.       return if @parent_sprite.character.instance_of?(Game_Vehicle) && !@parent_sprite.character.on_map?
  1831.       col_rect = @parent_sprite.character.collision_rect
  1832.       self.bitmap.fill_rect(col_rect.x + 32, col_rect.y + 32, col_rect.width, col_rect.height, @color)
  1833.       if(@parent_sprite.character == $game_player)
  1834.         int_rec = $game_player.interaction_rect
  1835.         d = $game_player.direction
  1836.         horz = (d - 1) % 3 - 1
  1837.         vert = 1 - ((d - 1) / 3)
  1838.         int_rect = Rect.new(int_rec.x + 32 + 32 * horz, int_rec.y + 32 + 32 * vert, int_rec.width, int_rec.height)
  1839.         self.bitmap.fill_rect(int_rect, @icolor)
  1840.       end
  1841.     end
  1842.   end
  1843.  
  1844.   #============================================================================
  1845.   # ** Spriteset_Map
  1846.   #----------------------------------------------------------------------------
  1847.   #  This class brings together map screen sprites, tilemaps, etc. It's used
  1848.   # within the Scene_Map class.
  1849.   #============================================================================
  1850.  
  1851.   class Spriteset_Map
  1852.     #--------------------------------------------------------------------------
  1853.     # * Alias: Create Character Sprite
  1854.     #--------------------------------------------------------------------------
  1855.     alias spriteset_map_create_characters_cxj_fm create_characters
  1856.     def create_characters
  1857.       spriteset_map_create_characters_cxj_fm
  1858.       @collision_sprites = []
  1859.       @character_sprites.each do |char|
  1860.         @collision_sprites.push(Sprite_CollisionBox.new(@viewport, char))
  1861.       end
  1862.     end
  1863.     #--------------------------------------------------------------------------
  1864.     # * Alias: Update Character Sprite
  1865.     #--------------------------------------------------------------------------
  1866.     alias spriteset_map_update_characters_cxj_fm update_characters
  1867.     def update_characters
  1868.       spriteset_map_update_characters_cxj_fm
  1869.       @collision_sprites.each {|sprite| sprite.update }
  1870.     end
  1871.   end
  1872. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement