Advertisement
LiTTleDRAgo

[RGSS] King's Tilemap (Edited)

Aug 5th, 2013
222
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 63.72 KB | None | 0 0
  1. #============================================================================
  2. # ** Tilemap Enchance v.0.75 (RGSS3 Version)
  3. #============================================================================
  4. #
  5. #  *HEAVILY EDITED* by LiTTleDRAgo
  6. #
  7. # This script serves as a complete standard tilemap class replacement and
  8. # enables you to access single layers. It's got some new special features
  9. # as well.
  10. # Basically the script works flawlessly, something that can't be said of most
  11. # other tilemap rewrites.
  12. #
  13. # 1. Installation
  14. #
  15. # Paste the script above main but below the standard scripts.
  16. #
  17. # 2. Functional Principle
  18. #
  19. # Upon entering a map the script loads the new class Tilemap_New instead of Tilemap.
  20. # A sprite with bitmap is created for every row of the map in y (from 0 to the
  21. # bottom). There's an additional distinction between the single priority settings and
  22. # tiles/autotiles. So the tiles are pre-cached and not drawn new during the game.
  23. # This requires lots of RAM and increases the maps' load times slightly but improves
  24. # performance as well!
  25. #
  26. # 3. Benefit
  27. #
  28. # You can directly modify the display process of tiles now, or modify the tile
  29. # graphics themselves. Three built-in features are:
  30. # Blend types for autotiles (normal, add, sub; useful for certain water/light effects)
  31. # Changeable animation speed of autotiles as well as a color tone for the tilemap alone.
  32. # Other purposes would be a screen size script. My tilemap class is especially suited
  33. # for those due to the performance not diminishing at higher resolutions, or just
  34. # marginally.
  35. #
  36. # 4. Usage
  37. #
  38. # The script is automatically used after inserting it, however special
  39. # features need to be activated seperately:
  40. #
  41. # - Autotile blend_type/speed:
  42. # Configuration via the module Autotile below this introduction.
  43. # Possible values for blend_type are 0 (normal), 1 (add), 2 (sub), for
  44. # speed every integer can be used. Small numbers mean faster animation
  45. # (0 = each frame).
  46. # Configuration like so: MAP_ID=>{AUTOTILE_ID=>BLEND_TYPE/BLEND_SPEED} in the
  47. # respective section BLEND_TYPE respectively SPEED. Examples are given.
  48. # ID goes from 0 to 6 (left to right in the tileset).
  49. #
  50. # DEFAULT_SPEED is the speed used in case SPEED doesn't contain a value for a map
  51. # or an autotile.
  52. #
  53. # - Tilemap-Tone:
  54. # Can be accessed via Call Script or in a script. Use this command:
  55. #
  56. # $game_map.start_tone_change(tone,duration)
  57. #
  58. # Whereas tone = Tone.new(r,g,b,gr). This tone affects tiles and autotiles only,
  59. # screen color tone can still be added seperately.
  60. #
  61. # 5. Restrictions
  62. #
  63. # - Post hoc changes of tile data in the script doesn't have an effect
  64. # in this version yet (e.g. via $game_map.data)
  65. #
  66. # - High memory consumption. Depending on the map size and usage of autotiles
  67. # the memory needed can add up to 800 MB. (200*200 map, 1 layer filled with
  68. # normal tiles, 1 layer filled with 4 frames autotile)
  69. # Realistic footprint accounts to 500 MB max, 512 MB RAM recommended for maps
  70. # bigger than 100*100!
  71. #
  72. # - Increased loading time. Depending on the map size and usage of autotiles
  73. # loading time ranges from 0 to 6 seconds. Small maps (30*30) are loaded
  74. # instantly, 60*60 with autotiles ca. 1 second, 100*100 with autotiles 2 seconds,
  75. # 200*200 map, 1 layer filled with normal tiles, 1 layer filled with 4 frames
  76. # autotiles 6 seconds.
  77. #
  78. # - A teleport to the current map leads to a graphical glitch.
  79. #
  80. # 6. Pros
  81. #
  82. # - Full access to all sprites on a map
  83. # - Autotile Blend_types and variable speed
  84. # - Autotile-Blend_types und variable Geschwindigkeit
  85. # - Great performance at memory's cost
  86. # - Full functionality (see Restrictions for exceptions)
  87. # - Lag doesn't increase when using higher resolutions
  88. #
  89. #
  90. # 7. Credits
  91. #
  92. # Credits to GodLike for the RPG::Cache extension
  93. # English translation by Terv
  94. # Edited by LiTTleDRAgo
  95. # Feel free to use and modify as you like, however be sure to give credit.
  96. #
  97. # 8. Changelog
  98. #
  99. # V 0.75:
  100. #
  101. # - Compatibility for RGSS3 added
  102. # - Load time slightly decreased
  103. # - General performance improved
  104. # - Small display errors caused by specific autotile combinations fixed
  105. #
  106. # 9. Contact
  107. #
  108. # Questions, ideas, bug reports? Please drop me an email: admin@envile-media.at
  109. #
  110. #
  111. #============================================================================
  112. RGSS3 = RUBY_VERSION == '1.9.2'
  113. #==============================================================================
  114. # ** Module Autotile
  115. #------------------------------------------------------------------------------
  116. #  
  117. #  This module contains autotile configurations.
  118. #  
  119. #==============================================================================
  120. if true
  121. module AUTOTILE
  122.  
  123.   # MAP_ID => { AUTOTILE_ID => BLEND_TYPE,.. }
  124.   BLEND_TYPE = {
  125.                   4 => { 5=>1, 6=>2 },
  126.                }
  127.  
  128.   # MAP_ID => { AUTOTILE_ID => SPEED,.. }
  129.   SPEED = {
  130.            4 => { 4 => 2 },
  131.           }
  132.  
  133.   # DEFAULT_SPEED
  134.   DEFAULT_SPEED = 4
  135.  
  136. end
  137.  
  138. #==============================================================================
  139. # ** Sprite_Auto NEW
  140. #------------------------------------------------------------------------------
  141. #
  142. #  This class manages autotiles layers. Every layer contains multiple sprites,
  143. #  one for each autotile column. Furthermore generates respective bitmaps for
  144. #  the layer.
  145. #
  146. #==============================================================================
  147.  
  148. class Sprite_Auto
  149.  
  150.   attr_reader :cache2
  151.   #--------------------------------------------------------------------------
  152.   # * Initialize (read tiles, create sprites & bitmaps)
  153.   #--------------------------------------------------------------------------
  154.   def initialize(viewport,tiles,speed,autotile_frames,priority,blend_type)
  155.     # Store autotile data
  156.     @tiles = tiles
  157.     @tileset_id = $game_map.map.tileset_id
  158.     @tileset = RPG::Cache.tileset($game_map.tileset_name)
  159.     @speed = speed
  160.     @priority = priority
  161.     @autotile_frames = autotile_frames
  162.     @frames = autotile_frames[tiles[0]]
  163.     @priorities = $game_map.priorities
  164.     @blend_type = blend_type
  165.     @viewport = viewport
  166.     # Animation variables
  167.     @time = 0
  168.     @state = -1
  169.     # Get number of tiles on x/y axis
  170.     @width = $game_map.width
  171.     @height = $game_map.height
  172.     # Set layer border variables to l<->r and u<->d (changed max/min values)
  173.     @border_lx = @width
  174.     @border_ty = @height
  175.     @border_rx = 0
  176.     @border_by = 0
  177.     # Set row borders
  178.     @border_lx_row = @width
  179.     @border_rx_row = 0
  180.     # Create table for row borders
  181.     @rows = Table.new(@height,2)
  182.     # Hash for sprites & cache
  183.     @sprites = {}
  184.     @cache = {}
  185.     @cache2 =  {}
  186.     # If special blend_type
  187.     if @blend_type != 0
  188.       # Setup tiles accordingly
  189.       setup_tiles_blend
  190.     # Else: normal blendig
  191.     else
  192.       # Setup tiles
  193.       setup_tiles
  194.     end
  195.     # Return if not valid
  196.     return if !valid?
  197.     # Otherwise, create sprites & bitmaps
  198.     create_sprites
  199.     # If special blend_type
  200.     if @blend_type != 0
  201.       # Draw blended tiles
  202.       draw_tiles_blend
  203.     else
  204.       # Draw tiles
  205.       draw_tiles
  206.     end
  207.     @tileset = nil
  208.   end
  209.   #--------------------------------------------------------------------------
  210.   # * Valid? (checks whether found in tiles for this layer)
  211.   #--------------------------------------------------------------------------
  212.   def valid?
  213.     # If right border greater or equal to left border and
  214.     # top border greater or equal to bottom border then true
  215.     return @border_rx >= @border_lx && @border_by >= @border_ty
  216.   end
  217.   #--------------------------------------------------------------------------
  218.   # * Row_valid? (checks whether found in tiles in column y)
  219.   #--------------------------------------------------------------------------
  220.   def row_valid?(y)
  221.     # If right border of row equal or greater to left border of row
  222.     # then true
  223.     return @rows[y,1] > @rows[y,0]
  224.   end
  225.   #--------------------------------------------------------------------------
  226.   # * Setup_tiles_blend (reads tiles for this layer and defines the borders.
  227.   # Makes use of special rules for reading)
  228.   #--------------------------------------------------------------------------
  229.   def setup_tiles_blend
  230.     # Get pre-sorted tile data with priority of the layer
  231.     @data_link = $game_map.priority_data(@priority)
  232.     # Clone hashs, needed for functionally interation while deleting stuff
  233.     # from the data
  234.     @data = @data_link.dup
  235.     @data_link.each_pair do |dx,data_x|
  236.       dat_x = @data[dx]
  237.       dat_x = data_x.dup
  238.       data_x.each_pair do |dz,data_z|
  239.         dat_x[dz] = data_z.dup
  240.       end
  241.     end
  242.     tiles_found = false
  243.     layer = 0
  244.     # Iterate through sorted tiles on y-axis
  245.     @data.each_pair do |y,data_y|
  246.       # Iterate through sorted tiles on x-axis
  247.       data_y.each_pair do |x,data_x|
  248.         # Iterate through map editor layers downwards
  249.         data_x.each_pair do |z,t|
  250.           # Get Tile ID
  251.           # Skip to next if there no tile
  252.           next if t == nil
  253.           # If tile fits properties of layer, only true if t is a autotile
  254.           if @tiles.include?(t/48-1)
  255.             # Add tile id to cache
  256.             @cache[y] = {} if @cache[y] == nil
  257.             @cache[y][x] = {} if @cache[y][x] == nil
  258.             @cache[y][x][z] = t
  259.             # Extend borders
  260.             border(x,y)
  261.             # Delete from map data list
  262.             @data_link[y][x].delete(z)
  263.             @data_link[y].delete(x) if @data_link[y][x].size == 0
  264.             @data_link.delete(y) if @data_link[y].size == 0
  265.             tiles_found = true
  266.             layer = z
  267.           end
  268.         end
  269.         if tiles_found == true
  270.           if layer == 0
  271.             for z in [1,2]
  272.               t = data_x[z]
  273.               next if t == nil || t < 384 || @priorities[t] != @priority
  274.               @cache2[y] = {} if @cache2[y] == nil
  275.               @cache2[y][x] = {} if @cache2[y][x] == nil
  276.               @cache2[y][x][z] = t
  277.               @data_link[y][x].delete(z)
  278.               @data_link[y].delete(x) if @data_link[y][x].size == 0
  279.               @data_link.delete(y) if @data_link[y].size == 0
  280.             end
  281.           elsif layer == 1
  282.             t = data_x[2]
  283.             next if t == nil || t < 384 || @priorities[t] != @priority
  284.             @cache2[y] = {} if @cache2[y] == nil
  285.             @cache2[y][x] = {} if @cache2[y][x] == nil
  286.             @cache2[y][x][z] = t
  287.             @data_link[y][x].delete(z)
  288.             @data_link[y].delete(x) if @data_link[y][x].size == 0
  289.             @data_link.delete(y) if @data_link[y].size == 0
  290.           end
  291.         end
  292.       end
  293.       # Set row borders
  294.       @rows[y,0] = @border_lx_row
  295.       @rows[y,1] = @border_rx_row
  296.       # Re-Initialize row border temporaries for next iteraton
  297.       @border_lx_row = @width/32
  298.       @border_rx_row = 0
  299.     end
  300.   end
  301.   #--------------------------------------------------------------------------
  302.   # * Setup_tiles (reads tiles for this layer and defines the borders.
  303.   # Makes use of special rules for reading)
  304.   #--------------------------------------------------------------------------
  305.   def setup_tiles
  306.     # Get pre-sorted tile data with priority of the layer
  307.     @data_link = $game_map.priority_data(@priority)
  308.     # Clone hashs, needed for functionally interation while deleting stuff
  309.     # from the data
  310.     @data = @data_link.dup
  311.     @data_link.each_pair do |dx,data_x|
  312.       dat_x = @data[dx]
  313.       dat_x = data_x.dup
  314.       data_x.each_pair do |dz,data_z|
  315.         dat_x[dz] = data_z.dup
  316.       end
  317.     end
  318.     # Iterate through sorted tiles on y-axis
  319.     @data.each_pair do |y,data_y|
  320.       # Iterate through sorted tiles on x-axis
  321.       data_y.each_pair do |x,data_x|
  322.         # Initialize autotile found flag to false
  323.         autotile_found = false
  324.         # Iterate through map editor layers downwards
  325.         data_x.each_pair do |z,t|
  326.         # Iterate through map editor layers
  327.           # Get tile id
  328.           # Store whether tile fits layer properties or not
  329.           # only true if t is a autotile
  330.           tiles_include = @tiles.include?(t/48-1)
  331.           # If tile is included or tile is from tileset or tile is autotile
  332.           # with 1 frame
  333.           if tiles_include || (t >= 384 || @autotile_frames[t/48-1] <= 1)
  334.             # Store in cache
  335.             @cache[y] = {} if @cache[y] == nil
  336.             @cache[y][x] = {} if @cache[y][x] == nil
  337.             @cache[y][x][z] = t
  338.             # If tile is a autotile and is included
  339.             if t < 384 && tiles_include
  340.               # Delete from map data list
  341.               @data_link[y][x].delete(z)
  342.               @data_link[y].delete(x) if @data_link[y][x].size == 0
  343.               @data_link.delete(y) if @data_link[y].size == 0
  344.               # Extend borders
  345.               border(x,y)
  346.               # Set autotile found flag to true
  347.               autotile_found = true
  348.             end
  349.           end
  350.         end
  351.         # If no autotile was found & row at y is not empty and x-position is not empty
  352.         if autotile_found == false && @cache[y] != nil && @cache[y][x] != nil
  353.           # Delete all tiles on x-position from cache
  354.           @cache[y].delete(x)
  355.           @cache.delete(y) if @data_link[y].size == 0  
  356.         end
  357.       end
  358.       # Set row borders
  359.       @rows[y,0] = @border_lx_row
  360.       @rows[y,1] = @border_rx_row
  361.       # Re-Initialize row border temporaries for next iteration
  362.       @border_lx_row = @width/32
  363.       @border_rx_row = 0
  364.     end
  365.   end
  366.   #--------------------------------------------------------------------------
  367.   # * Create_Sprites (creates sprites & mitmaps for every row)
  368.   #--------------------------------------------------------------------------
  369.   def create_sprites
  370.     # Iterate through tiles on y-axis
  371.     for y in @cache.keys
  372.       # If row is not valid
  373.       if !row_valid?(y)
  374.         # skip to next
  375.         next
  376.       end
  377.       # Calculate row width
  378.       distx = @rows[y,1] - @rows[y,0]
  379.       # Create sprite
  380.       sprite = Sprite.new(@viewport)
  381.       # Create bitmap with row-width*count of frames
  382.       sprite.bitmap = Bitmap.new(distx*32*@frames,32)
  383.       sprite.x = @rows[y,0]*32-$game_map.display_x/4
  384.       sprite.y = y*32-$game_map.display_y/4
  385.       # Set source rect to frame 0
  386.       sprite.src_rect = Rect.new(0,0,distx*32,32)
  387.       sprite.blend_type = @blend_type
  388.       # If priority equals 0
  389.       if @priority == 0
  390.         # Set z to 0, always beyond later created layers
  391.         sprite.z = 0
  392.       else
  393.         # Set z to base + priority + dosition - display-Position
  394.         sprite.z = 32 + 32*@priority + 32*y - $game_map.display_y/4
  395.       end
  396.       # Add sprite to hash
  397.       @sprites[y] = sprite
  398.     end
  399.   end
  400.   #--------------------------------------------------------------------------
  401.   # * Border (enhances the borders of the layer and the current row)
  402.   #--------------------------------------------------------------------------
  403.   def border(x,y)
  404.     # If X is outside left border
  405.     if x < @border_lx
  406.       # Extend left border to x
  407.       @border_lx = x
  408.     end
  409.     # If X is outside right border
  410.     if x > @border_rx
  411.       # Extend right border to x+1
  412.       @border_rx = x+1
  413.     end
  414.     # If Y is outside top border
  415.     if y < @border_ty
  416.       # Extend top border to y
  417.       @border_ty = y
  418.     end
  419.     # If Y is outside bottom border
  420.     if y > @border_by
  421.       # Extend bottom_border to y
  422.       @border_by = y
  423.     end
  424.     # If X is outside left row border
  425.     if x < @border_lx_row
  426.       # Extend left row border to x
  427.       @border_lx_row = x
  428.     end
  429.     # If X is outside right row border
  430.     if x+1 > @border_rx_row
  431.       # Extend right row border to y
  432.       @border_rx_row = x+1
  433.     end
  434.   end
  435.   #--------------------------------------------------------------------------
  436.   # * Update (updates row's position in the image as well as animations)
  437.   #--------------------------------------------------------------------------
  438.   def update(ox,oy)
  439.     # Get first and last row 1 outside screen
  440.     dy = oy/32.0
  441.     l = [dy.to_i-1,@border_ty].max
  442.     r = [dy.to_i+17,@border_by].min
  443.     # If time exceedes speed
  444.     if @time > @speed
  445.       # Reinit time, advance state
  446.       @time = 0
  447.       @state += 1
  448.       # Iterate through every row on screen
  449.       for i in l..r
  450.         # Skip to next If row has no sprite
  451.         sprite = @sprites[i]
  452.         next if sprite == nil || sprite.disposed? || !$game_map.tone
  453.         # Set sprite properties
  454.         sprite.tone = $game_map.tone# if @blend_type == 0
  455.         sprite.x = @rows[i,0]*32-ox
  456.         sprite.y = i*32-oy
  457.         sprite.zoom_x = $game_map.zoom_x || 1.0
  458.         sprite.zoom_y = $game_map.zoom_y || 1.0
  459.         sprite.x = (sprite.x * sprite.zoom_x)
  460.         sprite.y = (sprite.y * sprite.zoom_y)
  461.         # If priority equals 0
  462.         if @priority == 0
  463.           # Set Z to 0, always beyond later created tiles
  464.           sprite.z = 0
  465.         else
  466.           # Set Z to Base + Priority + Position - Tilemap position
  467.           sprite.z = 32 + 32*@priority + i*32 - oy
  468.         end
  469.         sprite.z *= ((sprite.zoom_x + sprite.zoom_y) / 2)
  470.         # Get row width
  471.         lx = @rows[i,0]
  472.         w = @rows[i,1] - lx
  473.         # Set animation frame
  474.         sprite.src_rect = Rect.new(@state*w*32,0,w*32,32)
  475.       end
  476.       # If state exceeded frame count
  477.       if @state >= @frames-1
  478.         # Reset state
  479.         @state = -1
  480.       end
  481.     # Else: just update position
  482.     else
  483.       # Iterate through every row on screen
  484.       for i in l..r
  485.         # Skip to next if row has no sprite
  486.         sprite = @sprites[i]
  487.         next if sprite == nil || sprite.disposed? || !$game_map.tone
  488.           # Set sprite properties
  489.         sprite.tone = $game_map.tone# if @blend_type == 0
  490.         sprite.x = @rows[i,0]*32-ox
  491.         sprite.y = i*32-oy
  492.         sprite.zoom_x = $game_map.zoom_x || 1.0
  493.         sprite.zoom_y = $game_map.zoom_y || 1.0
  494.         sprite.x = (sprite.x * sprite.zoom_x)
  495.         sprite.y = (sprite.y * sprite.zoom_y)
  496.         # If priority equals 0
  497.         if @priority == 0
  498.           # Set Z to 0, always beyond later created tiles
  499.           sprite.z = 0
  500.         else
  501.           # Set Z to Base + Priority + Position - Tilemap position
  502.           sprite.z = 32 + 32*@priority + i*32 - oy
  503.         end
  504.         sprite.z *= ((sprite.zoom_x + sprite.zoom_y) / 2)
  505.       end
  506.     end
  507.     # Advance time
  508.     @time += 1
  509.   end
  510.   #--------------------------------------------------------------------------
  511.   # * Refresh (refreshes all row's properties)
  512.   #--------------------------------------------------------------------------
  513.   def refresh
  514.     # Iterate through all sprites
  515.     for y in @cache.keys
  516.       # Skip if sprite doesn't exist
  517.       sprite = @sprites[y]
  518.       next if sprite == nil
  519.       sprite.tone = $game_map.tone if $game_map.tone
  520.       # If priority equals 0
  521.       sprite.x = @rows[y,0]*32-$game_map.display_x/4
  522.       sprite.y = y*32-$game_map.display_y/4
  523.       sprite.zoom_x = $game_map.zoom_x || 1.0
  524.       sprite.zoom_y = $game_map.zoom_y || 1.0
  525.       sprite.x = (sprite.x * sprite.zoom_x)
  526.       sprite.y = (sprite.y * sprite.zoom_y)
  527.       if @priority == 0
  528.         # Set z to 0, always beyond
  529.         sprite.z = 0
  530.       else
  531.         # Set Z to Base + Priority + Position - Screen Position
  532.         sprite.z = 32+32*@priority+y*32-$game_map.display_y/4
  533.       end
  534.       sprite.z *= ((sprite.zoom_x + sprite.zoom_y) / 2)
  535.     end
  536.   end
  537.   #--------------------------------------------------------------------------
  538.   # * Draw_tiles_blend (draws the complete layer in the single rows. Makes
  539.   #  use of special rules for 1/2-blended autotiles)
  540.   #--------------------------------------------------------------------------
  541.   def draw_tiles_blend
  542.     # Iterate through cached tiles on y axis
  543.     @cache.each_pair do |y,cache_y|
  544.       sprite = @sprites[y]
  545.       next if cache_y == nil
  546.       lx = @rows[y,0]
  547.       w = @rows[y,1]-lx
  548.       cache_y.each_pair do |x,cache_x|
  549.         x_values = RGSS3 ? cache_x.values.reverse : cache_x.values
  550.         x_values.each do |t| #RGSS3
  551.           file = (t / 48) - 1
  552.           a = t - (file+1)*48
  553.           for f in 0...@frames
  554.             autotile = RPG::Cache.atile($game_map.autotile_names[file],a,f)
  555.             sprite.bitmap.blt(-lx*32+x*32+f*w*32,0,autotile,autotile.rect)
  556.           end
  557.         end
  558.       end
  559.     end
  560.     RPG::Cache.clear_auto
  561.   end
  562.   #--------------------------------------------------------------------------
  563.   # * Draw_tiles
  564.   #--------------------------------------------------------------------------
  565.   def draw_tiles
  566.     @cache.each_pair do |y,cache_y|
  567.       sprite = @sprites[y]
  568.       lx = @rows[y,0]
  569.       w = @rows[y,1]-lx
  570.       cache_y.each_pair do |x,cache_x|
  571.         x_values = RGSS3 ? cache_x.keys.reverse : cache_x.keys
  572.         x_values.each do |z| #RGSS3
  573.           t = cache_x[z]
  574.           if t < 384
  575.             file = (t / 48) - 1
  576.             a = t - (file+1)*48
  577.             for f in 0...@frames
  578.               autotile = RPG::Cache.atile($game_map.autotile_names[file],a,f)
  579.               sprite.bitmap.blt(-lx*32+x*32+f*w*32,0,autotile,autotile.rect)
  580.             end
  581.             if @autotile_frames[file] <= 1
  582.               @data_link[y][x].delete(z)
  583.               @data_link[y].delete(x) if @data_link[y][x].size == 0
  584.               @data_link.delete(y) if @data_link[y].size == 0
  585.             end
  586.           else
  587.             t -=384
  588.             xt = t%8
  589.             yt = t/8
  590.             r = Rect.new(xt*32,yt*32,32,32)
  591.             for f in 0...@frames
  592.               sprite.bitmap.blt(-lx*32+x*32+f*w*32,0,@tileset,r)
  593.             end
  594.             @data_link[y][x].delete(z)
  595.             @data_link[y].delete(x) if @data_link[y][x].size == 0
  596.             @data_link.delete(y) if @data_link[y].size == 0
  597.           end
  598.         end
  599.       end
  600.     end
  601.     RPG::Cache.clear_auto
  602.   end
  603.   #--------------------------------------------------------------------------
  604.   # * Frame Dispose
  605.   #--------------------------------------------------------------------------
  606.   def dispose
  607.     @sprites.each_value {|sprite|  sprite.dispose }
  608.   end
  609. end
  610.  
  611. module RPG
  612.   module Cache
  613.    
  614.     [[27,28,33,34],[5,28,33,34] ,[27,6,33,34] ,[5,6,33,34]  ,
  615.     [27,28,33,12] ,[5,28,33,12] ,[27,6,33,12] ,[5,6,33,12]  ,[27,28,11,34],
  616.     [5,28,11,34]  ,[27,6,11,34] ,[5,6,11,34]  ,[27,28,11,12],[5,28,11,12] ,
  617.     [27,6,11,12]  ,[5,6,11,12]  ,[25,26,31,32],[25,6,31,32] ,[25,26,31,12],
  618.     [25,6,31,12]  ,[15,16,21,22],[15,16,21,12],[15,16,11,22],[15,16,11,12],
  619.     [29,30,35,36] ,[29,30,11,36],[5,30,35,36] ,[5,30,11,36] ,[39,40,45,46],
  620.     [5,40,45,46]  ,[39,6,45,46] ,[5,6,45,46]  ,[25,30,31,36],[15,16,45,46],
  621.     [13,14,19,20] ,[13,14,19,12],[17,18,23,24],[17,18,11,24],[41,42,47,48],
  622.     [5,42,47,48]  ,[37,38,43,44],[37,6,43,44] ,[13,18,19,24],[13,14,43,44],
  623.     [37,42,43,48] ,[17,18,47,48],[13,18,43,48],[13,18,43,48]]
  624.  
  625.     AUTOTILES = [26, 27, 32, 33,  4, 27, 32, 33, # 1
  626.                  26, 5, 32, 33,   4,  5, 32, 33, # 3
  627.                  26, 27, 32, 11,  4, 27, 32, 11, # 5
  628.                  26,  5, 32, 11,  4,  5, 32, 11, # 7
  629.                  26, 27, 10, 33,  4, 27, 10, 33, # 9
  630.                  26,  5, 10, 33,  4,  5, 10, 33, # 11
  631.                  26, 27, 10, 11,  4, 27, 10, 11, # 13
  632.                  26,  5, 10, 11,  4,  5, 10, 11, # 15
  633.                  24, 25, 30, 31, 24,  5, 30, 31, # 17
  634.                  24, 25, 30, 11, 24,  5, 30, 11, # 19
  635.                  14, 15, 20, 21, 14, 15, 20, 11, # 21
  636.                  14, 15, 10, 21, 14, 15, 10, 11, # 23
  637.                  28, 29, 34, 35, 28, 29, 10, 35, # 25
  638.                   4, 29, 34, 35,  4, 29, 10, 35, # 27
  639.                  38, 39, 44, 45,  4, 39, 44, 45, # 29
  640.                  38,  5, 44, 45,  4,  5, 44, 45, # 31
  641.                  24, 29, 30, 35, 14, 15, 44, 45, # 33
  642.                  12, 13, 18, 19, 12, 13, 18, 11, # 35
  643.                  16, 17, 22, 23, 16, 17, 10, 23, # 37
  644.                  40, 41, 46, 47,  4, 41, 46, 47, # 39
  645.                  36, 37, 42, 43, 36,  5, 42, 43, # 41
  646.                  12, 17, 18, 23, 12, 13, 42, 43, # 43
  647.                  36, 41, 42, 47, 16, 17, 46, 47, # 45
  648.                  12, 17, 42, 47,  0,  1,  6,  7] # 47
  649.  
  650.     module_function
  651.     def atile(file, id , offset)
  652.       @auto_cache ||= {}
  653.       if @auto_cache[[file,id,offset]] == nil
  654.         autotile_bitmap = Bitmap.new(32, 32)
  655.         autotiles_bitmap = autotile(file)
  656.         if autotiles_bitmap.height == 32
  657.           if offset*32 >= autotiles_bitmap.width
  658.             autotile_bitmap.blt(0,0,autotiles_bitmap,Rect.new(0,0,32,32))
  659.           else
  660.             autotile_bitmap.blt(0,0,autotiles_bitmap,Rect.new(offset*32,0,32,32))
  661.           end
  662.           @auto_cache[[file,id,offset]] = autotile_bitmap
  663.           return autotile_bitmap
  664.         end
  665.         real_id = id*4
  666.         off = offset*96
  667.         if off>=autotiles_bitmap.width
  668.           off = 0
  669.         end
  670.         auto1 = AUTOTILES.at(real_id + 0)
  671.         auto2 = AUTOTILES.at(real_id + 1)
  672.         auto3 = AUTOTILES.at(real_id + 2)
  673.         auto4 = AUTOTILES.at(real_id + 3)
  674.         rect1 = Rect.new(auto1 % 6 * 16 + off, auto1 / 6 * 16, 16, 16)
  675.         rect2 = Rect.new(auto2 % 6 * 16 + off, auto2 / 6 * 16, 16, 16)
  676.         rect3 = Rect.new(auto3 % 6 * 16 + off, auto3 / 6 * 16, 16, 16)
  677.         rect4 = Rect.new(auto4 % 6 * 16 + off, auto4 / 6 * 16, 16, 16)
  678.         autotile_bitmap.blt(0, 0, autotiles_bitmap, rect1)
  679.         autotile_bitmap.blt(16, 0, autotiles_bitmap, rect2)
  680.         autotile_bitmap.blt(0, 16, autotiles_bitmap, rect3)
  681.         autotile_bitmap.blt(16, 16, autotiles_bitmap, rect4)
  682.         @auto_cache[[file,id,offset]] = autotile_bitmap
  683.       end
  684.       return @auto_cache[[file,id,offset]]
  685.     end
  686.  
  687.     def clear_auto
  688.       @auto_cache ||= {}
  689.       @auto_cache.values.each {|bitmap|  bitmap.dispose}
  690.       @auto_cache.clear
  691.       #GC.start
  692.     end
  693.   end
  694. end
  695.  
  696. #==============================================================================
  697. # ** Sprite_Layer NEW
  698. #------------------------------------------------------------------------------
  699. #  
  700. #  This class manages tile layers. Every layer contains multipe sprites, one
  701. #  for each tile row. Furthermore creates the respective bitmaps for the layer.
  702. #
  703. #==============================================================================
  704. class Sprite_Layer
  705.   #--------------------------------------------------------------------------
  706.   # * Initialize (read tiles, create sprites & bitmaps)
  707.   #--------------------------------------------------------------------------
  708.   def initialize(viewport,priority,autotile_frames,cache=nil)
  709.     # Get Tileset ID
  710.     @tileset_id = $game_map.map.tileset_id
  711.     # Class variables
  712.     @priority = priority
  713.     @autotile_frames = autotile_frames
  714.     @viewport = viewport
  715.     # Calculate number of tiles on x and y axis
  716.     @width = $game_map.width
  717.     @height = $game_map.height
  718.     # Cache for the tiles
  719.     if cache == nil
  720.       @cache = {}
  721.     else
  722.       @cache = cache
  723.     end
  724.     # Set layer border variables to l<->r and u<->d (changed max/min values)
  725.     @border_lx = @width
  726.     @border_ty = @height
  727.     @border_rx = 0
  728.     @border_by = 0
  729.     # Row border
  730.     @border_lx_row = @width
  731.     @border_rx_row = 0
  732.     # Table to store left and right border of every row
  733.     @rows = Table.new(@height,2)
  734.     # Hash for the sprites
  735.     @sprites = {}
  736.     # Setup tiles
  737.     if @cache.size == 0
  738.       setup_tiles
  739.     else
  740.       setup_tiles_cache
  741.     end
  742.     # If not valid, return
  743.     return if !valid?
  744.     # Otherwise, create sprites
  745.     create_sprites
  746.     # Get tileset graphic
  747.     @tileset = RPG::Cache.tileset($game_map.tileset_name)
  748.     # Draw tiles
  749.     draw_tiles
  750.     @tileset = nil
  751.   end
  752.   #--------------------------------------------------------------------------
  753.   # * Valid? (checks whether found in tiles for this layer)
  754.   #--------------------------------------------------------------------------
  755.   def valid?
  756.     # If right border greater or equal to left border and
  757.     # top border greater or equal to bottom border then true
  758.     return @border_rx >= @border_lx && @border_by >= @border_ty
  759.   end
  760.   #--------------------------------------------------------------------------
  761.   # * Row_valid? (checks whether found in tiles in row y)
  762.   #--------------------------------------------------------------------------
  763.   def row_valid?(y)
  764.     # If right row border is greater than left row border true
  765.     return @rows[y,1]>@rows[y,0]
  766.   end
  767.   #--------------------------------------------------------------------------
  768.   # * Setup_tiles (reads tiles for this layer and defines the borders)
  769.   #--------------------------------------------------------------------------
  770.   def setup_tiles
  771.     # Get pre-sorted Tile data with priority of the layer
  772.     @data_link = $game_map.priority_data(@priority)
  773.     # Clone hashs, needed for functionally interation while deleting stuff
  774.     # from the data
  775.     @data = @data_link.clone
  776.     @data_link.each_pair do |dx,data_x|
  777.       dat_x = @data[dx]
  778.       dat_x = data_x.dup
  779.       data_x.each_pair do |dz,data_z|
  780.         dat_x[dz] = data_z.dup
  781.       end
  782.     end
  783.     # Iterate through sorted tiles on y-axis
  784.     @data.each_pair do |y,data_y|
  785.       # Iterate through sorted tiles on x-axis
  786.       data_y.each_pair do |x,data_x|
  787.         # Iterate through map editor layers downwards
  788.         data_x.each_pair do |z,t|
  789.           # Get Tile ID
  790.           # If tile is from tileset or autotile with 1 frame
  791.           if t >= 384 || @autotile_frames[t/48-1] <= 1
  792.             # Store in cache
  793.             @cache[y] = {} if @cache[y] == nil
  794.             @cache[y][x] = {} if @cache[y][x] == nil
  795.             @cache[y][x][z] = t
  796.             # Extend border
  797.             border(x,y)
  798.             # Delete from sorted tile list
  799.             #@data_link[y][x].delete(z)
  800.             #@data_link[y].delete(x) if @data_link[y][x].size == 0
  801.             #@data_link.delete(y) if @data_link[y].size == 0
  802.           end
  803.         end
  804.       end
  805.       # Set row borders
  806.       @rows[y,0] = @border_lx_row
  807.       @rows[y,1] = @border_rx_row
  808.       # Re-Initialize row borders for next iteration
  809.       @border_lx_row = @width/32
  810.       @border_rx_row = 0
  811.     end
  812.   end
  813.   #--------------------------------------------------------------------------
  814.   # * Setup_tiles_Cache
  815.   #--------------------------------------------------------------------------
  816.   def setup_tiles_cache
  817.     # Get pre-sorted Tile data with priority of the layer
  818.     @data_link = $game_map.priority_data(@priority)
  819.     # Clone hashs, needed for functionally interation while deleting stuff
  820.     # from the data
  821.     @data = @data_link.clone
  822.     @data_link.each_pair do |dx,data_x|
  823.       dat_x = @data[dx]
  824.       dat_x = data_x.dup
  825.       data_x.each_pair do |dz,data_z|
  826.         dat_x[dz] = data_z.dup
  827.       end
  828.     end
  829.     # Iterate through sorted tiles on y-axis
  830.     @cache.each_pair do |y,cache_y|
  831.       # Iterate through sorted tiles on x-axis
  832.       cache_y.each_pair do |x,cache_x|
  833.         # Iterate through map editor layers
  834.         border(x,y) if cache_x.size > 0
  835.       end
  836.       # Set row borders
  837.       @rows[y,0] = @border_lx_row
  838.       @rows[y,1] = @border_rx_row
  839.       # Re-Initialize row borders for next iteration
  840.       @border_lx_row = @width/32
  841.       @border_rx_row = 0
  842.     end
  843.   end
  844.   #--------------------------------------------------------------------------
  845.   # * Create_Sprites (creates sprites & bitmaps for each row)
  846.   #--------------------------------------------------------------------------
  847.   def create_sprites
  848.     # Iterate from upper border to lower border
  849.     for y in @border_ty..@border_by
  850.       # If row is not valid
  851.       if !row_valid?(y)
  852.         # Skip to next
  853.         next
  854.       end
  855.       # Otherwise, calculate distance from left to right border
  856.       distx = @rows[y,1] - @rows[y,0]
  857.       # Create sprite
  858.       sprite = Sprite.new(@viewport)
  859.       # Create bitmap in row-size
  860.       sprite.bitmap = Bitmap.new(distx*32,32)
  861.       # Set x-coordinate to left border
  862.       sprite.x = @rows[y,0]*32-$game_map.display_x/4
  863.       # Set y-coordinate to row y
  864.       sprite.y = y*32-$game_map.display_y/4
  865.       sprite.blend_type = 0
  866.       # If priority equals 0
  867.       if @priority == 0
  868.         # Set Z to 0, Sprite always beyond later created
  869.         sprite.z = 0
  870.       else
  871.         # Set Z to Base + Priority + Position - Screen Position
  872.         sprite.z = 32 + 32*@priority + y*32 - $game_map.display_y/4
  873.       end
  874.       # Add sprite to hash
  875.       @sprites[y] = sprite
  876.     end
  877.   end
  878.   #--------------------------------------------------------------------------
  879.   # * Border (enhances borders of layer and current row)
  880.   #--------------------------------------------------------------------------
  881.   def border(x,y)
  882.     # If X is outside left border
  883.     if x < @border_lx
  884.       # Extend left border to x
  885.       @border_lx = x
  886.     end
  887.     # If X is outside right border
  888.     if x > @border_rx
  889.       # Extend right border to x+1
  890.       @border_rx = x+1
  891.     end
  892.     # If Y is outside top border
  893.     if y < @border_ty
  894.       # Extend top border to y
  895.       @border_ty = y
  896.     end
  897.     # If Y is outside bottom border
  898.     if y > @border_by
  899.       # Extend bottom_border to y
  900.       @border_by = y
  901.     end
  902.     # If X is outside left row border
  903.     if x < @border_lx_row
  904.       # Extend left row border to x
  905.       @border_lx_row = x
  906.     end
  907.     # If X is outside right row border
  908.     if x+1 > @border_rx_row
  909.       # Extend right row border to y
  910.       @border_rx_row = x+1
  911.     end
  912.   end
  913.   #--------------------------------------------------------------------------
  914.   # * Update (updates position of image's rows)
  915.   #--------------------------------------------------------------------------
  916.   def update(ox,oy)
  917.     # Get uppermost row 1 block outside of screen
  918.     y = [((oy*4-224)/128).to_i,@border_ty].max
  919.     # Get lowermost row 1 block outside of screen
  920.     y2 = [y+17,@border_by].min
  921.     # Iterate from uppermost to lowermost row
  922.     for i in y..y2
  923.       # Skip if row has no sprite
  924.       sprite = @sprites[i]
  925.       next if sprite == nil || sprite.disposed? || !$game_map.tone
  926.       sprite.tone = $game_map.tone
  927.       # If priority equals 0
  928.       sprite.x = @rows[i,0]*32-ox
  929.       sprite.y = i*32-oy
  930.       sprite.zoom_x = $game_map.zoom_x || 1.0
  931.       sprite.zoom_y = $game_map.zoom_y || 1.0
  932.       sprite.x = (sprite.x * sprite.zoom_x)
  933.       sprite.y = (sprite.y * sprite.zoom_y)
  934.       if @priority == 0
  935.         # Set z to 0, always beyond
  936.         sprite.z = 0
  937.       else
  938.         # Set Z to Base + Priority + Position - Screen Position
  939.         sprite.z = 32+32*@priority+i*32-oy
  940.       end
  941.       sprite.z *= ((sprite.zoom_x + sprite.zoom_y) / 2)
  942.     end
  943.   end
  944.   #--------------------------------------------------------------------------
  945.   # * Refresh (refreshes all sprites' properties)
  946.   #--------------------------------------------------------------------------
  947.   def refresh
  948.     # Iterate through all sprites
  949.     for y in @cache.keys
  950.       sprite = @sprites[y]
  951.       # Skip if sprite doesn't exist
  952.       next if sprite == nil
  953.       sprite.tone = $game_map.tone if $game_map.tone
  954.       # If priority equals 0
  955.       sprite.x = @rows[y,0]*32-$game_map.display_x/4
  956.       sprite.y = y*32-$game_map.display_y/4
  957.       sprite.zoom_x = $game_map.zoom_x || 1.0
  958.       sprite.zoom_y = $game_map.zoom_y || 1.0
  959.       sprite.x = (sprite.x * sprite.zoom_x)
  960.       sprite.y = (sprite.y * sprite.zoom_y)
  961.       if @priority == 0
  962.         # Set z to 0, always beyond
  963.         sprite.z = 0
  964.       else
  965.         # Set Z to Base + Priority + Position - Screen Position
  966.         sprite.z = 32+32*@priority+y*32-$game_map.display_y/4
  967.       end
  968.       sprite.z *= ((sprite.zoom_x + sprite.zoom_y) / 2)
  969.     end
  970.   end
  971.   #--------------------------------------------------------------------------
  972.   # * Draw_tiles (draws the complete layer into the single rows)
  973.   #--------------------------------------------------------------------------
  974.   def draw_tiles
  975.     # Iterate through all cached tiles on y-axis
  976.     @cache.each_pair do |y,cache_y|
  977.       # Iterate through all cached tiles on x-axis
  978.       sprite = @sprites[y]
  979.       cache_y.each_pair do |x,cache_x|
  980.         x_values = RGSS3 ? cache_x.values.reverse : cache_x.values
  981.         # Iterate through all cached tile layers (map-editor)
  982.         # ! Lowest z first !
  983.         x_values.each do |t| #RGSS3
  984.           # Get tile ID from cache
  985.           # Get left border of row
  986.           lx = @rows[y,0]
  987.           # If tile is from tileset
  988.           if t >= 384
  989.             # Calculate x/y-position on tileset
  990.             t -= 384
  991.             xt = t%8
  992.             yt = t/8
  993.             # Source rect
  994.             r = Rect.new(xt*32,yt*32,32,32)
  995.             # Blt tile from tileset to row on -border+x
  996.             sprite.bitmap.blt(-lx*32+x*32,0,@tileset,r)
  997.           # Else: Tile is an autotile (with 1 frame)
  998.           else
  999.             # Calculate file id and autotile id
  1000.             file = (t / 48) - 1
  1001.             a = t - (file+1)*48
  1002.             # Get autotile bitmap from RPG::Cache
  1003.             autotile = RPG::Cache.atile($game_map.autotile_names[file],a,0)
  1004.             # Blt autotile to row on -border+x
  1005.             sprite.bitmap.blt(-lx*32+x*32,0,autotile,autotile.rect)
  1006.           end
  1007.         end
  1008.       end
  1009.     end
  1010.     # Clear autotile cache
  1011.     RPG::Cache.clear_auto
  1012.   end
  1013.   #--------------------------------------------------------------------------
  1014.   # * Dispose (delete row sprites)
  1015.   #--------------------------------------------------------------------------
  1016.   def dispose
  1017.     # Dispose every sprite
  1018.     for sprite in @sprites.values
  1019.       sprite.dispose
  1020.     end
  1021.   end
  1022. end
  1023.  
  1024. #==============================================================================
  1025. # ** Tilemap_New NEW
  1026. #------------------------------------------------------------------------------
  1027. #  
  1028. #  This is the script's core, the new tilemap class. Currently contains methods
  1029. #  for updating and deleting, mostly self-managing.
  1030. #  Creates up to 5 layers and 6 autotile layers. Layers are created depending
  1031. #  on priority and mapping, autotile layer depending on properties of autotiles
  1032. #  (speed,frames,blend mode).
  1033. #
  1034. #==============================================================================
  1035. class Tilemap_New
  1036.   #--------------------------------------------------------------------------
  1037.   # * Public Instance Variables
  1038.   #--------------------------------------------------------------------------
  1039.   attr_accessor :tileset,:autotiles,:viewport
  1040.   attr_reader :autotile_frames
  1041.   #--------------------------------------------------------------------------
  1042.   # * Initialize (create layer)
  1043.   #--------------------------------------------------------------------------
  1044.   def initialize(viewport,tileset,autiles)
  1045.     # Save tileset & autotiles
  1046.     @viewport = viewport
  1047.     @tileset = tileset
  1048.     @autotiles = autiles
  1049.     # Get number of frames per autotile
  1050.     @autotile_frames = []
  1051.     for autotile in @autotiles
  1052.       # If autotiles height exceeds 32
  1053.       if autotile.height > 32
  1054.         @autotile_frames << autotile.width/96
  1055.       # Else: autotiles in X*32 format
  1056.       else
  1057.         @autotile_frames << autotile.width/32
  1058.       end
  1059.     end
  1060.     # Tileset ID
  1061.     id = $game_map.map.tileset_id
  1062.     # Temporaries
  1063.     autotiles = []
  1064.     done = []
  1065.     autotiles_later = {}
  1066.     # Class variables
  1067.     @autotile_layers = []
  1068.     @layers = []
  1069.     @ox = 0
  1070.     @oy = 0
  1071.     # Iterate through autotiles
  1072.     for i in 0..6
  1073.       # Get frames
  1074.       frames = @autotile_frames[i]
  1075.       # If only one frame => static, skip
  1076.       next if frames <= 1 || done.include?(i)
  1077.       # Get properties
  1078.       speed = AUTOTILE::SPEED[id][i] if AUTOTILE::SPEED[id] != nil
  1079.       speed = AUTOTILE::DEFAULT_SPEED if speed == nil
  1080.       blend_type = AUTOTILE::BLEND_TYPE[id][i] if AUTOTILE::BLEND_TYPE[id] != nil
  1081.       blend_type = 0 if blend_type == nil
  1082.       priority = $game_map.priorities[(i+1)*48]
  1083.       # Iterate through all autotiles >= current one
  1084.       # Batches similar autotiles in the same layer -> less memody/lag
  1085.       for j in i..6
  1086.         # Get 2nd autotile properties
  1087.         speed2 = AUTOTILE::SPEED[id][j] if AUTOTILE::SPEED[id] != nil
  1088.         speed2 = AUTOTILE::DEFAULT_SPEED if speed2 == nil
  1089.         frames2 = @autotile_frames[j]
  1090.         blend_type2 = AUTOTILE::BLEND_TYPE[id][j] if AUTOTILE::BLEND_TYPE[id] != nil
  1091.         blend_type2 = 0 if blend_type2 == nil
  1092.         priority2 = $game_map.priorities[(j+1)*48]
  1093.         # If properties of both autotiles match
  1094.         if speed2 == speed && frames2 == frames && blend_type2 == blend_type &&
  1095.           priority2 == priority
  1096.           # Store autotile id
  1097.           autotiles << j
  1098.           # Store properties
  1099.           speed3 = speed
  1100.           frames3 = frames
  1101.           priority3 = priority
  1102.           blend_type3 = blend_type
  1103.           # Autotile id is done
  1104.           done << j
  1105.         end
  1106.       end
  1107.       # If special blended autotiles
  1108.       if blend_type3 >= 1
  1109.         # Store autotile ids & properties for later creation (z-priority)
  1110.         autotiles_later[priority3] = [] if autotiles_later[priority3] == nil
  1111.         autotiles_later[priority3] << Command_Autotile.new(autotiles,speed3,@autotile_frames,priority3,blend_type3)
  1112.       # Else : Normal blended tile
  1113.       else
  1114.         # Create autotile-Layer
  1115.         @autotile_layers << Sprite_Auto.new(@viewport,autotiles,speed3,@autotile_frames,priority3,blend_type3)
  1116.         # Delete if not valid
  1117.         @autotile_layers.delete_at(@autotile_layers.size-1) if !@autotile_layers[@autotile_layers.size-1].valid?
  1118.       end
  1119.       autotiles.clear
  1120.     end
  1121.     # Iterate through all priority layers
  1122.     for i in 0..5
  1123.       # Create layer sprite
  1124.       sprite = Sprite_Layer.new(@viewport,i,@autotile_frames)
  1125.       # Keep sprite onty if valid?
  1126.       @layers << sprite if sprite.valid?
  1127.       # If blended autotile waits for creation at current priority
  1128.       if autotiles_later[i] != nil
  1129.         # Iterate through autotile commands
  1130.         for c in autotiles_later[i]
  1131.           # Create autotile-layer
  1132.           @autotile_layers << Sprite_Auto.new(@viewport,c.autotiles,c.speed,c.frames,c.priority,c.blend_type)
  1133.           # Delete if not valid
  1134.           @autotile_layers.delete_at(@autotile_layers.size-1) if !@autotile_layers[@autotile_layers.size-1].valid?
  1135.         end
  1136.         # Delete command layer
  1137.         autotiles_later.delete(i)
  1138.       end
  1139.     end
  1140.   end
  1141.   #--------------------------------------------------------------------------
  1142.   # * Ox (returns tilemap x-position)
  1143.   #--------------------------------------------------------------------------
  1144.   def ox
  1145.     return @ox
  1146.   end
  1147.   #--------------------------------------------------------------------------
  1148.   # * Oy (returns tilemap y-position)
  1149.   #--------------------------------------------------------------------------
  1150.   def oy
  1151.     return @oy
  1152.   end
  1153.   #--------------------------------------------------------------------------
  1154.   # * Ox= (sets tilemap x-position)
  1155.   #--------------------------------------------------------------------------
  1156.   def ox=(ox)
  1157.     # Return if position is equal to new position
  1158.     return if @ox == ox
  1159.     @ox = ox
  1160.   end
  1161.   #--------------------------------------------------------------------------
  1162.   # * Oy= (sets tilemap y-position)
  1163.   #--------------------------------------------------------------------------
  1164.   def oy=(oy)
  1165.     # Return if position is equal to new position
  1166.     return if @oy == oy
  1167.     @oy = oy
  1168.   end
  1169.   #--------------------------------------------------------------------------
  1170.   # * Initialize (position,frames,z-position)
  1171.   #--------------------------------------------------------------------------
  1172.   def update
  1173.     # Update viewport. Corrupts standard x/y positions of fog,characters,weather,
  1174.     # panorama, corrected in the corresponding method
  1175.     #@viewport.ox = $game_map.display_x/4
  1176.     #@viewport.oy = $game_map.display_y/4
  1177.     # Update autotile_layers
  1178.     @autotile_layers.each {|layer| layer.update(@ox,@oy)}
  1179.     # Update_layers
  1180.     @layers.each {|layer| layer.update(@ox,@oy)}
  1181.   end
  1182.   #--------------------------------------------------------------------------
  1183.   # * Dispose (delete layer & autotile layer)
  1184.   #--------------------------------------------------------------------------
  1185.   def dispose
  1186.     # Dispose autotile layers
  1187.     @autotile_layers.each {|layer|  layer.dispose }
  1188.     @autotile_layers = []
  1189.     # Dispose layers
  1190.     @layers.each {|layer|  layer.dispose }
  1191.     @layers = []
  1192.   end
  1193.   #--------------------------------------------------------------------------
  1194.   # * Initialize (updates all rows of all layers)
  1195.   #--------------------------------------------------------------------------
  1196.   def refresh
  1197.     @autotile_layers.each {|layer|  layer.refresh}
  1198.     @layers.each {|layer|  layer.refresh}
  1199.   end
  1200. end
  1201.  
  1202. #==============================================================================
  1203. # ** Command_Autotile NEW
  1204. #------------------------------------------------------------------------------
  1205. #  This class saves all autotile data. Used in order to create autotiles with
  1206. #  blend-mode 1/2 after normal tile layer.
  1207. #==============================================================================
  1208.  
  1209. class Command_Autotile
  1210.   #--------------------------------------------------------------------------
  1211.   # * Public Instance Variables
  1212.   #--------------------------------------------------------------------------
  1213.   attr_reader :autotiles,:speed,:frames,:blend_type,:priority
  1214.   #--------------------------------------------------------------------------
  1215.   # * Initialize
  1216.   #--------------------------------------------------------------------------
  1217.   def initialize(autotiles,speed,frames,priority,blend_type)
  1218.     @autotiles = autotiles.clone #Autotile list
  1219.     @speed = speed               #Animation speed
  1220.     @frames = frames             #Nr. of frames
  1221.     @blend_type = blend_type     #Blend type
  1222.     @priority = priority         #Priority
  1223.   end
  1224. end
  1225.  
  1226. #==============================================================================
  1227. # ** Game_Temp EDIT
  1228. #------------------------------------------------------------------------------
  1229. #  Addon for saving the tilemap upon switching scene.
  1230. #==============================================================================
  1231.  
  1232. class Game_Temp
  1233.  
  1234.   attr_accessor :store_tilemap
  1235.   attr_accessor :tilemap
  1236.  
  1237. end
  1238.  
  1239. #==============================================================================
  1240. # ** Spriteset_Map EDIT
  1241. #------------------------------------------------------------------------------
  1242. #  Enhances the class Spriteset_Map. Creates an Tilemap new object. Overwrites
  1243. #  initialize, dispose and update methods.
  1244. #
  1245. #==============================================================================
  1246.  
  1247. class Spriteset_Map
  1248.   #--------------------------------------------------------------------------
  1249.   # * Public Instance_Variables
  1250.   #--------------------------------------------------------------------------
  1251.   attr_reader :tilemap
  1252.   attr_reader :viewport1
  1253.   if !method_defined?(:create_tilemap) || !method_defined?(:create_viewports)
  1254.     #--------------------------------------------------------------------------
  1255.     # * Object Initialization
  1256.     #--------------------------------------------------------------------------
  1257.     def initialize
  1258.       create_viewports
  1259.       create_tilemap
  1260.       create_panorama
  1261.       create_fog
  1262.       create_characters
  1263.       create_player
  1264.       create_weather
  1265.       create_pictures
  1266.       create_timer
  1267.       update
  1268.     end
  1269.     #--------------------------------------------------------------------------
  1270.     # * Panorama Initialization
  1271.     #--------------------------------------------------------------------------
  1272.     def create_panorama
  1273.       @panorama = Plane.new(@viewport1)      # Make panorama plane
  1274.       @panorama.z = -1000
  1275.     end
  1276.     #--------------------------------------------------------------------------
  1277.     # * Fog Initialization
  1278.     #--------------------------------------------------------------------------
  1279.     def create_fog
  1280.       @fog = Plane.new(@viewport1)           # Make fog plane
  1281.       @fog.z = 3000
  1282.     end
  1283.     #--------------------------------------------------------------------------
  1284.     # * Character Sprite Initialization
  1285.     #--------------------------------------------------------------------------
  1286.     def create_characters
  1287.       @character_sprites = []
  1288.       for i in $game_map.events.keys.sort    # Make character sprites
  1289.         sprite = Sprite_Character.new(@viewport1, $game_map.events[i])
  1290.         @character_sprites.push(sprite)
  1291.       end
  1292.     end
  1293.     #--------------------------------------------------------------------------
  1294.     # * Player Initialization
  1295.     #--------------------------------------------------------------------------
  1296.     def create_player
  1297.       @character_sprites.push(Sprite_Character.new(@viewport1, $game_player))
  1298.     end
  1299.     #--------------------------------------------------------------------------
  1300.     # * Weather Initialization
  1301.     #--------------------------------------------------------------------------
  1302.     def create_weather
  1303.       @weather = RPG::Weather.new(@viewport1)  # Make weather
  1304.     end
  1305.     #--------------------------------------------------------------------------
  1306.     # * Picture Initialization
  1307.     #--------------------------------------------------------------------------
  1308.     def create_pictures
  1309.       @picture_sprites = []
  1310.       for i in 1..50                           # Make picture sprites
  1311.         @picture_sprites.push(Sprite_Picture.new(@viewport2,
  1312.           $game_screen.pictures[i]))
  1313.       end
  1314.     end
  1315.     #--------------------------------------------------------------------------
  1316.     # * Timer Initialization
  1317.     #--------------------------------------------------------------------------
  1318.     def create_timer
  1319.       @timer_sprite = Sprite_Timer.new          # Make timer sprite
  1320.     end
  1321.   end
  1322.   #--------------------------------------------------------------------------
  1323.   # * Viewport Initialization
  1324.   #--------------------------------------------------------------------------
  1325.   def create_viewports
  1326.     #@viewport1 = Viewport.new(0, 0, 640, 480) # Make viewports
  1327.     @viewport2 = Viewport.new(0, 0, 640, 480)
  1328.     @viewport3 = Viewport.new(0, 0, 640, 480)
  1329.     @viewport2.z = 200
  1330.     @viewport3.z = 5000
  1331.   end
  1332.   #--------------------------------------------------------------------------
  1333.   # * Tilemap Initialization
  1334.   #--------------------------------------------------------------------------
  1335.   def create_tilemap
  1336.     if $game_temp.tilemap == nil                # Make tilemap
  1337.       @viewport1 = Viewport.new(0, 0, 640, 480) # Make Viewport1
  1338.       redraw_tilemap
  1339.     else                                        # Else: Tilemap is stored
  1340.       @tilemap = $game_temp.tilemap             # Load Tilemap & Viewport
  1341.       @viewport1 = @tilemap.viewport
  1342.       @viewport1.visible = true
  1343.       $game_temp.tilemap = nil                  # Remove tilemap from storage
  1344.     end
  1345.   end
  1346.   #--------------------------------------------------------------------------
  1347.   # * redraw_tilemap
  1348.   #--------------------------------------------------------------------------
  1349.   def redraw_tilemap
  1350.     @tilemap.dispose if @tilemap
  1351.     for i in 0..6
  1352.       autotile_name = $game_map.autotile_names[i].dup
  1353.       (autotiles ||= []) << RPG::Cache.autotile(autotile_name)
  1354.     end
  1355.     tileset = RPG::Cache.tileset($game_map.tileset_name)
  1356.     @tilemap = Tilemap_New.new(@viewport1,tileset,autotiles)
  1357.   end
  1358.   #--------------------------------------------------------------------------
  1359.   # * Dispose
  1360.   #--------------------------------------------------------------------------
  1361.   if !method_defined?(:dispose_tilemap) || !method_defined?(:dispose_viewports)
  1362.     def dispose
  1363.       dispose_tilemap
  1364.       dispose_fog
  1365.       dispose_panorama
  1366.       dispose_characters
  1367.       dispose_weather
  1368.       dispose_pictures
  1369.       dispose_timer
  1370.       dispose_viewports
  1371.     end
  1372.     #--------------------------------------------------------------------------
  1373.     # * Dispose Fog
  1374.     #--------------------------------------------------------------------------
  1375.     def dispose_fog
  1376.       @fog.dispose
  1377.     end
  1378.     #--------------------------------------------------------------------------
  1379.     # * Dispose Panorama
  1380.     #--------------------------------------------------------------------------
  1381.     def dispose_panorama
  1382.       @panorama.dispose
  1383.     end
  1384.     #--------------------------------------------------------------------------
  1385.     # * Dispose Character Sprite
  1386.     #--------------------------------------------------------------------------
  1387.     def dispose_characters
  1388.       @character_sprites.each {|sprite| sprite.dispose }
  1389.     end
  1390.     #--------------------------------------------------------------------------
  1391.     # * Dispose Weather
  1392.     #--------------------------------------------------------------------------
  1393.     def dispose_weather
  1394.       @weather.dispose
  1395.     end
  1396.     #--------------------------------------------------------------------------
  1397.     # * Dispose Picture Sprite
  1398.     #--------------------------------------------------------------------------
  1399.     def dispose_pictures
  1400.       @picture_sprites.compact.each {|sprite| sprite.dispose }
  1401.     end
  1402.     #--------------------------------------------------------------------------
  1403.     # * Dispose Timer Sprite
  1404.     #--------------------------------------------------------------------------
  1405.     def dispose_timer
  1406.       @timer_sprite.dispose
  1407.     end
  1408.   end
  1409.   #--------------------------------------------------------------------------
  1410.   # * Dispose Tilemap
  1411.   #--------------------------------------------------------------------------
  1412.   def dispose_tilemap
  1413.     @tilemap.tileset.dispose
  1414.     (0..6).each {|i| @tilemap.autotiles[i].dispose }
  1415.     if $game_temp.store_tilemap == true   # If tilemap should be stored
  1416.       $game_temp.tilemap = @tilemap.clone # Store tilemap
  1417.       $game_temp.store_tilemap = false    # Disable storage flag
  1418.       @viewport1.visible = false
  1419.     else                                  # Else
  1420.       @tilemap.dispose                    # Dispose tilemap & viewport
  1421.       @viewport1.dispose
  1422.     end
  1423.   end
  1424.   #--------------------------------------------------------------------------
  1425.   # * Dispose Viewport
  1426.   #--------------------------------------------------------------------------
  1427.   def dispose_viewports
  1428.     #@viewport1.dispose
  1429.     @viewport2.dispose
  1430.     @viewport3.dispose
  1431.   end
  1432. end
  1433.  
  1434. #==============================================================================
  1435. # ** Game_Map EDIT
  1436. #------------------------------------------------------------------------------
  1437. #  Enhances the class Game_Map in order to presort tiles by priority; used for
  1438. #  tilemap tone.
  1439. #==============================================================================
  1440. class Game_Map
  1441.   #--------------------------------------------------------------------------
  1442.   # * Public Instance Variables
  1443.   #--------------------------------------------------------------------------
  1444.   attr_writer   :zoom_x
  1445.   attr_writer   :zoom_y
  1446.   attr_reader   :map           # Map-Daten
  1447.   attr_reader   :tone          # Color-Tone
  1448.   attr_accessor :need_redraw
  1449.   #--------------------------------------------------------------------------
  1450.   # * Alias Method
  1451.   #--------------------------------------------------------------------------
  1452.   alias_method :init_later,  :initialize
  1453.   alias_method :setup_later, :setup
  1454.   alias_method :upd_later,   :update
  1455.   define_method(:zoom_x) { @zoom_x ||= 1.0 }
  1456.   define_method(:zoom_y) { @zoom_y ||= 1.0 }
  1457.   #--------------------------------------------------------------------------
  1458.   # * Initialize (variables for tilemap tone)
  1459.   #--------------------------------------------------------------------------
  1460.   def initialize
  1461.     init_later
  1462.     @tone = Tone.new(0,0,0,0)  # Tilemap-tone
  1463.     @tone_duration = 0         # Tone-duration
  1464.     @need_redraw = false
  1465.   end
  1466.   #--------------------------------------------------------------------------
  1467.   # * Setup
  1468.   #--------------------------------------------------------------------------
  1469.   def setup(map_id)
  1470.     setup_later(map_id)
  1471.     sort                       # Sort tiles after setup
  1472.   end
  1473.   #--------------------------------------------------------------------------
  1474.   # * Sort (sorts tile IDs by priority for later reading)
  1475.   #--------------------------------------------------------------------------
  1476.   def sort
  1477.     @priority0 = {}            # One hash for every priority
  1478.     @priority1 = {}
  1479.     @priority2 = {}
  1480.     @priority3 = {}
  1481.     @priority4 = {}
  1482.     @priority5 = {}
  1483.     for x in 0...width         # Iterate through tiles on x-axis
  1484.       for y in 0...height      # Iterate through tiles on y-axis
  1485.         for z in z_data        # Check layers from map editor top->bottom
  1486.           tile = data[x,y,z]   # Tile ID
  1487.           if tile != 0         # If tile is not empty
  1488.             # Get & check priority for tile, set in according hash
  1489.             case @priorities[tile]
  1490.             when 0
  1491.               @priority0[y]     ||= {}
  1492.               @priority0[y][x]  ||= {}
  1493.               @priority0[y][x][z] = tile
  1494.             when 1
  1495.               @priority1[y]     ||= {}
  1496.               @priority1[y][x]  ||= {}
  1497.               @priority1[y][x][z] = tile
  1498.             when 2
  1499.               @priority2[y]     ||= {}
  1500.               @priority2[y][x]  ||= {}
  1501.               @priority2[y][x][z] = tile
  1502.             when 3
  1503.               @priority3[y]     ||= {}
  1504.               @priority3[y][x]  ||= {}
  1505.               @priority3[y][x][z] = tile
  1506.             when 4
  1507.               @priority4[y]     ||= {}
  1508.               @priority4[y][x]  ||= {}
  1509.               @priority4[y][x][z] = tile
  1510.             when 5
  1511.               @priority5[y]     ||= {}
  1512.               @priority5[y][x]  ||= {}
  1513.               @priority5[y][x][z] = tile
  1514.             end
  1515.           end
  1516.         end
  1517.       end
  1518.     end
  1519.   end
  1520.   #--------------------------------------------------------------------------
  1521.   # * Priority-Data (returns previously sorted tiles)
  1522.   #--------------------------------------------------------------------------  
  1523.   def priority_data(priority)
  1524.     case priority       # Check priority and return appropriate sorted hash
  1525.     when 0 then return @priority0
  1526.     when 1 then return @priority1
  1527.     when 2 then return @priority2
  1528.     when 3 then return @priority3
  1529.     when 4 then return @priority4
  1530.     when 5 then return @priority5
  1531.     else
  1532.       return @priority0 # Invalid priority: return hash 0
  1533.     end
  1534.   end
  1535.   #--------------------------------------------------------------------------
  1536.   # * New Method : z_data
  1537.   #--------------------------------------------------------------------------
  1538.   unless method_defined?(:z_data)
  1539.     def z_data
  1540.       (0...data.zsize).to_a.reverse
  1541.     end
  1542.   end
  1543.   #--------------------------------------------------------------------------
  1544.   # * Start tone change (like in Game_screen, but for the tilemap!)
  1545.   #--------------------------------------------------------------------------  
  1546.   def start_tone_change(tone, duration)
  1547.     @tone_target = tone.clone
  1548.     @tone_duration = duration
  1549.     @tone = @tone_target.clone if @tone_duration == 0
  1550.   end
  1551.   #--------------------------------------------------------------------------
  1552.   # * change_tile
  1553.   #--------------------------------------------------------------------------
  1554.   def change_tile(x,y,i,new_tile)
  1555.     return if data[x,y,i] == new_tile
  1556.     data[x,y,i] = new_tile
  1557.     @need_redraw = true
  1558.   end
  1559.   #--------------------------------------------------------------------------
  1560.   # * Alias update (executes tone change)
  1561.   #--------------------------------------------------------------------------
  1562.   def update
  1563.     if @tone_duration && @tone_duration >= 1
  1564.       d = @tone_duration
  1565.       @tone.red = (@tone.red * (d - 1) + @tone_target.red) / d
  1566.       @tone.green = (@tone.green * (d - 1) + @tone_target.green) / d
  1567.       @tone.blue = (@tone.blue * (d - 1) + @tone_target.blue) / d
  1568.       @tone.gray = (@tone.gray * (d - 1) + @tone_target.gray) / d
  1569.       @tone_duration -= 1
  1570.     end
  1571.     upd_later
  1572.     if @need_redraw && $scene.is_a?(Scene_Map)
  1573.       sort
  1574.       $scene.redraw_tilemap
  1575.       @need_redraw = false
  1576.     end
  1577.   end
  1578. end
  1579. #==============================================================================
  1580. # ** Scene_Map EDIT
  1581. #------------------------------------------------------------------------------
  1582. #  Overwrites the main method in order to save the spriteset when changing
  1583. #  scene.
  1584. #==============================================================================
  1585. class Scene_Map
  1586.   #--------------------------------------------------------------------------
  1587.   # * Constant
  1588.   #--------------------------------------------------------------------------
  1589.   @@sdk_main_dispose = method_defined?(:main_dispose)
  1590.   #--------------------------------------------------------------------------
  1591.   # * Main overwrite (sets the store-tileset-flag in case of scene change)
  1592.   #--------------------------------------------------------------------------
  1593.   alias kings_tilemap_main main
  1594.   def main
  1595.     return kings_tilemap_main if @@sdk_main_dispose
  1596.     @spriteset      = Spriteset_Map.new
  1597.     @message_window = Window_Message.new
  1598.     Graphics.transition
  1599.     [Graphics,Input,self].each {|s| s.update } while $scene == self
  1600.     Graphics.freeze
  1601.     $game_temp.store_tilemap = true  # Set store tilemap flag to true
  1602.     @spriteset.dispose
  1603.     @message_window.dispose
  1604.     if $scene.is_a?(Scene_Title)
  1605.       Graphics.transition
  1606.       Graphics.freeze
  1607.     end
  1608.   end
  1609.   #--------------------------------------------------------------------------
  1610.   # * main_dispose (if main_dispose exist)
  1611.   #--------------------------------------------------------------------------
  1612.   if @@sdk_main_dispose
  1613.     alias kings_tilemap_main_dispose main_dispose
  1614.     def main_dispose
  1615.       $game_temp.store_tilemap = true
  1616.       kings_tilemap_main_dispose
  1617.     end
  1618.   end
  1619.   #--------------------------------------------------------------------------
  1620.   # * Alias transfer_player (required for flawless teleport to the current map)
  1621.   #--------------------------------------------------------------------------
  1622.   alias transfer_later transfer_player
  1623.   def transfer_player
  1624.     # If old and new_map are the same
  1625.     if $game_map.map_id == $game_temp.player_new_map_id
  1626.       $game_temp.store_tilemap = true # Set store tilemap flag
  1627.     end
  1628.     transfer_later
  1629.     @spriteset.tilemap.refresh        # Refresh tilemap
  1630.   end
  1631.   #--------------------------------------------------------------------------
  1632.   # * redraw_tilemap
  1633.   #--------------------------------------------------------------------------
  1634.   def redraw_tilemap
  1635.     @spriteset.redraw_tilemap
  1636.   end
  1637. end
  1638.  
  1639. #==============================================================================
  1640. # ** Graphics
  1641. #------------------------------------------------------------------------------
  1642. #  This module handles all Graphics
  1643. #==============================================================================
  1644. module Graphics
  1645.   #--------------------------------------------------------------------------
  1646.   # ● class << self
  1647.   #--------------------------------------------------------------------------
  1648.   class << self
  1649.     #--------------------------------------------------------------------------
  1650.     # ● Alias Method
  1651.     #--------------------------------------------------------------------------
  1652.     unless self.method_defined?(:atilemap_update)
  1653.       alias_method(:atilemap_update, :update)
  1654.       #-------------------------------------------------------------------------
  1655.       # ● Update
  1656.       #-------------------------------------------------------------------------
  1657.       def update
  1658.         atilemap_update
  1659.         scene = $scene
  1660.         return if scene.nil? || scene.is_a?(Scene_Map)
  1661.         spriteset = scene.instance_variables.any? {|var|
  1662.                     scene.instance_variable_get(var).is_a?(Spriteset_Map)}
  1663.         $game_temp.instance_variable_set(:@store_tilemap,true) if spriteset
  1664.       end
  1665.     end
  1666.   end
  1667. end
  1668. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement