Advertisement
Double_X

DoubleX RMVXA Pixel Movement v1.01a

Aug 12th, 2015 (edited)
2,448
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 20.49 KB | None | 0 0
  1. #==============================================================================|
  2. #  ** Script Info                                                              |
  3. #------------------------------------------------------------------------------|
  4. #  * Script Name                                                               |
  5. #    DoubleX RMVXA Pixel Movement                                              |
  6. #------------------------------------------------------------------------------|
  7. #  * Functions                                                                 |
  8. #    Lets users set the smallest number of pixel covered per move command      |
  9. #------------------------------------------------------------------------------|
  10. #  * Terms Of Use                                                              |
  11. #    You shall keep this script's Script Info part's contents intact           |
  12. #    You shalln't claim that this script is written by anyone other than       |
  13. #    DoubleX or his aliases                                                    |
  14. #    None of the above applies to DoubleX or his aliases                       |
  15. #------------------------------------------------------------------------------|
  16. #  * Prerequisites                                                             |
  17. #    Abilities:                                                                |
  18. #    1. Little RGSS3 scripting proficiency to fully utilize this script        |
  19. #------------------------------------------------------------------------------|
  20. #  * Instructions                                                              |
  21. #    1. Open the script editor and put this script into an open slot between   |
  22. #       Materials and Main, save to take effect.                               |
  23. #------------------------------------------------------------------------------|
  24. #  * Links                                                                     |
  25. #    Script Usage 101:                                                         |
  26. #    1. forums.rpgmakerweb.com/index.php?/topic/32752-rmvxa-script-usage-101/  |
  27. #    2. rpgmakervxace.net/topic/27475-rmvxa-script-usage-101/                  |
  28. #    This script:                                                              |
  29. #    1. http://pastebin.com/RPF8dDDR                                           |
  30. #    Mentioned Patreon Supporters:                                             |
  31. #    https://www.patreon.com/posts/71738797                                    |
  32. #------------------------------------------------------------------------------|
  33. #  * Authors                                                                   |
  34. #    DoubleX                                                                   |
  35. #------------------------------------------------------------------------------|
  36. #  * Changelog                                                                 |
  37. #    v1.01a(GMT 1600 14-8-2015):                                               |
  38. #    1. Lets users set a key/script call to set a char to have integer coors   |
  39. #    2. Fixed event triggered by player touch not triggering bug               |
  40. #    3. Fixed encounters simply not working bug                                |
  41. #    4. Fixed the bullet through paper problem when moving diagonally          |
  42. #    5. Found the origin of the starting map not passable bug with either      |
  43. #       vehicle's starting positions being uninitialized by users              |
  44. #    6. Increased this script's correctness, effectiveness and efficiency      |
  45. #    7. Little RGSS3 scripting proficiency's needed to fully utilize the script|
  46. #    v1.00a(GMT 1600 12-8-2015):                                               |
  47. #    1. 1st version of this script finished                                    |
  48. #==============================================================================|
  49.  
  50. #==============================================================================|
  51. #  ** (v1.01a+)Script Call Info                                                |
  52. #------------------------------------------------------------------------------|
  53. #  * Character manipulations                                                   |
  54. #    1. pixel_movement_nearest_tile                                            |
  55. #       - Sets the x and y psotions of the char to be their nearest integers   |
  56. #==============================================================================|
  57.  
  58. ($doublex_rmvxa ||= {})[:Pixel_Movement] = "v1.01a"
  59.  
  60. #==============================================================================|
  61. #  ** Script Configurations                                                    |
  62. #     You only need to edit this part as it's about what this script does      |
  63. #------------------------------------------------------------------------------|
  64.  
  65. module DoubleX_RMVXA
  66.  
  67.   module Pixel_Movement
  68.  
  69.     # Sets the global minimum pixel covered per move command as MIN_PIXEL_MOVE
  70.     # It must return a natural number
  71.     # If an object moves faster than MIN_PIXEL_MOVE per frame, that object's
  72.     # original speed will be used instead
  73.     # Errors might come if MIN_PIXEL_MOVE is increased during the game execution
  74.     # If MIN_PIXEL_MOVE_VAR_ID is a natural number, the value of variable with
  75.     # id MIN_PIXEL_MOVE_VAR_ID will be used instead of using MIN_PIXEL_MOVE
  76.     MIN_PIXEL_MOVE = 1
  77.     MIN_PIXEL_MOVE_VAR_ID = 0
  78.  
  79.     # (v1.01a+)Sets the key to set the player's x and y positions as their
  80.     # nearest integers as NEAREST_TILE_KEY
  81.     # It must return a symbol and should return a keymap binding symbol
  82.     # Using a custom keymap binding script might help setting NEAREST_TILE_KEY
  83.     # If NEAREST_TILE_KEY_VAR_ID is a natural number, the value of variable with
  84.     # id NEAREST_TILE_KEY_VAR_ID will be used instead of using NEAREST_TILE_KEY
  85.     NEAREST_TILE_KEY = :X
  86.     NEAREST_TILE_KEY_VAR_ID = 0
  87.  
  88. #==============================================================================|
  89. #  ** Script Implementations                                                   |
  90. #     You need not edit this part as it's about how this script works          |
  91. #------------------------------------------------------------------------------|
  92. #  * Script Support Info:                                                      |
  93. #    1. Prerequisites                                                          |
  94. #       - Basic knowledge of pixel movement                                    |
  95. #       - Some RGSS3 scripting proficiency to fully comprehend this script     |
  96. #    2. Method documentation                                                   |
  97. #       - The 1st part describes why this method's rewritten/aliased for       |
  98. #         rewritten/aliased methods or what the method does for new methods    |
  99. #       - The 2nd part describes what the arguments of the method are          |
  100. #       - The 3rd part informs which version rewritten, aliased or created this|
  101. #         method                                                               |
  102. #       - The 4th part informs whether the method's rewritten or new           |
  103. #       - The 5th part describes how this method works for new methods only,   |
  104. #         and describes the parts added, removed or rewritten for rewritten or |
  105. #         aliased methods only                                                 |
  106. #       Example:                                                               |
  107. # #--------------------------------------------------------------------------| |
  108. # #  Why rewrite/alias/What this method does                                 | |
  109. # #--------------------------------------------------------------------------| |
  110. # # *argv: What these variables are                                            |
  111. # # &argb: What this block is                                                  |
  112. # def def_name(*argv, &argb) # Version X+; Rewrite/New                         |
  113. #   # Added/Removed/Rewritten to do something/How this method works            |
  114. #   def_name_code                                                              |
  115. #   #                                                                          |
  116. # end # def_name                                                               |
  117. #------------------------------------------------------------------------------|
  118.  
  119.     #--------------------------------------------------------------------------|
  120.     #  Helper methods simplifying the uses of the configuration value          |
  121.     #--------------------------------------------------------------------------|
  122.  
  123.     def self.min_pixel_move
  124.       return MIN_PIXEL_MOVE if MIN_PIXEL_MOVE_VAR_ID <= 0
  125.       $game_variables[MIN_PIXEL_MOVE_VAR_ID]
  126.     end # min_pixel_move
  127.  
  128.     def self.nearest_tile_key # v1.01a+
  129.       return NEAREST_TILE_KEY if NEAREST_TILE_KEY_VAR_ID <= 0
  130.       $game_variables[NEAREST_TILE_KEY_VAR_ID]
  131.     end # nearest_tile_key
  132.  
  133.   end # Pixel_Movement
  134.  
  135. end # DoubleX_RMVXA
  136.  
  137. class Game_Map # Edit
  138.  
  139.   def x_with_direction(x, d) # Rewrite
  140.     # Rewritten
  141.     return x + DoubleX_RMVXA::Pixel_Movement.min_pixel_move / 32.0 if d == 6
  142.     return x - DoubleX_RMVXA::Pixel_Movement.min_pixel_move / 32.0 if d == 4
  143.     x
  144.     #
  145.   end # x_with_direction
  146.  
  147.   def y_with_direction(y, d) # Rewrite
  148.     # Rewritten
  149.     return y + DoubleX_RMVXA::Pixel_Movement.min_pixel_move / 32.0 if d == 2
  150.     return y - DoubleX_RMVXA::Pixel_Movement.min_pixel_move / 32.0 if d == 8
  151.     y
  152.     #
  153.   end # y_with_direction
  154.  
  155.   def round_x_with_direction(x, d) # Rewrite
  156.     round_x(x_with_direction(x, d)) # Rewritten
  157.   end # round_x_with_direction
  158.  
  159.   def round_y_with_direction(y, d) # Rewrite
  160.     round_y(y_with_direction(y, d)) # Rewritten
  161.   end # round_y_with_direction
  162.  
  163.   def valid?(x, y) # Rewrite
  164.     x >= 0 && x <= width - 1 && y >= 0 && y <= height - 1 # Rewritten
  165.   end # valid?
  166.  
  167.   #----------------------------------------------------------------------------|
  168.   #  Uses a unit bounding square to detect overlapped tiles instead            |
  169.   #----------------------------------------------------------------------------|
  170.   alias layered_tiles_flag_pixel_movement? layered_tiles_flag?
  171.   def layered_tiles_flag?(x, y, bit, &argb)
  172.     # Rewritten
  173.     (x == (x = x.to_i) ? [x] : [x, x + 1]).each { |xi|
  174.       (y == (y = y.to_i) ? [y] : [y, y + 1]).each { |yi|
  175.         return true if layered_tiles_flag_pixel_movement?(x, y, bit, &argb)
  176.       }
  177.     }
  178.     false
  179.     #
  180.   end # layered_tiles_flag?
  181.  
  182. end # Game_Map
  183.  
  184. class Game_CharacterBase # Edit
  185.  
  186.   #----------------------------------------------------------------------------|
  187.   #  New private instance variables                                            |
  188.   #----------------------------------------------------------------------------|
  189.   # @pixel_movement_diff: The movement distance of the current frame
  190.   # @pixel_movement_dist: The accumulated movement distance
  191.  
  192.   #----------------------------------------------------------------------------|
  193.   #  Uses a unit bounding square to detect character collisions instead        |
  194.   #----------------------------------------------------------------------------|
  195.   def pos?(x, y) # Rewrite
  196.     # Rewritten to regard just touching as edges as colliding
  197.     x + 1 >= @x && x <= @x + 1 && y + 1 >= @y && y <= @y + 1
  198.     #
  199.   end # pos?
  200.  
  201.   #----------------------------------------------------------------------------|
  202.   #  Uses a unit bounding square to detect character collisions instead        |
  203.   #----------------------------------------------------------------------------|
  204.   def pos_nt?(x, y) # Rewrite
  205.     # Rewritten to regard just touching the edges as not colliding
  206.     !@through && x + 1 > @x && x < @x + 1 && y + 1 > @y && y < @y + 1
  207.     #
  208.   end # pos_nt?
  209.  
  210.   #----------------------------------------------------------------------------|
  211.   #  Uses a unit bounding square to detect character collisions instead        |
  212.   #----------------------------------------------------------------------------|
  213.   def passable?(x, y, d) # Rewrite
  214.     x2 = $game_map.round_x_with_direction(x, d)
  215.     y2 = $game_map.round_y_with_direction(y, d)
  216.     # Rewritten to check if all overlapped tiles are valid and passable as well
  217.     xs = x2 == (x2i = x2.to_i) ? [x2i] : [x2i, x2i + 1]
  218.     ys = y2 == (y2i = y2.to_i) ? [y2i] : [y2i, y2i + 1]
  219.     xs.each { |xi|
  220.       ys.each { |yi| return false unless $game_map.valid?(xi, yi) }
  221.     }
  222.     return true if @through || debug_through?
  223.     (x == (x = x.to_i) ? [x] : [x, x + 1]).each { |xi|
  224.       (y == (y = y.to_i) ? [y] : [y, y + 1]).each { |yi|
  225.         return false unless map_passable?(xi, yi, d)
  226.       }
  227.     }
  228.     rd = reverse_dir(d)
  229.     xs.each { |xi|
  230.       ys.each { |yi| return false unless map_passable?(xi, yi, rd) }
  231.     }
  232.     #
  233.     !collide_with_characters?(x2, y2)
  234.   end # passable?
  235.  
  236.   #----------------------------------------------------------------------------|
  237.   #  Prevents an event from being falsely considered as colliding with itself  |
  238.   #----------------------------------------------------------------------------|
  239.   def collide_with_events?(x, y) # Rewrite
  240.     return true if is_a?(Game_Event)
  241.     ($game_map.events_xy_nt(x, y) - [self]).any? { |e| e.normal_priority? }
  242.   end # collide_with_events?
  243.  
  244.   def move_straight(d, turn_ok = true) # Rewrite
  245.     @move_succeed = passable?(@x, @y, d)
  246.     if @move_succeed
  247.       set_direction(d)
  248.       @x = $game_map.round_x_with_direction(@x, d)
  249.       @y = $game_map.round_y_with_direction(@y, d)
  250.       @real_x = $game_map.x_with_direction(@x, reverse_dir(d))
  251.       @real_y = $game_map.y_with_direction(@y, reverse_dir(d))
  252.       # Rewritten to prevent character from being locked into impassable places
  253.       set_pixel_movement_min
  254.       last_x = @real_x
  255.       last_y = @real_y
  256.       pixel_movement_straight(last_x, last_y, d) unless passable?(@x, @y, d)
  257.       @pixel_movement_diff = ((@x - last_x) ** 2 + (@y - last_y) ** 2) ** 0.5
  258.       @pixel_movement_dist += @pixel_movement_diff
  259.       while @pixel_movement_dist >= 1
  260.         increase_steps
  261.         @pixel_movement_dist -= 1
  262.       end
  263.       #
  264.     elsif turn_ok
  265.       set_direction(d)
  266.       check_event_trigger_touch_front
  267.     end
  268.   end # move_straight
  269.  
  270.   def move_diagonal(horz, vert) # Rewrite
  271.     @move_succeed = diagonal_passable?(@x, @y, horz, vert)
  272.     if @move_succeed
  273.       @x = $game_map.round_x_with_direction(@x, horz)
  274.       @y = $game_map.round_y_with_direction(@y, vert)
  275.       @real_x = $game_map.x_with_direction(@x, reverse_dir(horz))
  276.       @real_y = $game_map.y_with_direction(@y, reverse_dir(vert))
  277.       # Rewritten to prevent character from being locked into impassable places
  278.       set_pixel_movement_min
  279.       set_pixel_movement_diagonal(horz, vert)
  280.       @pixel_movement_diff = ((@x - @real_x) ** 2 + (@y - @real_y) ** 2) ** 0.5
  281.       @pixel_movement_dist += @pixel_movement_diff
  282.       while @pixel_movement_dist >= 1
  283.         increase_steps
  284.         @pixel_movement_dist -= 1
  285.       end
  286.       #
  287.       increase_steps
  288.     end
  289.     set_direction(horz) if @direction == reverse_dir(horz)
  290.     set_direction(vert) if @direction == reverse_dir(vert)
  291.   end # move_diagonal
  292.  
  293.   alias init_private_members_pixel_movement init_private_members
  294.   def init_private_members(*argv, &argb)
  295.     init_private_members_pixel_movement(*argv, &argb)
  296.     @pixel_movement_diff = @pixel_movement_dist = 0 # Added
  297.   end # init_private_members
  298.  
  299.   #----------------------------------------------------------------------------|
  300.   #  Checks if events collide with the players as well                         |
  301.   #----------------------------------------------------------------------------|
  302.   alias collide_with_characters_pixel_movement? collide_with_characters?
  303.   def collide_with_characters?(x, y)
  304.     return true if $game_player != self && $game_player.pos_nt?(x, y) # Added
  305.     collide_with_characters_pixel_movement?(x, y)
  306.   end # collide_with_characters?
  307.  
  308.   #----------------------------------------------------------------------------|
  309.   #  Sets the number of pixel covered per frame to be at least that of the char|
  310.   #----------------------------------------------------------------------------|
  311.   def set_pixel_movement_min # New
  312.     dpf = distance_per_frame
  313.     if @x > @real_x
  314.       @x = [@real_x + dpf, $game_map.width - 1].min if @x < @real_x + dpf
  315.     elsif @x < @real_x
  316.       @x = [@real_x - dpf, 0].max if @x > @real_x - dpf
  317.     end
  318.     if @y > @real_y
  319.       @y = [@real_y + dpf, $game_map.height - 1].min if @y < @real_y + dpf
  320.     elsif @y < @real_y
  321.       @y = [@real_y - dpf, 0].max if @y > @real_y - dpf
  322.     end
  323.   end # set_pixel_movement_min
  324.  
  325.   #----------------------------------------------------------------------------|
  326.   #  Prevents the character from being locked into an impassable place         |
  327.   #----------------------------------------------------------------------------|
  328.   # last_x : The real x coordinate right before moving straight
  329.   # last_y : The real y coordinate right before moving straight
  330.   # d: The movement direction
  331.   def pixel_movement_straight(last_x, last_y, d) # New
  332.     mpm = DoubleX_RMVXA::Pixel_Movement.min_pixel_move / 32.0
  333.     # Uses a binary search to find the point making the char to become passable
  334.     while (@x - last_x).abs > mpm || (@y - last_y).abs > mpm
  335.       @real_x = (@x + last_x) / 2
  336.       @real_y = (@y + last_y) / 2
  337.       if passable?(@real_x, @real_y, d)
  338.         last_x = @real_x
  339.         next last_y = @real_y
  340.       end
  341.       @x = @real_x
  342.       @y = @real_y
  343.     end
  344.     #
  345.     @real_x = @x
  346.     @real_y = @y
  347.   end # pixel_movement_straight
  348.  
  349.   #----------------------------------------------------------------------------|
  350.   #  Fixes the bullet through paper problem when moving diagonally             |
  351.   #----------------------------------------------------------------------------|
  352.   # horz: The horizontal direction component
  353.   # vert: The vertical direction component
  354.   def set_pixel_movement_diagonal(horz, vert) # New
  355.     # Sets the maximum number of pixels covered that are still passable
  356.     mpm = DoubleX_RMVXA::Pixel_Movement.min_pixel_move / 32.0
  357.     xi = @real_x
  358.     yi = @real_y
  359.     xs = (@x - @real_x) / (@x - @real_x).abs
  360.     ys = (@y - @real_y) / (@y - @real_y).abs
  361.     while xi * xs <= @x * xs && yi * ys <= @y * ys &&
  362.     diagonal_passable?(xi, yi, horz, vert)
  363.       xi += mpm * xs
  364.       yi += mpm * ys
  365.     end
  366.     @x = xi
  367.     @y = yi
  368.     #
  369.   end # set_pixel_movement_diagonal
  370.  
  371.   #----------------------------------------------------------------------------|
  372.   #  Tries to set the real x and y positions to be their nearest integers      |
  373.   #----------------------------------------------------------------------------|
  374.   def pixel_movement_nearest_tile # v1.01a+; New
  375.     test_x = ((@x * 2).to_i + 1) / 2
  376.     test_y = ((@y * 2).to_i + 1) / 2
  377.     [2, 4, 6, 8].each { |d| return unless passable?(test_x, test_y, d) }
  378.     @x = test_x
  379.     @y = test_y
  380.   end # pixel_movement_nearest_tile
  381.  
  382. end # Game_CharacterBase
  383.  
  384. class Game_Player < Game_Character # v1.01a+; Edit
  385.  
  386.   def update # Rewrite
  387.     last_real_x = @real_x
  388.     last_real_y = @real_y
  389.     last_moving = moving?
  390.     move_by_input
  391.     super
  392.     update_scroll(last_real_x, last_real_y)
  393.     update_vehicle
  394.     # Rewritten
  395.     unless $game_map.interpreter.running?
  396.       moving? ? pixel_movement_update : update_nonmoving(last_moving)
  397.     end
  398.     #
  399.     @followers.update
  400.     # Added
  401.     return unless Input.trigger?(DoubleX_RMVXA::Pixel_Movement.nearest_tile_key)
  402.     pixel_movement_nearest_tile
  403.     #
  404.   end # update
  405.  
  406.   # last_moving: The moving flag at the last frame
  407.   def update_nonmoving(last_moving) # Rewrite
  408.     # Rewritten
  409.     return if last_moving && check_touch_event
  410.     movable? && Input.trigger?(:C) && (get_on_off_vehicle || check_action_event)
  411.     #
  412.   end # update_nonmoving
  413.  
  414.   alias move_by_input_pixel_movement move_by_input
  415.   def move_by_input
  416.     # Added
  417.     @pixel_movement_diff = ((@x - @real_x) ** 2 + (@y - @real_y) ** 2) ** 0.5
  418.     #
  419.     move_by_input_pixel_movement
  420.   end # move_by_input
  421.  
  422.   alias encounter_progress_value_pixel_movement encounter_progress_value
  423.   def encounter_progress_value
  424.     encounter_progress_value_pixel_movement * @pixel_movement_diff # Rewritten
  425.   end # encounter_progress_value
  426.  
  427.   def moving? # New
  428.     @pixel_movement_diff != 0
  429.   end # moving?
  430.  
  431.   def pixel_movement_update # New
  432.     $game_party.on_player_walk
  433.     check_touch_event || update_encounter
  434.   end # pixel_movement_update
  435.  
  436. end # Game_Player
  437.  
  438. #------------------------------------------------------------------------------|
  439.  
  440. #==============================================================================|
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement