Advertisement
TmanDaCool1

HM7 NEW CLASSES

Jul 30th, 2018
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 54.12 KB | None | 0 0
  1. #============================================================================
  2. # H-Mode7 Engine
  3. # V.1.4.4 - 26/01/2012
  4. # Author : MGC (MGCaladtogel)
  5. # Heightmaps cache by DerVVulman
  6. #
  7. # New classes
  8. #============================================================================
  9.  
  10. #==============================================================================
  11. # ** RPG
  12. #------------------------------------------------------------------------------
  13. #  A module containing RPGXP's data structures and more.
  14. #==============================================================================
  15. module RPG
  16.   #============================================================================
  17.   # ** Cache
  18.   #----------------------------------------------------------------------------
  19.   #  A module that loads each of RPGXP's graphic formats, creates a Bitmap
  20.   #  object, and retains it.
  21.   #============================================================================
  22.   module Cache
  23.     #------------------------------------------------------------------------
  24.     # * Obtains a heightmap graphic
  25.     # V.1.2 : heightmaps cache
  26.     #------------------------------------------------------------------------
  27.     def self.heightmap(filename)
  28.       self.load_bitmap("Graphics/Heightmap/", filename)
  29.     end
  30.   end
  31. end
  32.  
  33. #==============================================================================
  34. # ** HM7
  35. #------------------------------------------------------------------------------
  36. #  DLL calls to load C functions into memory
  37. #==============================================================================
  38. module HM7
  39.   Draw_Map_Tileset = Win32API.new("MGC_Hmode7", "drawMapTileset", "llllll", "l")
  40.   Draw_Textureset = Win32API.new("MGC_Hmode7", "drawTextureset", "lll", "l")
  41.   Draw_Heightmap = Win32API.new("MGC_Hmode7", "drawHeightmap", "lllll", "l")
  42.   Apply_Lighting = Win32API.new("MGC_Hmode7", "applyLighting", "l", "l")
  43.   Compute_M7 = Win32API.new("MGC_Hmode7", "computeM7", "lll", "l")
  44.   Render_HM7 = Win32API.new("MGC_Hmode7", "renderHM7", "llll", "l")
  45.   Refresh_Map_Tileset = Win32API.new("MGC_Hmode7", "refreshMapTileset", "lllll", "l")
  46.   # V.1.2 : events translucidity & blend type
  47.   Apply_Opacity = Win32API.new("MGC_Hmode7", "applyOpacity", "ll", "l")
  48.   # V.1.3
  49.   Apply_Zoom = Win32API.new("MGC_Hmode7", "applyZoom", "lll", "l")
  50.   #--------------------------------------------------------------------------
  51.   # * Draw the specific tileset for the map
  52.   # V.1.4 : n-layers
  53.   #--------------------------------------------------------------------------
  54.   def self.draw_map_tileset(map_tileset, tileset, heightset, tilemap_hash,
  55.     auto_tilesets, nb_layers)
  56.     Draw_Map_Tileset.call(map_tileset.__id__, tileset.__id__, heightset.__id__,
  57.     tilemap_hash.__id__, auto_tilesets.__id__, nb_layers)
  58.   end
  59.   #--------------------------------------------------------------------------
  60.   # * Draw the specific textureset for the map
  61.   #--------------------------------------------------------------------------
  62.   def self.draw_textureset(textures, colormap, texture_auto)
  63.     Draw_Textureset.call(textures.__id__, colormap.__id__, texture_auto.__id__)
  64.   end
  65.   #--------------------------------------------------------------------------
  66.   # * Draw the complete heightmap
  67.   # V.1.4 : n-layers
  68.   #--------------------------------------------------------------------------
  69.   def self.draw_heightmap(heightmap, heightpattern, map_tileset, tilemap_data,
  70.     nb_layers)
  71.     Draw_Heightmap.call(heightmap.__id__, heightpattern.__id__,
  72.     map_tileset.__id__, tilemap_data.__id__, nb_layers)
  73.   end
  74.   #--------------------------------------------------------------------------
  75.   # * Apply the lighting effects on the map
  76.   #--------------------------------------------------------------------------
  77.   def self.apply_lighting(heightmap)
  78.     Apply_Lighting.call(heightmap.__id__)
  79.   end
  80.   #--------------------------------------------------------------------------
  81.   # * Calculate a basic mode7 rendering
  82.   #--------------------------------------------------------------------------
  83.   def self.compute_m7(datatable, lightline, params)
  84.     Compute_M7.call(datatable.__id__, lightline.__id__, params.__id__)
  85.   end
  86.   #--------------------------------------------------------------------------
  87.   # * H-Mode7 rendering
  88.   # V.1.4 : n-layers
  89.   #--------------------------------------------------------------------------
  90.   def self.render_hm7(params, vars, surfaces, nb_layers)
  91.     return Render_HM7.call(params.__id__, vars.__id__, surfaces.__id__, nb_layers)
  92.   end
  93.   #--------------------------------------------------------------------------
  94.   # * Refresh the specific tileset for the map for animated autotiles
  95.   # V.1.4 : n-layers
  96.   #--------------------------------------------------------------------------
  97.   def self.refresh_map_tileset(map_tileset, tileset, tilemap_hash, auto_tilesets,
  98.     nb_layers)
  99.     Refresh_Map_Tileset.call(map_tileset.__id__, tileset.__id__,
  100.     tilemap_hash.__id__, auto_tilesets.__id__, nb_layers)
  101.   end
  102.   #--------------------------------------------------------------------------
  103.   # * Alter a bitmap by applying an opacity value
  104.   # V.1.2 : events translucidity & blend type
  105.   #--------------------------------------------------------------------------
  106.   def self.apply_opacity(bitmap, opacity)
  107.     Apply_Opacity.call(bitmap.__id__, opacity)
  108.   end
  109.   #--------------------------------------------------------------------------
  110.   # * V.1.3 : Apply an zoom value
  111.   #--------------------------------------------------------------------------
  112.   def self.apply_zoom(bitmap, source, lissage)
  113.     Apply_Zoom.call(bitmap.__id__, source.__id__, lissage)
  114.   end
  115. end
  116.  
  117. #============================================================================
  118. # ** HM7::Bitmap_Autotiles
  119. #============================================================================
  120. module HM7
  121.   class Bitmap_Autotiles < Bitmap
  122.     # data list to form tiles from an autotiles file
  123.     Data_Patterns = [[27,28,33,34],[5,28,33,34],[27,6,33,34],[5,6,33,34],
  124.     [27,28,33,12],[5,28,33,12],[27,6,33,12],[5,6,33,12],[27,28,11,34],
  125.     [5,28,11,34],[27,6,11,34],[5,6,11,34],[27,28,11,12],[5,28,11,12],
  126.     [27,6,11,12],[5,6,11,12],[25,26,31,32],[25,6,31,32],[25,26,31,12],
  127.     [25,6,31,12],[15,16,21,22],[15,16,21,12],[15,16,11,22],[15,16,11,12],
  128.     [29,30,35,36],[29,30,11,36],[5,30,35,36],[5,30,11,36],[39,40,45,46],
  129.     [5,40,45,46],[39,6,45,46],[5,6,45,46],[25,30,31,36],[15,16,45,46],
  130.     [13,14,19,20],[13,14,19,12],[17,18,23,24],[17,18,11,24],[41,42,47,48],
  131.     [5,42,47,48],[37,38,43,44],[37,6,43,44],[13,18,19,24],[13,14,43,44],
  132.     [37,42,43,48],[17,18,47,48],[13,18,43,48],[13,18,43,48]]
  133.     #--------------------------------------------------------------------------
  134.     # * Attributes
  135.     #--------------------------------------------------------------------------
  136.     attr_accessor :number # autotile's number to identify it
  137.     attr_accessor :animated # TRUE if the autotile is animated
  138.     #--------------------------------------------------------------------------
  139.     # * Initialize Object
  140.     #     file : autotiles file's bitmap (Bitmap)
  141.     #     l : pattern's number for animated autotiles
  142.     #--------------------------------------------------------------------------
  143.     def initialize(file, l)
  144.       super(256, 192)
  145.       create(file, l)
  146.     end
  147.     #--------------------------------------------------------------------------
  148.     # * Create the tiles set
  149.     #     file : autotiles file's bitmap (Bitmap)
  150.     #     l : pattern's number for animated autotiles
  151.     #--------------------------------------------------------------------------
  152.     def create(file, l)
  153.       l = (file.width > 96 ? l : 0)
  154.       self.animated = (file.width > 96)
  155.       for i in 0..5
  156.         for j in 0..7
  157.           data = Data_Patterns[(i << 3) + j]
  158.           for number in data
  159.             number -= 1
  160.             m = number % 6 << 4
  161.             n = number / 6 << 4
  162.             blt((j << 5) + m % 32, (i << 5) + n % 32, file,
  163.             Rect.new(m + 96 * l, n, 16, 16))
  164.           end
  165.         end
  166.       end
  167.     end
  168.   end
  169. end
  170.  
  171. #============================================================================
  172. # ** HM7::Autotile
  173. #============================================================================
  174. module HM7
  175.   class Autotile
  176.     #--------------------------------------------------------------------------
  177.     # * Attributes
  178.     #--------------------------------------------------------------------------
  179.     attr_accessor :autotile_id
  180.     attr_accessor :animated
  181.     attr_accessor :animations_number
  182.     attr_accessor :graphics
  183.     attr_accessor :animation_index
  184.     #--------------------------------------------------------------------------
  185.     # * Initialize Object
  186.     #--------------------------------------------------------------------------
  187.     def initialize(autotile_id, autotile_name)
  188.       self.autotile_id = autotile_id
  189.       bmp_file = RPG::Cache.autotile(autotile_name)
  190.       self.animations_number = bmp_file.width / 96
  191.       self.animated = (animations_number > 1)
  192.       self.graphics = []
  193.       for pattern_iterator in 0...animations_number
  194.         data_autotile = HM7::Bitmap_Autotiles.new(bmp_file, pattern_iterator)
  195.         data_autotile.number = pattern_iterator * 10 + autotile_id
  196.         graphics.push(data_autotile)
  197.       end
  198.       self.animation_index = 0
  199.     end
  200.     #--------------------------------------------------------------------------
  201.     # * Get current graphics
  202.     #--------------------------------------------------------------------------
  203.     def get_current_graphics
  204.       return graphics[animation_index]
  205.     end
  206.     #--------------------------------------------------------------------------
  207.     # * Animate - next pattern
  208.     #--------------------------------------------------------------------------
  209.     def animate
  210.       self.animation_index = animation_index.succ % animations_number
  211.     end
  212.   end
  213. end
  214.  
  215. #============================================================================
  216. # ** HM7::Surface
  217. # V.1.3 : modifications to handle wall events
  218. #============================================================================
  219. module HM7
  220.   class Surface
  221.     attr_accessor :type, :bitmap, :bitmap_set, :screen_x, :screen_y, :character,
  222.     :visible, :opacity, :blend_type, :displayed, :altitude
  223.     attr_reader :x1, :y1, :x2, :y2, :screen_x1, :screen_y1,
  224.     :screen_x2, :screen_y2, :inverse
  225.     #--------------------------------------------------------------------------
  226.     # * Technical constant to handle relative reference of frame
  227.     #--------------------------------------------------------------------------
  228.     Left = [6, 2, 8, 4]
  229.     #--------------------------------------------------------------------------
  230.     # * Object Initialization
  231.     #     character (Game_Character) : character to display
  232.     #     tilemap (HM7::Tilemap)
  233.     #--------------------------------------------------------------------------
  234.     def initialize(character, tilemap, viewport)
  235.       @viewport = viewport
  236.       self.character = character
  237.       @tilemap = tilemap
  238.       self.type = character.type
  239.       @need_refresh = false
  240.       @sx_old = nil
  241.       @sy_old = nil
  242.       @visible_old = nil
  243.       @opacity_old = nil
  244.       @blend_type_old = nil
  245.       @screen_x_old = nil
  246.       @screen_y_old = nil
  247.       @altitude_old = nil
  248.       update
  249.     end
  250.     #--------------------------------------------------------------------------
  251.     # * Frame Update
  252.     #--------------------------------------------------------------------------
  253.     def update
  254.       if character.character_name == ""
  255.         self.displayed = false
  256.         return
  257.       end
  258.       # If tile ID, file name, or hue are different from current ones
  259.       if @tile_id != character.tile_id or
  260.          @character_name != character.character_name or
  261.          @character_hue != character.character_hue
  262.         # Remember tile ID, file name, and hue
  263.         @tile_id = character.tile_id
  264.         @character_name = character.character_name
  265.         @character_hue = character.character_hue
  266.         # If tile ID value is valid
  267.         if @tile_id >= 384
  268.           @offset_height = 0
  269.           self.bitmap_set = RPG::Cache.tile($game_map.tileset_name,
  270.           @tile_id, character.character_hue)
  271.           @sx = 0
  272.           @sy = 0
  273.           @cw = 32
  274.           @ch = 32
  275.         # If tile ID value is invalid
  276.         else
  277.           # V.1.3 : OV
  278.           unless bitmap_set.nil?
  279.             bitmap_set.dispose
  280.           end
  281.           @offset_height = 2
  282.           self.bitmap_set = RPG::Cache.character(character.character_name,
  283.           character.character_hue)
  284.           # V.1.3 : OV
  285.           if $game_system.hm7_ov && character.ov
  286.             ov_bmp = Bitmap.new(bitmap_set.width * HM7::OV_ZOOM,
  287.             bitmap_set.height * HM7::OV_ZOOM)
  288.             HM7.apply_zoom(ov_bmp, bitmap_set, 1)
  289.             self.bitmap_set = ov_bmp
  290.           end
  291.           @cw = bitmap_set.width >> 2
  292.           # V.1.1 : 8-directions graphics
  293.           @ch = bitmap_set.height / character.directions
  294.         end
  295.         self.bitmap = Bitmap.new(@cw, @ch - @offset_height)
  296.         @need_refresh = true
  297.       end
  298.       # Set visible situation
  299.       self.visible = (not character.transparent)
  300.       # If graphic is character
  301.       if @tile_id == 0
  302.         # Set rectangular transfer
  303.         @sx = character.pattern * @cw
  304.         unless character.instance_variable_get(:@direction_fix)
  305.           # V.1.1 : 8-directions graphics
  306.           current_direction = (@character.direction - 2) / 2
  307.           directions_list = HM7::Dirs[character.directions]
  308.           list_size = directions_list.size
  309.           current_direction = directions_list[(directions_list.index(current_direction) +
  310.           (($game_system.hm7_theta + (180 / list_size)) % 360) / (360 / list_size)) % list_size]
  311.           @sy = current_direction * @ch
  312.         else
  313.           @sy = ((character.direction >> 1) - 1) * @ch
  314.         end
  315.       end
  316.       if @need_refresh || @sx_old != @sx || @sy_old != @sy
  317.         bitmap.clear
  318.         bitmap.blt(0, 0, bitmap_set, Rect.new(@sx, @sy, @cw, @ch - @offset_height))
  319.         # V.1.2 : events translucidity & blend type
  320.         HM7.apply_opacity(bitmap, character.opacity)
  321.       end
  322.       # Set sprite coordinates
  323.       update_coordinates
  324.       # Set sprite altitude
  325.       update_altitude
  326.       # Set opacity level, blend method
  327.       self.opacity = character.opacity
  328.       self.blend_type = character.blend_type
  329.       # Force rendering if condition changed
  330.       if @need_refresh || @screen_x_old != screen_x1 || @screen_y_old != screen_y1 ||
  331.         @sx_old != @sx || @sy_old != @sy ||
  332.         @visible_old != visible || @opacity_old != opacity ||
  333.         @blend_type_old != blend_type || @altitude_old != altitude
  334.       then
  335.         @tilemap.need_update_surfaces = true
  336.         @screen_x_old = screen_x1
  337.         @screen_y_old = screen_y1
  338.         @sx_old = @sx
  339.         @sy_old = @sy
  340.         @visible_old = visible
  341.         @opacity_old = opacity
  342.         @blend_type_old = blend_type
  343.         @altitude_old = altitude
  344.         @need_refresh = false
  345.       end
  346.       # V.1.1 : map animations
  347.       if character.animation_id != 0
  348.         @tilemap.spriteset.play_animation(@character.animation_id, screen_x, screen_y, get_zoom)
  349.         character.animation_id = 0
  350.       end
  351.     end
  352.     #--------------------------------------------------------------------------
  353.     # * Dispose
  354.     #--------------------------------------------------------------------------
  355.     def dispose
  356.       unless bitmap.nil? then bitmap.dispose end
  357.       unless bitmap_set.nil? then bitmap_set.dispose end
  358.     end
  359.     #--------------------------------------------------------------------------
  360.     # * Get data to render the surface
  361.     #--------------------------------------------------------------------------
  362.     def get_data
  363.       # V.1.2 : events translucidity & blend type
  364.       return [type, screen_x1, screen_y1, screen_x2, screen_y2, inverse,
  365.       bitmap, altitude, blend_type, @d_width, @d_offset]
  366.     end
  367.     #--------------------------------------------------------------------------
  368.     # * Calculate initial coordinates
  369.     #--------------------------------------------------------------------------
  370.     def update_coordinates
  371.       x0 = character.screen_x + character.pos_x - 16
  372.       y0 = character.screen_y + character.pos_y - 32
  373.       if character.type == 0
  374.         dx = @cw * character.cos_angle >> 13
  375.         dy = @cw * character.sin_angle >> 13
  376.       else
  377.         dx = 0
  378.         dy = 0
  379.       end
  380.       @x1 = x0 - dx
  381.       @y1 = y0 + dy
  382.       @x2 = x0 + dx
  383.       @y2 = y0 - dy
  384.       update_screen_coordinates
  385.     end
  386.     #--------------------------------------------------------------------------
  387.     # * Calculate x and y coordinates in the screen for a HM7 rendering
  388.     #--------------------------------------------------------------------------
  389.     def update_screen_coordinates
  390.       @d_width = bitmap.width
  391.       @d_offset = 0
  392.       screen_coords1 = calculate_screen_coordinates(x1, y1)
  393.       if screen_coords1.nil? ||
  394.         (screen_coords1[0].abs >> 12) != 0 ||
  395.         (screen_coords1[1].abs >> 12) != 0
  396.       then
  397.         self.displayed = false
  398.         return
  399.       end
  400.       if character.type == 0
  401.         screen_coords2 = calculate_screen_coordinates(x2, y2)
  402.         if screen_coords2.nil? ||
  403.           (screen_coords2[0].abs >> 12) != 0 ||
  404.           (screen_coords2[1].abs >> 12) != 0
  405.         then
  406.           self.displayed = false
  407.           return
  408.         end
  409.       else
  410.         halfwidth = (get_zoom(screen_coords1[1]) * @cw).to_i >> 1
  411.         screen_coords2 = [screen_coords1[0] + halfwidth, screen_coords1[1]]
  412.         screen_coords1[0] -= halfwidth
  413.       end
  414.       @inverse = 0
  415.       if screen_coords2[1] > screen_coords1[1]
  416.         @inverse = 1 - inverse
  417.         @screen_y1 = screen_coords2[1]
  418.         @screen_y2 = screen_coords1[1]
  419.       else
  420.         @screen_y1 = screen_coords1[1]
  421.         @screen_y2 = screen_coords2[1]
  422.       end
  423.       if screen_coords1[0] > screen_coords2[0]
  424.         @inverse = 1 - inverse
  425.         @screen_x1 = screen_coords2[0]
  426.         @screen_x2 = screen_coords1[0]
  427.       else
  428.         @screen_x1 = screen_coords1[0]
  429.         @screen_x2 = screen_coords2[0]
  430.       end
  431.       if @screen_y1 == @screen_y2
  432.         @inverse = 0
  433.       end
  434.       if @screen_x2 < @tilemap.display_x_min || @screen_x1 >= @tilemap.display_x_max ||
  435.         @screen_y1 < @tilemap.display_y_min ||
  436.         @screen_y2 >= @tilemap.display_y_max + get_zoom(@screen_y2) * (character.get_altitude + @ch) # V.1.4.1
  437.       then
  438.         self.displayed = false
  439.       else
  440.         self.displayed = true
  441.       end
  442.     end
  443.     #--------------------------------------------------------------------------
  444.     # calculate x and y coordinates in mode 7 for a character sprite
  445.     #--------------------------------------------------------------------------
  446.     def calculate_screen_coordinates(xs, ys)
  447.       y_init = $game_temp.zoom_sprites * (ys - $game_temp.pivot)
  448.       x_init = $game_temp.zoom_sprites * (xs - 320)
  449.       y_intermediate = (y_init * $game_temp.cos_theta -
  450.       x_init * $game_temp.sin_theta).to_i >> 11
  451.       x_intermediate = (x_init * $game_temp.cos_theta +
  452.       y_init * $game_temp.sin_theta).to_i >> 11
  453.       scr_y = $game_temp.pivot + ($game_temp.distance_h * y_intermediate *
  454.       $game_temp.cos_alpha) / (($game_temp.distance_h << 11) - y_intermediate *
  455.       $game_temp.sin_alpha)
  456.       yc = @tilemap.render.height - 1 -
  457.       (scr_y / @tilemap.coeff_resolution).to_i
  458.       xc = ((320 + ($game_temp.slope_value * scr_y +
  459.       $game_temp.corrective_value) * x_intermediate) /
  460.       @tilemap.coeff_resolution).to_i
  461.       self.displayed = true
  462.       return [xc, @tilemap.render.height - 1 - yc]
  463.     end
  464.     #--------------------------------------------------------------------------
  465.     # calculate x and y coordinates in mode 7 for a character sprite
  466.     #--------------------------------------------------------------------------
  467.     def update_altitude
  468.       # V.1.1 : integer values for better compatibility
  469.       xx = ((character.real_x.to_i >> 2) + 16) % ($game_map.width << 5)
  470.       yy = ((character.real_y.to_i >> 2) + 16) % ($game_map.height << 5)
  471.       # V.1.1 : replaced $game_map.width << 4 by $game_map.width << 5
  472.       if yy & 1 == 1 then xx += ($game_map.width << 5) end
  473.       yy = ($game_map.height << 5) + (yy >> 1)
  474.       # V.1.1 : jump command
  475.       self.altitude = character.get_altitude + (character.floating ? 0 : @tilemap.heightmap[xx, yy])
  476.     end
  477.     #--------------------------------------------------------------------------
  478.     # * Get zoom
  479.     # V.1.1 : map animations
  480.     #--------------------------------------------------------------------------
  481.     def get_zoom(scr_y = screen_y)
  482.       if scr_y >= @tilemap.display_y_max # V.1.4.1
  483.         return @tilemap.zoom_min + @tilemap.zoom_slope * (scr_y - @tilemap.y_min)
  484.       else
  485.         color = @tilemap.rowsdata.get_pixel(scr_y, 1)
  486.         return ((color.red.to_i << 8) + color.alpha).to_f / 4096
  487.       end
  488.     end
  489.   end
  490. end
  491.  
  492. #============================================================================
  493. # ** HM7::Tilemap
  494. #----------------------------------------------------------------------------
  495. # This new Tilemap class handles the drawing of a HM7 map
  496. #============================================================================
  497. module HM7
  498.   class Tilemap
  499.     #--------------------------------------------------------------------------
  500.     # * Attributes
  501.     #--------------------------------------------------------------------------
  502.     attr_reader :spriteset # spriteset that called this class
  503.     attr_accessor :sprite # sprite used to contain the map's drawing
  504.     attr_accessor :alpha # angle of slant
  505.     attr_accessor :theta # angle of rotation
  506.     attr_writer :need_update_surfaces
  507.     attr_reader :heightmap
  508.     attr_reader :coeff_resolution
  509.     attr_reader :render
  510.     attr_reader :rowsdata # V.1.1 : map animations
  511.     attr_reader :display_x_min, :display_x_max # V.1.3
  512.     attr_reader :display_y_min, :display_y_max # V.1.3
  513.     attr_reader :y_min, :zoom_min, :zoom_slope # V.1.4.1
  514.     #--------------------------------------------------------------------------
  515.     # * Object Initialization
  516.     #     viewport  : viewport
  517.     #--------------------------------------------------------------------------
  518.     def initialize(viewport, spriteset)
  519.       @viewport = viewport
  520.       @spriteset = spriteset
  521.       @id = $game_map.map_id
  522.       @height = $game_map.height << 5 # @height : map's height (in pixel)
  523.       @width = $game_map.width << 5 # @width : map's width (in pixel)
  524.       @zoom = $game_system.hm7_zoom # zoom level of the map
  525.       $game_temp.zoom_sprites = @zoom.to_f / 100
  526.       $game_temp.zoom_map = (4096 * (1.0 / $game_temp.zoom_sprites)).to_i
  527.      
  528.       # angle of rotation (theta)
  529.       self.theta = $game_system.hm7_theta
  530.       theta_rad = (Math::PI * theta) / 180
  531.       # easier to work with integer value than floats ('>>' and '<<' operations)
  532.       $game_temp.cos_theta = (2048 * Math.cos(theta_rad)).to_i
  533.       $game_temp.sin_theta = (2048 * Math.sin(theta_rad)).to_i
  534.      
  535.       $game_temp.distance_h = 480 # distance between the center of the map (halfwidth, pivot) and the point of view
  536.       # screenline's number of the slant's pivot = y-coordinate of the rotation center
  537.       $game_temp.pivot = $game_system.hm7_pivot # character sprites
  538.       $game_temp.pivot_map = $game_temp.pivot /
  539.       ($game_system.hm7_resolution == 1 ? 1 :
  540.       ($game_system.hm7_resolution == 2 ? 1.33 : 2)) # map sprite
  541.       # distance between the center of the map (halfwidth, pivot) and the projection plane surface
  542.       $game_temp.distance_p = $game_temp.distance_h - $game_temp.distance_h /
  543.       ($game_system.hm7_resolution == 1 ? 1 :
  544.       ($game_system.hm7_resolution == 2 ? 1.334 :  2))
  545.       # zoom value of the map sprite
  546.       @coeff_resolution = ($game_system.hm7_resolution == 1 ? 1 :
  547.       ($game_system.hm7_resolution == 2 ? 1.334 : 2))
  548.       # x-offset for the 3 resolutions
  549.       @offset_x_res = ($game_system.hm7_resolution == 1 ? 0 :
  550.       ($game_system.hm7_resolution == 2 ? 40 : 80))
  551.       # y-offset for the 3 resolutions
  552.       @offset_y_res = ($game_temp.pivot - $game_temp.pivot_map).to_i >> 1
  553.       @index_animated = 0 # 0..3 : index of animated tiles pattern
  554.      
  555.       # map sprite
  556.       self.sprite = Sprite.new(@viewport)
  557.       sprite.x = HM7::X - (640 - HM7::WIDTH >> 1)
  558.       sprite.y = HM7::Y - (480 - HM7::HEIGHT >> 1)
  559.       sprite.z = -99999
  560.       if $game_system.hm7_resolution != 1
  561.         @render = ($game_system.hm7_resolution == 2 ?
  562.         Bitmap.new(480, 360) : Bitmap.new(320, 240))
  563.       else
  564.         @render = Bitmap.new(640, 480)
  565.       end
  566.       sprite.zoom_x = @coeff_resolution
  567.       sprite.zoom_y = @coeff_resolution
  568.       sprite.bitmap = @render
  569.       if $game_system.hm7_less_cut # V.1.2.1
  570.         @computetable = Table.new(@render.width, @render.height << 1, 2)
  571.         @rowsdata = Bitmap.new(@render.height << 1, 3)
  572.       else
  573.         @computetable = Table.new(@render.width, @render.height, 2)
  574.         @rowsdata = Bitmap.new(@render.width, 3)
  575.       end
  576.       # V.1.3
  577.       d_width = (HM7::WIDTH / @coeff_resolution).to_i
  578.       d_height = (HM7::HEIGHT / @coeff_resolution).to_i
  579.       @display_x_min = @render.width - d_width >> 1
  580.       @display_x_max = display_x_min + d_width
  581.       @display_y_min = @render.height - d_height >> 1
  582.       @display_y_max = display_y_min + d_height
  583.      
  584.       if HM7::Cache.in_cache?(@id)
  585.         # load the data in the Cache
  586.         array = HM7::Cache.load(@id)
  587.         @heightmap = array[0]
  588.         @map_tileset = array[1]
  589.         @tiletable = array[2]
  590.         @textureset = array[3]
  591.         @autotiles = array[4]
  592.         @tilemap_hash_animated = array[5]
  593.         # V.1.3
  594.         @animated_textures = array[6]
  595.         @animated_tiles = array[7]
  596.         @texture_auto = HM7::Bitmap_Autotiles.new(RPG::Cache.autotile("Textures/Texture_Auto"), 0)
  597.         # V.1.4.2
  598.         @nb_layers = array[8]
  599.       else
  600.         HM7::Cache.clear
  601.         # create specific tilesets for the map
  602.         initialize_map_data
  603.         # load the ground heightmap
  604.         if $game_system.hm7_heightmap == ""
  605.           heightpattern = Bitmap.new(32, 32)
  606.         else
  607.           # V.1.2 : heightmaps cache
  608.           heightpattern = RPG::Cache.heightmap($game_system.hm7_heightmap)
  609.         end
  610.         # create the complete heightmap : HUGE OBJECT IN MEMORY !!!
  611.         @heightmap = Table.new(@width << 1, @height + (@height >> 1))
  612.         HM7.draw_heightmap(@heightmap, heightpattern,
  613.         @map_tileset, @tiletable, @nb_layers) # V.1.4 : n-layers
  614.         heightpattern.dispose
  615.         # generate lighting effects
  616.         if $game_system.hm7_lighting
  617.           HM7.apply_lighting(@heightmap)
  618.         end
  619.         # save the data in the Cache
  620.         # V.1.3
  621.         HM7::Cache.save(@id, [@heightmap, @map_tileset, @tiletable,
  622.         @textureset, @autotiles, @tilemap_hash_animated,
  623.         @animated_textures, @animated_tiles, @nb_layers]) # V.1.4.2
  624.       end
  625.      
  626.       # angle of slant (alpha)
  627.       self.alpha = $game_system.hm7_alpha
  628.      
  629.       # V.1.2 : events translucidity & blend type
  630.       @params = [@render, @computetable, @rowsdata, @heightmap,
  631.       @map_tileset, @tiletable, @textureset, $game_system.hm7_loop_x,
  632.       $game_system.hm7_loop_y, $game_system.hm7_camera_mode,
  633.       Bitmap.new(@render.width << 1, @render.height), $game_system.hm7_less_cut,
  634.       $game_system.hm7_no_black_cut, @display_x_min, @display_x_max,
  635.       @display_y_min, @display_y_max] # V.1.2.1, V.1.3
  636.       @vars = [0, 0, 0, 0, $game_temp.camera_altitude] # V.1.4.2
  637.       @parameters = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] # V.1.3
  638.       refresh_alpha
  639.      
  640.       # initialize surfaces
  641.       @surfaces = []
  642.       for i in $game_map.events.keys.sort
  643.         surface = HM7::Surface.new($game_map.events[i], self, @viewport)
  644.         @surfaces.push(surface)
  645.       end
  646.       # V.1.4.2
  647.       @surface_player = HM7::Surface.new($game_player, self, @viewport)
  648.       @surfaces.push(@surface_player)
  649.       @render_surfaces = []
  650.       self.need_update_surfaces = true
  651.       update_surfaces
  652.     end
  653.     #--------------------------------------------------------------------------
  654.     # * Refresh all the parameters dependent on the angle of slant
  655.     #--------------------------------------------------------------------------
  656.     def refresh_alpha
  657.       # angle of slant
  658.       alpha_rad = (Math::PI * alpha) / 180
  659.       $game_temp.cos_alpha = (2048 * Math.cos(alpha_rad)).to_i
  660.       $game_temp.sin_alpha = (2048 * Math.sin(alpha_rad)).to_i
  661.       $game_system.hm7_alpha = alpha
  662.       $game_system.hm7_pivot = $game_temp.pivot
  663.       # h0,  z0 : intermediate values used to calculate the slope
  664.       h0 = (- ($game_temp.distance_h) * $game_temp.pivot *
  665.       $game_temp.cos_alpha) / (($game_temp.distance_h << 11) +
  666.       $game_temp.pivot * $game_temp.sin_alpha) + $game_temp.pivot
  667.       z0 = ($game_temp.distance_h << 11).to_f /
  668.       (($game_temp.distance_h << 11) + $game_temp.pivot * $game_temp.sin_alpha)
  669.       # slope
  670.       $game_temp.slope_value = (1.0 - z0) / ($game_temp.pivot - h0)
  671.       $game_temp.slope_value_map = (131072 * $game_temp.slope_value).to_i
  672.       $game_temp.corrective_value = 1.0 - $game_temp.pivot * $game_temp.slope_value
  673.       $game_temp.corrective_value_map = (131072 * $game_temp.corrective_value / @coeff_resolution).to_i
  674.       last_line = - $game_temp.pivot_map - $game_system.hm7_horizon
  675.       old_limit = $game_temp.hm7_height_limit
  676.       $game_temp.hm7_height_limit = (($game_temp.distance_h - $game_temp.distance_p) *
  677.       last_line * $game_temp.cos_alpha) / (($game_temp.distance_h << 11) -
  678.       last_line * $game_temp.sin_alpha) + $game_temp.pivot_map
  679.       $game_temp.hm7_height_limit = [$game_temp.hm7_height_limit.to_i, 0].max
  680.      
  681.       @parameters = [$game_temp.cos_alpha, $game_temp.sin_alpha,
  682.       $game_temp.distance_h, $game_temp.pivot_map.to_i,
  683.       $game_temp.slope_value_map, $game_temp.corrective_value_map,
  684.       $game_temp.hm7_height_limit, $game_temp.cos_theta, $game_temp.sin_theta,
  685.       $game_temp.distance_p.to_i, $game_temp.zoom_map,
  686.       @display_x_min, @display_x_max, @display_y_min, @display_y_max,
  687.       $game_system.hm7_less_cut] # V.1.3
  688.       @rowsdata.set_pixel(0, 0, $game_system.hm7_fading_color)
  689.       HM7.compute_m7(@computetable, @rowsdata, @parameters)
  690.       refresh_zoom_data # V.1.4.1
  691.       @vars[0] = $game_temp.hm7_height_limit
  692.       @need_update = true
  693.     end
  694.     #--------------------------------------------------------------------------
  695.     # * Increase (or decrease) the angle of slant
  696.     #--------------------------------------------------------------------------
  697.     def increase_alpha(value)
  698.       self.alpha = [[alpha + value, 80].min, 0].max
  699.       refresh_alpha
  700.     end
  701.     #--------------------------------------------------------------------------
  702.     # * Set the angle of slant
  703.     #--------------------------------------------------------------------------
  704.     def set_alpha(value)
  705.       self.alpha = [[value, 80].min, 0].max
  706.       refresh_alpha
  707.     end
  708.     #--------------------------------------------------------------------------
  709.     # * Slide from the current slant angle into the target value
  710.     #--------------------------------------------------------------------------
  711.     def to_alpha(value, speed)
  712.       value = [[value, 80].min, 0].max
  713.       while value > alpha
  714.         increase_alpha([speed, value - alpha].min)
  715.         spriteset.update
  716.         Graphics.update
  717.       end
  718.       while value < alpha
  719.         increase_alpha(-([speed, alpha - value].min))
  720.         spriteset.update
  721.         Graphics.update
  722.       end
  723.     end
  724.     #--------------------------------------------------------------------------
  725.     # * Refresh all the parameters dependent on the angle of rotation
  726.     #--------------------------------------------------------------------------
  727.     def refresh_theta
  728.       @rowsdata.set_pixel(0, 0, $game_system.hm7_fading_color)
  729.       @parameters[7] = $game_temp.cos_theta
  730.       @parameters[8] = $game_temp.sin_theta
  731.       HM7.compute_m7(@computetable, @rowsdata, @parameters)
  732.       refresh_zoom_data # V.1.4.1
  733.       @need_update = true
  734.     end
  735.     #--------------------------------------------------------------------------
  736.     # * Increase (or decrease) the angle of rotation
  737.     #--------------------------------------------------------------------------
  738.     def increase_theta(value)
  739.       self.theta += value
  740.       self.theta %= 360
  741.       theta_rad = (Math::PI * theta) / 180
  742.       $game_temp.cos_theta = (2048 * Math.cos(theta_rad)).to_i
  743.       $game_temp.sin_theta = (2048 * Math.sin(theta_rad)).to_i
  744.       $game_system.hm7_theta = theta
  745.       refresh_theta
  746.     end
  747.     #--------------------------------------------------------------------------
  748.     # * Set the angle of rotation
  749.     #--------------------------------------------------------------------------
  750.     def set_theta(value)
  751.       self.theta = value % 360
  752.       theta_rad = (Math::PI * theta) / 180
  753.       $game_temp.cos_theta = (2048 * Math.cos(theta_rad)).to_i
  754.       $game_temp.sin_theta = (2048 * Math.sin(theta_rad)).to_i
  755.       $game_system.hm7_theta = theta
  756.       refresh_theta
  757.     end
  758.     #--------------------------------------------------------------------------
  759.     # * Slide from the current theta into the target value
  760.     #--------------------------------------------------------------------------
  761.     def to_theta(value, speed, direction)
  762.       value %= 360
  763.       while value != theta
  764.         increase_theta(direction * ([(value - theta).abs, speed].min))
  765.         spriteset.update
  766.         Graphics.update
  767.       end
  768.     end
  769.     #--------------------------------------------------------------------------
  770.     # * Increase (or decrease) the zoom level
  771.     #--------------------------------------------------------------------------
  772.     def increase_zoom(value)
  773.       value = value.to_f / 100
  774.       @zoom = [[@zoom * (2 ** value), 500].min, 1].max
  775.       $game_temp.zoom_sprites = @zoom.to_f / 100
  776.       $game_temp.zoom_map = (4096 * (1.0 / $game_temp.zoom_sprites)).to_i
  777.       $game_system.hm7_zoom = @zoom
  778.       refresh_alpha
  779.     end
  780.     #--------------------------------------------------------------------------
  781.     # * Set the zoom level
  782.     #--------------------------------------------------------------------------
  783.     def set_zoom(value)
  784.       @zoom = [[value, 500].min, 1].max
  785.       $game_temp.zoom_sprites = @zoom.to_f / 100
  786.       $game_temp.zoom_map = (4096 * (1.0 / $game_temp.zoom_sprites)).to_i
  787.       $game_system.hm7_zoom = @zoom
  788.       refresh_alpha
  789.     end
  790.     #--------------------------------------------------------------------------
  791.     # * Slide from the current zoom level into the target value
  792.     #--------------------------------------------------------------------------
  793.     def to_zoom(value, speed)
  794.       value = [[value, 500].min, 1].max
  795.       while value > @zoom
  796.         increase_zoom(speed)
  797.         if value < @zoom
  798.           set_zoom(value)
  799.         end
  800.         spriteset.update
  801.         Graphics.update
  802.       end
  803.       while value < @zoom
  804.         increase_zoom(-speed)
  805.         if value > @zoom
  806.           set_zoom(value)
  807.         end
  808.         spriteset.update
  809.         Graphics.update
  810.       end
  811.     end
  812.     #--------------------------------------------------------------------------
  813.     # * Set the light fading
  814.     #--------------------------------------------------------------------------
  815.     def set_fading(red, green, blue, flag)
  816.       $game_system.hm7_fading_color = Color.new(red, green, blue, flag)
  817.       @rowsdata.set_pixel(0, 0, $game_system.hm7_fading_color)
  818.       HM7.compute_m7(@computetable, @rowsdata, @parameters)
  819.       refresh_zoom_data # V.1.4.1
  820.       @need_update = true
  821.     end
  822.     #--------------------------------------------------------------------------
  823.     # * Increase/Decrease  the pivot value (V.1.3)
  824.     #--------------------------------------------------------------------------
  825.     def increase_pivot(value)
  826.       res = [[$game_temp.pivot + value, 472].min, 32].max
  827.       $game_map.display_y -= ((res - $game_temp.pivot) << 2)
  828.       $game_system.hm7_center_y += ((res - $game_temp.pivot) << 2)
  829.       $game_temp.pivot = res
  830.       $game_temp.pivot_map = $game_temp.pivot / @coeff_resolution
  831.       @offset_y_res = ($game_temp.pivot - $game_temp.pivot_map).to_i >> 1
  832.       refresh_alpha
  833.     end
  834.     #--------------------------------------------------------------------------
  835.     # * Set the pivot value (V.1.3)
  836.     #--------------------------------------------------------------------------
  837.     def set_pivot(value)
  838.       res = [[value, 472].min, 32].max
  839.       $game_map.display_y -= ((res - $game_temp.pivot) << 2)
  840.       $game_system.hm7_center_y += ((res - $game_temp.pivot) << 2)
  841.       $game_temp.pivot = res
  842.       $game_temp.pivot_map = $game_temp.pivot / @coeff_resolution
  843.       @offset_y_res = ($game_temp.pivot - $game_temp.pivot_map).to_i >> 1
  844.       refresh_alpha
  845.     end
  846.     #--------------------------------------------------------------------------
  847.     # * Slide from the current pivot value into the target value (V.1.3)
  848.     #--------------------------------------------------------------------------
  849.     def to_pivot(value, speed)
  850.       value = [[value, 480].min, 32].max
  851.       while value > $game_temp.pivot
  852.         increase_pivot([speed, value - $game_temp.pivot].min)
  853.         spriteset.update
  854.         Graphics.update
  855.       end
  856.       while value < $game_temp.pivot
  857.         increase_pivot(-([speed, $game_temp.pivot - value].min))
  858.         spriteset.update
  859.         Graphics.update
  860.       end
  861.     end
  862.     #--------------------------------------------------------------------------
  863.     # * Dispose
  864.     #--------------------------------------------------------------------------
  865.     def dispose
  866.       @render.dispose
  867.       @rowsdata.dispose
  868.       # dispose of surfaces
  869.       @surfaces.each{|surface|
  870.         surface.dispose
  871.       }
  872.       # dispose of map sprite
  873.       sprite.dispose
  874.     end
  875.     #--------------------------------------------------------------------------
  876.     # * Update
  877.     #--------------------------------------------------------------------------
  878.     def update
  879.       # update animated autotiles / tiles (V.1.3)
  880.       if Graphics.frame_count % $game_system.hm7_anim_freq == 0 &&
  881.         $game_system.hm7_animated
  882.       then
  883.         update_autotiles
  884.         update_animated_tiles
  885.         @need_update = true
  886.       end
  887.       # update surfaces
  888.       update_surfaces
  889.       if $game_system.hm7_two_frames_refresh && Graphics.frame_count & 1 == 0
  890.         return
  891.       end
  892.       # update offsets
  893.       offset_x = ($game_map.display_x >> 3) + @offset_x_res
  894.       offset_y = ($game_map.display_y >> 3) + @offset_y_res
  895.       if !@need_update && (offset_x != @offset_x_old || offset_y != @offset_y_old)
  896.         @offset_x_old = offset_x
  897.         @offset_y_old = offset_y
  898.         @need_update = true
  899.       end
  900.       if @need_update
  901.         @vars[1] = offset_x
  902.         @vars[2] = offset_y
  903.         @need_update = false
  904.         if $game_system.hm7_filter
  905.           if $game_system.hm7_two_frames_refresh
  906.             @vars[3] = (Graphics.frame_count >> 1 & 1) + 1
  907.           else
  908.             @vars[3] = (Graphics.frame_count & 1) + 1
  909.           end
  910.         end
  911.         # V.1.4 : n-layers
  912.         @target_y = HM7.render_hm7(@params, @vars, @render_surfaces, @nb_layers)
  913.         @need_update_screen = true
  914.       elsif @need_update_screen
  915.         @vars[3] = 0
  916.         # V.1.4 : n-layers
  917.         @target_y = HM7.render_hm7(@params, @vars, @render_surfaces, @nb_layers)
  918.         @need_update_screen = false
  919.       end
  920.       # camera : vertical offset update
  921.       update_camera
  922.     end
  923.     #--------------------------------------------------------------------------
  924.     # * Update surfaces
  925.     #--------------------------------------------------------------------------
  926.     def update_surfaces
  927.       @surfaces.each{|surface|
  928.         surface.update
  929.       }
  930.       if @need_update_surfaces
  931.         @render_surfaces.clear
  932.         @surfaces.each{|surface|
  933.           if surface.displayed then @render_surfaces.push(surface.get_data) end
  934.         }
  935.         @render_surfaces.sort! {|a, b| b[2] - a[2] == 0 ? a[1] - b[1] : b[2] - a[2]}
  936.         self.need_update_surfaces = false
  937.         @need_update = true
  938.       end
  939.     end
  940.     #--------------------------------------------------------------------------
  941.     # * Update animated autotiles
  942.     #--------------------------------------------------------------------------
  943.     def update_autotiles
  944.       if @tilemap_hash_animated.keys.empty? then return end # V.1.3
  945.       autotiles_graphics = {}
  946.       @autotiles.each{|autotile|
  947.         autotile.animate
  948.         autotiles_graphics[autotile.autotile_id] = autotile.get_current_graphics
  949.       }
  950.       auto_tilesets = []
  951.       for i in 0..6
  952.         if autotiles_graphics.has_key?(i)
  953.           auto_tilesets.push(autotiles_graphics[i])
  954.         else
  955.           auto_tilesets.push(0)
  956.         end
  957.       end
  958.       HM7.refresh_map_tileset(@map_tileset,
  959.       RPG::Cache.tileset($game_map.tileset_name),
  960.       @tilemap_hash_animated, auto_tilesets, @nb_layers) # V.1.4 : n-layers
  961.     end
  962.     #--------------------------------------------------------------------------
  963.     # * Update animated tiles V.1.3
  964.     #--------------------------------------------------------------------------
  965.     def update_animated_tiles
  966.       if @animated_tiles.empty? then return end
  967.       @animated_tiles.each {|animated_tile|
  968.         animated_tile.animate
  969.       }
  970.       HM7.draw_textureset(@animated_textures, @textureset, @texture_auto)
  971.     end
  972.     #--------------------------------------------------------------------------
  973.     # * Update camera
  974.     #--------------------------------------------------------------------------
  975.     def update_camera
  976.       if $game_system.hm7_camera_mode > 0
  977.         # V.1.4.2
  978.         if $game_system.hm7_camera_mode == 3
  979.           # V.1.4.3 : I forgot the sinus, that's really a shame.
  980.           @target_y = @surface_player.altitude * $game_temp.sin_alpha >> 14
  981.         end
  982.         $game_temp.camera_altitude = @target_y # V.1.4.2
  983.         if @vars[4] < @target_y
  984.           @vars[4] = [@vars[4] + 1 + (@target_y - @vars[4] >> 2), @target_y].min
  985.           @need_update = true
  986.         elsif @vars[4] > @target_y + 1
  987.           @vars[4] = [@vars[4] - 1 - (@vars[4] - @target_y >> 2), @target_y].max
  988.           @need_update = true
  989.         end
  990.       end
  991.     end
  992.     #--------------------------------------------------------------------------
  993.     # * no tileset for HM7 maps
  994.     #--------------------------------------------------------------------------
  995.     def tileset
  996.       return nil
  997.     end
  998.     #--------------------------------------------------------------------------
  999.     # * Compute zoom data V.1.4.1
  1000.     #--------------------------------------------------------------------------
  1001.     def refresh_zoom_data
  1002.       color = rowsdata.get_pixel(display_y_max - 1, 1)
  1003.       zoom_max = ((color.red.to_i << 8) + color.alpha).to_f / 4096
  1004.       if $game_temp.hm7_height_limit > display_y_min
  1005.         @y_min = $game_temp.hm7_height_limit
  1006.       else
  1007.         @y_min = display_y_min
  1008.       end
  1009.       color = rowsdata.get_pixel(y_min, 1)
  1010.       @zoom_min = ((color.red.to_i << 8) + color.alpha).to_f / 4096
  1011.       @zoom_slope = (zoom_max - zoom_min) / (display_y_max - 1 - y_min)
  1012.     end
  1013.   end
  1014. end
  1015.  
  1016. #============================================================================
  1017. # ** HM7::Tilemap
  1018. #============================================================================
  1019. module HM7
  1020.   class Tilemap
  1021.     #--------------------------------------------------------------------------
  1022.     # * Initialize the HM7 data depending on the map
  1023.     #--------------------------------------------------------------------------
  1024.     def initialize_map_data
  1025.       data = $game_map.data
  1026.       @nb_layers = data.zsize # V.1.4 : n-layers
  1027.       # Create autotiles graphics
  1028.       # autotiles_hmap : [autotile heightmap]
  1029.       autotiles_hmap = []
  1030.       # animated_autotiles_ids : [animated autotile identifier]
  1031.       animated_autotiles_ids = []
  1032.       # autotiles_graphics : {autotile identifier => HM7::Autotile_Bitmap}
  1033.       autotiles_graphics = {}
  1034.       # @autotiles : [HM7::Autotile]
  1035.       @autotiles = []
  1036.       # autotextures_map : {autotile identifier => texture name}
  1037.       autotextures_map = {}
  1038.       # create the graphics for the autotiles colormap
  1039.       @texture_auto = HM7::Bitmap_Autotiles.new(RPG::Cache.autotile("Textures/Texture_Auto"), 0) # V.1.3
  1040.       for i in 0..6
  1041.         autotile_name = $game_map.autotile_names[i]
  1042.         if autotile_name == ""
  1043.           autotiles_hmap.push(0)
  1044.         else
  1045.           autotile = HM7::Autotile.new(i, autotile_name)
  1046.           @autotiles.push(autotile)
  1047.           if autotile.animated then animated_autotiles_ids.push(i) end
  1048.           autotiles_graphics[i] = autotile.get_current_graphics
  1049.           # heigthmap
  1050.           if FileTest.exist?("Graphics/Autotiles/" + autotile_name + "_Hmap.png") ||
  1051.             FileTest.exist?("Graphics/Autotiles/" + autotile_name + "_Hmap.PNG")
  1052.           then
  1053.             autotiles_hmap.push(HM7::Bitmap_Autotiles.new(RPG::Cache.autotile(autotile_name + "_Hmap"), 0))
  1054.           else
  1055.             autotiles_hmap.push(Bitmap.new(256, 192))
  1056.           end
  1057.           # texturemap
  1058.           if FileTest.exist?("Graphics/Autotiles/Textures/Texture_" + autotile_name + ".png") ||
  1059.             FileTest.exist?("Graphics/Autotiles/Textures/Texture_" + autotile_name + ".PNG")
  1060.           then
  1061.             autotextures_map[i] = autotile_name
  1062.           end
  1063.         end
  1064.       end
  1065.      
  1066.       # Get the textures graphics for the tileset
  1067.       textures_list = Dir.glob("Graphics/Tilesets/" + $game_map.tileset_name + "_Textures/*.{png,PNG}")
  1068.       textures_map = {} # {tileId => texture filename}
  1069.       for filename in textures_list
  1070.         basic_filename = File.basename(filename, ".*")
  1071.         num_tile = (basic_filename[/\d+/]).to_i
  1072.         textures_map[num_tile] = basic_filename
  1073.       end
  1074.      
  1075.       # V.1.4 : n-layers
  1076.       # tiletable : for each map square, store the HM7Ids of :
  1077.       # [n-layers tile, layer1 tile, layer2 tile, layer3 tile, ...]
  1078.       @tiletable = Table.new((@width >> 5) * (@nb_layers + 1), @height >> 5, 1)
  1079.       textures = {}
  1080.       @animated_textures = {} # V.1.3
  1081.       @animated_tiles = [] # V.1.3
  1082.       basic_tiles_list = {}
  1083.       basic_tiles_count = 0
  1084.       tiles_list = {}
  1085.       tiles_count = 0
  1086.       animated_autotiles_keys = []
  1087.       bush_data = {}
  1088.       for i in 0...$game_map.height
  1089.         for j in 0...$game_map.width
  1090.           # V.1.4 : n-layers
  1091.           tiles_values = []
  1092.           for l in 0...@nb_layers
  1093.             tiles_values.push(data[j, i, l])
  1094.           end
  1095.           unless tiles_list.has_key?(tiles_values)
  1096.             tiles_count += 1
  1097.             tiles_list[tiles_values] = tiles_count
  1098.             # determine the bush value
  1099.             bush_value = @nb_layers
  1100.             for tile_id in tiles_values.reverse
  1101.               if tile_id.nil? || tile_id == 0 ||
  1102.                 $game_map.passages[tile_id] & 0x40 == 0x40
  1103.               then
  1104.                 bush_value -= 1
  1105.               else
  1106.                 break
  1107.               end
  1108.             end
  1109.             bush_data[tiles_count - 1] = bush_value
  1110.           end
  1111.           count = tiles_list[tiles_values]
  1112.           @tiletable[j * (@nb_layers + 1), i, 0] = count - 1
  1113.           k = 0
  1114.           for value in tiles_values
  1115.             k += 1
  1116.             if value > 0
  1117.               unless basic_tiles_list.has_key?(value)
  1118.                 basic_tiles_list[value] = basic_tiles_count
  1119.                 if value >= 384
  1120.                   value -= 384
  1121.                   if textures_map.has_key?(value)
  1122.                     texture_bmp = RPG::Cache.tileset($game_map.tileset_name + "_Textures/" + textures_map[value])
  1123.                     # V.1.3
  1124.                     if texture_bmp.width > 160
  1125.                       animated_tile = HM7::Animated_Tile.new(basic_tiles_count,
  1126.                       value + 384, texture_bmp)
  1127.                       @animated_tiles.push(animated_tile)
  1128.                       textures[basic_tiles_count] = animated_tile.get_data
  1129.                       @animated_textures[basic_tiles_count] = animated_tile.get_data
  1130.                     else
  1131.                       textures[basic_tiles_count] = [value + 384, texture_bmp, 1, 0]
  1132.                     end
  1133.                   end
  1134.                   value += 384
  1135.                 else # autotile
  1136.                   if autotextures_map.has_key?(value / 48 - 1)
  1137.                     texture_bmp = RPG::Cache.autotile("Textures/Texture_" + autotextures_map[value / 48 - 1])
  1138.                     # V.1.3
  1139.                     if texture_bmp.width > 128
  1140.                       animated_tile = HM7::Animated_Tile.new(basic_tiles_count,
  1141.                       value, texture_bmp)
  1142.                       @animated_tiles.push(animated_tile)
  1143.                       textures[basic_tiles_count] = animated_tile.get_data
  1144.                       @animated_textures[basic_tiles_count] = animated_tile.get_data
  1145.                     else
  1146.                       textures[basic_tiles_count] = [value, texture_bmp, 1, 0]
  1147.                     end
  1148.                   end
  1149.                 end
  1150.                 basic_tiles_count += 1
  1151.               end
  1152.               if value < 384 &&
  1153.                 animated_autotiles_ids.include?(value / 48 - 1)
  1154.               then
  1155.                 animated_autotiles_keys.push(count - 1)
  1156.               end
  1157.               @tiletable[j * (@nb_layers + 1) + k, i, 0] = basic_tiles_list[value]
  1158.             end
  1159.           end
  1160.         end
  1161.       end
  1162.       tileset_height = 1 + (tiles_count >> 3) << 5
  1163.       auto_tilesets = []
  1164.       for i in 0..6
  1165.         if autotiles_graphics.has_key?(i)
  1166.           auto_tilesets.push(autotiles_graphics[i])
  1167.         else
  1168.           auto_tilesets.push(0)
  1169.         end
  1170.       end
  1171.       for i in 0..6
  1172.         auto_tilesets.push(autotiles_hmap[i])
  1173.       end
  1174.      
  1175.       # V.1.4 : n-layers
  1176.       @map_tileset = Bitmap.new(256 * (@nb_layers + 8 >> 2), tileset_height)
  1177.       tilemap_hash = {}
  1178.       for key in tiles_list.keys
  1179.         value = tiles_list[key] - 1
  1180.         tilemap_hash[value] = key.push(bush_data[value])
  1181.       end
  1182.  
  1183.       # V.1.4 : n-layers
  1184.       # create the specific n-layers tileset for the map
  1185.       HM7.draw_map_tileset(@map_tileset,
  1186.       RPG::Cache.tileset($game_map.tileset_name),
  1187.       RPG::Cache.tileset($game_map.tileset_name + "_Hmap"),
  1188.       tilemap_hash, auto_tilesets, @nb_layers)
  1189.       for bitmap in autotiles_hmap
  1190.         unless bitmap.is_a?(Fixnum)
  1191.           bitmap.dispose
  1192.         end
  1193.       end
  1194.      
  1195.       # create a hash that contains data for animated 3-layers tiles
  1196.       @tilemap_hash_animated = {}
  1197.       for key in animated_autotiles_keys
  1198.         if tilemap_hash.has_key?(key)
  1199.           @tilemap_hash_animated[key] = tilemap_hash[key]
  1200.         end
  1201.       end
  1202.       if animated_autotiles_keys.empty? && @animated_tiles.empty? # V.1.3
  1203.         $game_system.hm7_animated = false
  1204.       end
  1205.  
  1206.       # create the textureset used to draw vertical walls
  1207.       @textureset = Bitmap.new(160, basic_tiles_count << 5)
  1208.       HM7.draw_textureset(textures, @textureset, @texture_auto) # V.1.3
  1209.            
  1210.     end
  1211.   end
  1212. end
  1213.  
  1214. #============================================================================
  1215. # ** HM7::Cache
  1216. #============================================================================
  1217. module HM7
  1218.   module Cache
  1219.     @cache = {}
  1220.     #------------------------------------------------------------------------
  1221.     # * Check if the map is in the Cache
  1222.     #   map_id : map identifier
  1223.     #------------------------------------------------------------------------
  1224.     def self.in_cache?(map_id)
  1225.       return @cache.include?(map_id)
  1226.     end
  1227.     #------------------------------------------------------------------------
  1228.     # * Return the map data (Array)
  1229.     #   map_id : map identifier
  1230.     #------------------------------------------------------------------------
  1231.     def self.load(map_id)
  1232.       return @cache[map_id]
  1233.     end
  1234.     #------------------------------------------------------------------------
  1235.     # * Save the map data in the Cache
  1236.     #   map_id : map identifier
  1237.     #   params : map data (Array)
  1238.     #------------------------------------------------------------------------
  1239.     def self.save(map_id, params)
  1240.       @cache[map_id] = params
  1241.     end
  1242.     #------------------------------------------------------------------------
  1243.     # * Clear the Cache
  1244.     #------------------------------------------------------------------------
  1245.     def self.clear
  1246.       @cache = {}
  1247.       GC.start
  1248.     end
  1249.   end
  1250. end
  1251.  
  1252. #============================================================================
  1253. # ** HM7::Animated_Tile (V.1.3)
  1254. #============================================================================
  1255. module HM7
  1256.   class Animated_Tile
  1257.     #--------------------------------------------------------------------------
  1258.     # * Attributes
  1259.     #--------------------------------------------------------------------------
  1260.     attr_accessor :tile_count
  1261.     attr_accessor :animations_number
  1262.     attr_accessor :animation_index
  1263.     #--------------------------------------------------------------------------
  1264.     # * Initialize Object
  1265.     #--------------------------------------------------------------------------
  1266.     def initialize(tile_count, tile_id, texture_bmp)
  1267.       self.animations_number = (texture_bmp.width / (tile_id < 384 ? 128 : 160))
  1268.       self.animation_index = 0
  1269.       @data = [tile_id, texture_bmp, animations_number, animation_index]
  1270.     end
  1271.     #--------------------------------------------------------------------------
  1272.     # * Get current data
  1273.     #--------------------------------------------------------------------------
  1274.     def get_data
  1275.       return @data
  1276.     end
  1277.     #--------------------------------------------------------------------------
  1278.     # * Animate - next pattern
  1279.     #--------------------------------------------------------------------------
  1280.     def animate
  1281.       self.animation_index = animation_index.succ % animations_number
  1282.       @data[3] = animation_index
  1283.     end
  1284.   end
  1285. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement