neonblack

Smart Followers v1.0a

Jan 24th, 2014
1,222
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ##-----------------------------------------------------------------------------
  2. #  Smart(er) Followers v1.0a
  3. #  Created by Neon Black
  4. #  v1.0 - 1.24.14 - Main script completed
  5. #  For both commercial and non-commercial use as long as credit is given to
  6. #  Neon Black and any additional authors.  Licensed under Creative Commons
  7. #  CC BY 4.0 - http://creativecommons.org/licenses/by/4.0/
  8. ##-----------------------------------------------------------------------------
  9.  
  10. module CPSmartFollowers
  11.   ## The minimum delay between each character in the party in frames.
  12.   ## What this means is the followers will appear a few spaces behind each
  13.   ## other rather than being right on each others' backs.
  14.   MoveDelay = 8
  15. end
  16.  
  17.  
  18. ##-----------------------------------------------------------------------------
  19. ## The following lines are the actual core code of the script.  While you are
  20. ## certainly invited to look, modifying it may result in undesirable results.
  21. ## Modify at your own risk!
  22. ###----------------------------------------------------------------------------
  23.  
  24.  
  25. $imported ||= {}
  26. $imported["CP_SMART_FOLLOWERS"] = 1.0
  27.  
  28. class Game_Player < Game_Character
  29.   ## Adds the latest player movement to the follower queue.
  30.   def move_straight(d, turn_ok = true)
  31.     forefront = passable?(@x, @y, d)
  32.     super
  33.     return unless forefront
  34.     @followers.move(d, nil, self.direction, :str)
  35.   end
  36.  
  37.   def move_diagonal(horz, vert)
  38.     forefront = diagonal_passable?(@x, @y, horz, vert)
  39.     super
  40.     return unless forefront
  41.     @followers.move(horz, vert, self.direction, :dia)
  42.   end
  43.  
  44.   def jump(x_plus, y_plus)
  45.     super
  46.     @followers.move(x_plus, y_plus, self.direction, :jum)
  47.   end
  48.  
  49.   ## Re-orders the order methods are performed in the update method.  May be
  50.   ## problomatic if another script expects the original ordering.  If there are
  51.   ## issues, try commenting out lines 52 to 63 using CTRL+Q.
  52.   def update
  53.     last_real_x = @real_x
  54.     last_real_y = @real_y
  55.     last_moving = moving?
  56.     ## Original location of "move_by_input".
  57.     super
  58.     update_scroll(last_real_x, last_real_y)
  59.     update_vehicle
  60.     update_nonmoving(last_moving) unless moving?
  61.     move_by_input
  62.     @followers.update
  63.   end
  64.  
  65.   ## Size of the queue for proper following.
  66.   def movement_index
  67.     @followers.follower_queue.size
  68.   end
  69. end
  70.  
  71. class Game_Followers
  72.   attr_reader :follower_queue
  73.   alias_method "cp_092013_move", "move"
  74.   alias_method "cp_092013_initialize", "initialize"
  75.   alias_method "cp_092213_synchronize", "synchronize"
  76.  
  77.   def initialize(*args)
  78.     cp_092013_initialize(*args)
  79.     @follower_queue = []
  80.   end
  81.  
  82.   def update
  83.     update_movement(gathering?)
  84.     @gathering = false if gathering? && gather?
  85.     each { |follower| follower.update }
  86.   end
  87.  
  88.   ## Long method that checks numerous conditions to ensure that the follower is
  89.   ## allowed to move forward.  Has a forced method to allow followers to
  90.   ## gather.
  91.   def update_movement(force = false)
  92.     @last_follow = nil
  93.     @data.each_with_index do |f,i|
  94.       unless force
  95.         last = @last_follow.nil? ? $game_player : @last_follow
  96.         last = f if last.movement_index <= 1
  97.         @last_follow = f if @last_follow.nil? && @follower_queue[f.movement_index+1].nil?
  98.         @last_follow = f if @last_follow && f.movement_index+1 >= @last_follow.movement_index
  99.         f.increase_displacement_count(last != f && last.moving?)
  100.         if last.moving? || f.movement_index + 1 >= last.movement_index
  101.           @last_follow = f unless f.check_displacement_count
  102.         end ## The lines above are used for follower displacement.
  103.       end
  104.       @last_follow = f if f.moving?
  105.       comm = @follower_queue[f.movement_index]
  106.       @last_follow = f unless comm
  107.       next if @last_follow == f
  108.       f.direction = comm[2]
  109.       case comm[3] ## Perform a specific kind of motion when following.
  110.       when :str
  111.         f.move_straight(comm[0])
  112.       when :dia
  113.         f.move_diagonal(*comm[0..1])
  114.       when :jum
  115.         f.jump(*comm[0..1])
  116.       end
  117.       f.movement_index += 1
  118.       @last_follow = f
  119.     end
  120.     if @data[-1].movement_index > 1
  121.       each { |follower| follower.movement_index -= 1 }
  122.       @follower_queue.shift
  123.     end
  124.   end
  125.  
  126.   ## Ironically, I kept the original methods in for random errors.
  127.   def move(*args)
  128.     if args.empty?
  129.       cp_092013_move()
  130.     else
  131.       @follower_queue.push(args)
  132.     end
  133.   end
  134.  
  135.   def synchronize(*args)
  136.     cp_092213_synchronize(*args)
  137.     clear_queue
  138.   end
  139.  
  140.   def clear_queue
  141.     each do |follower|
  142.       follower.movement_index = 0
  143.       follower.jump_count = 0
  144.     end
  145.     @follower_queue = []
  146.   end
  147. end
  148.  
  149. class Game_Follower < Game_Character
  150.   attr_accessor :direction, :movement_index
  151.   attr_writer :jump_count
  152.   alias_method "cp_092213_initialize", "initialize"
  153.  
  154.   def initialize(*args)
  155.     cp_092213_initialize(*args)
  156.     @movement_index = 0
  157.     @displ_count = 0
  158.   end
  159.  
  160.   ## Needed @direction_fix to be free from the player.
  161.   def update
  162.     @direction_fix  = true
  163.     @move_speed     = $game_player.real_move_speed
  164.     @transparent    = $game_player.transparent
  165.     @walk_anime     = $game_player.walk_anime
  166.     @step_anime     = $game_player.step_anime
  167.     @opacity        = $game_player.opacity
  168.     @blend_type     = $game_player.blend_type
  169.     super
  170.   end
  171.  
  172.   ## Counts and uncounts displacement for better following.
  173.   def increase_displacement_count(count = false)
  174.     if count
  175.       @displ_count += 1 unless moving? || @displ_count >= CPSmartFollowers::MoveDelay
  176.     else
  177.       @displ_count -= 1 unless @displ_count <= 0
  178.     end
  179.   end
  180.  
  181.   def check_displacement_count
  182.     @displ_count >= CPSmartFollowers::MoveDelay
  183.   end
  184.  
  185.   def no_displacement
  186.     @displ_count == 0
  187.   end
  188. end
  189.  
  190.  
  191. ##-----------------------------------------------------------------------------
  192. ## End of script.
  193. ##-----------------------------------------------------------------------------
RAW Paste Data