neonblack

Large Sprite ☆ Display Fix v1.4

Aug 17th, 2013
3,465
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ##-----------------------------------------------------------------------------
  2. #  Large Sprite ☆ Display Fix v1.3
  3. #  Created by Neon Black at request of seita
  4. #  v1.4 - 12.18.14 - Added position tuning
  5. #  v1.3 - 1.12.14  - Viewport/position issue fixes
  6. #  v1.1 - 8.18.13  - Fixed an odd lag issue
  7. #  v1.0 - 8.17.13  - Main script completed
  8. #  For both commercial and non-commercial use as long as credit is given to
  9. #  Neon Black and any additional authors.  Licensed under Creative Commons
  10. #  CC BY 4.0 - http://creativecommons.org/licenses/by/4.0/
  11. ##-----------------------------------------------------------------------------
  12.  
  13. ##------
  14. ## By default, this script only affects the player.  To allow it to affect
  15. ## an event page as well, add a comment with the tag <large sprite> to the page
  16. ## of the event you would like to have affected by this.
  17.  
  18. class Sprite_Character < Sprite_Base
  19.   ##------
  20.   ## The ID of the terrain used to display the large character above ☆ tiles.
  21.   ## If the player is below this tile (y position), the sprite will appear
  22.   ## above all tiles and events from that y position up.  If the player is on
  23.   ## the same tile or above (y position) the event will appear BELOW ☆ tiles
  24.   ## from that position up.
  25.   ##------
  26.   UpperTerrain = 7
  27.  
  28.   ##------
  29.   ## This value is the pixel tuning used to check the location.  This is
  30.   ## because characters tagged with a '!' in their name are drawn lower than
  31.   ## normal characters and are considered to be lower than these.  This causes
  32.   ## the script to think they are on the tile below where they really are and
  33.   ## draw them above tiles they should appear under.
  34.   ##------
  35.   Tuning = -1
  36.  
  37.   alias :cp_011214_update_bitmap :update_bitmap
  38.   def update_bitmap(*args)
  39.     if graphic_changed? && @set_upper_area_sprite
  40.       @force_no_gfx_change = true
  41.     else
  42.       @force_no_gfx_change = false
  43.     end
  44.     cp_011214_update_bitmap(*args)
  45.   end
  46.  
  47.   ## Alias the update method to add in the new graphic check.
  48.   alias :cp_073013_update_pos :update_position
  49.   def update_position(*args)
  50.     cp_073013_update_pos(*args)
  51.     check_encompassed_area if sprite_is_onscreen?
  52.   end
  53.  
  54.   ## Alias the dispose to dispose the upper sprite.
  55.   alias :cp_073013_dispose :dispose
  56.   def dispose(*args)
  57.     @upper_area_sprite.dispose if @upper_area_sprite
  58.     cp_073013_dispose(*args)
  59.   end
  60.  
  61. #~   ## Alias the graphic changed method to allow the sprite to revent to what it
  62. #~   ## was during the last frame.  This allows the check to work again.
  63. #~   alias :cp_073013_graphic_changed? :graphic_changed?
  64. #~   def graphic_changed?(*args)
  65. #~     cp_073013_graphic_changed?(*args) || @set_upper_area_sprite
  66. #~   end
  67.  
  68.   ## Check if the sprite is onscreen.  Reduces redundant drawing.
  69.   def sprite_is_onscreen?
  70.     return false if @character.is_a?(Game_Vehicle) || @character.is_a?(Game_Follower)
  71.     return false unless @character.is_a?(Game_Player) || @character.large_sprite
  72.     return false if @character.screen_z >= 200
  73.     top_left, bot_right = get_edge_corner_dis
  74.     return false if top_left[0] > Graphics.width
  75.     return false if top_left[1] > Graphics.height
  76.     return false if bot_right[0] < 0
  77.     return false if bot_right[1] < 0
  78.     return true
  79.   end
  80.  
  81.   ## Get the top left and bottom right positions.
  82.   def get_edge_corner_dis
  83.     top_left = [self.x - self.ox, self.y - self.oy]
  84.     bot_right = [top_left[0] + self.width, top_left[1] + self.height]
  85.     return [top_left, bot_right]
  86.   end
  87.  
  88.   ## Long method that checks each position and draws the upper sprite.
  89.   def check_encompassed_area
  90.     if @set_upper_area_sprite && !@force_no_gfx_change
  91.       old_src = self.src_rect.clone
  92.       self.bitmap = @old_bitmap
  93.       self.src_rect = old_src
  94.     end
  95.     @set_upper_area_sprite = false
  96.     top_left, bot_right = get_edge_corner_dis
  97.     last_x, last_y, copy_region = nil, nil, 0
  98.     map_xd, map_yd = $game_map.display_x * 32, $game_map.display_y * 32
  99.     total_height = (self.height + @character.jump_height).round
  100.     self.width.times do |x|
  101.       xp = map_xd.to_i + top_left[0] + x
  102.       unless xp / 32 == last_x
  103.         last_x = xp / 32
  104.         last_y, copy_region = nil, 0
  105.         total_height.times do |y|
  106.           yp = map_yd.to_i + bot_right[1] + @character.jump_height - y + Tuning
  107.           next if yp.to_i / 32 == last_y
  108.           last_y = yp.to_i / 32
  109.           if last_y == (@character.screen_y + @character.jump_height + Tuning +
  110.                         map_yd).to_i / 32
  111.             break if $game_map.terrain_tag(last_x, last_y) == UpperTerrain
  112.             next
  113.           end
  114.           next if $game_map.terrain_tag(last_x, last_y) != UpperTerrain
  115.           copy_region = [self.height, total_height - y + 1].min
  116.           set_upper_sprite
  117.           break
  118.         end
  119.       end
  120.       next if copy_region == 0
  121.       rect = Rect.new(src_rect.x + x, src_rect.y, 1, copy_region)
  122.       @upper_area_sprite.bitmap.blt(x, 0, self.bitmap, rect)
  123.       self.bitmap.clear_rect(rect)
  124.     end
  125.     if !@set_upper_area_sprite && @upper_area_sprite
  126.       @upper_area_sprite.visible = false
  127.     end
  128.   end
  129.  
  130.   ## Creates the upper sprite that's a copy of the current sprite.
  131.   def set_upper_sprite
  132.     return if @set_upper_area_sprite
  133.     @upper_area_sprite ||= Sprite.new
  134.     @upper_area_sprite.bitmap = Bitmap.new(self.width, self.height)
  135.     props = ["x", "y", "ox", "oy", "zoom_x", "zoom_y", "angle", "mirror",
  136.              "bush_depth", "opacity", "blend_type", "color", "tone", "visible",
  137.              "viewport"]
  138.     props.each do |meth|
  139.       @upper_area_sprite.method("#{meth}=").call(self.method(meth).call)
  140.     end
  141.     @upper_area_sprite.z = 200
  142.     @set_upper_area_sprite = true
  143.     @old_bitmap, old_src_rect = self.bitmap, self.src_rect.clone
  144.     self.bitmap = Bitmap.new(@old_bitmap.width, @old_bitmap.height)
  145.     self.bitmap.blt(0, 0, @old_bitmap, @old_bitmap.rect)
  146.     self.src_rect = old_src_rect
  147.   end
  148. end
  149.  
  150. class Game_Event < Game_Character
  151.   attr_reader :large_sprite
  152.  
  153.   alias :cp_081713_setup_page_settings :setup_page_settings
  154.   def setup_page_settings(*args)
  155.     cp_081713_setup_page_settings(*args)
  156.     get_large_sprite_conditions
  157.   end
  158.  
  159.   def get_large_sprite_conditions
  160.     @large_sprite = false
  161.     return if @list.nil? || @list.empty?
  162.     @list.each do |line|
  163.       next unless line.code == 108 || line.code == 408
  164.       case line.parameters[0]
  165.       when /<large sprite>/i
  166.         @large_sprite = true
  167.       end
  168.     end
  169.   end
  170. end
RAW Paste Data