SonicBounty50 0 Report post Posted February 26, 2011 I am not a noob with RPG Maker XP at all, but I just started using Mode 7 script and I am lost on how to make my sprites on my maps vertical. Could anyone help me? They all come out flat. It must be something very easy. Thank you, Share this post Link to post Share on other sites
0 SonicBounty50 0 Report post Posted February 26, 2011 bump! Share this post Link to post Share on other sites
0 Dark Den 4 Report post Posted February 26, 2011 Try posting the script maybe then someone might be able to help. Share this post Link to post Share on other sites
0 Broken Messiah 20 Report post Posted February 26, 2011 Theres a specific terrain ta you have to set it to. Share this post Link to post Share on other sites
0 SonicBounty50 0 Report post Posted February 26, 2011 Try posting the script maybe then someone might be able to help. The script has instructions, but they aren't that clear to me. #==============================================================================# Mode 7 # Written by: MGCaladtogel # Version: unknown # English version date: 21.5.2007 #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:= # - instruction rewritten by Blizzard for easier understanding. # - slightly optimized by Blizzard #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:= # # Introduction: # # This script can display maps in a type of 3D with depth. It has a low lag # factor. # # # Instructions: # # In the editor in the lower left corner is the map list of the maps you # are using in your game. You have several options: If you want to make a # map use Mode 7 you need to ADD one or more of these text commands to the # map's name. Those commands should not appear in the map's name if using # a location display script. The options you have are the following: # # [M7] : to activate Mode7 # [#XX] : XX is the slant angle (in degree). Default value is 0 (normal maps) # [Y] : Y-map looping # [X] : X-map looping. This option needs resources (lower fps). # [A] : animated autotiles (with 4 patterns). This option increases # significantly the loading time, so it may crash for large maps # (SystemStackError) # [C] : to center the map on the hero (even for small maps) # [P] : to have a fixed panorama # [H] : to have a white horizon # [OV] : Overworld Sprite Resize (a Mewsterus's script feature) # # Alternatively you can define prepared settings that will be triggered with # every map that has that specific text included in its name. See the # "MODE7_SETTINGS" below to prepare your settings. # # # Control commands: # # You can change the settings on the map in-game and use a couple of # additional commands. If you want to use one of those commands, use a "Call # Script" event command and type one of the following commands into the text # input window: # # 1. $scene.spriteset.tilemap.mode7_set(ANGLE) # 2. $scene.spriteset.tilemap.mode7_set_p(ANGLE) # 3. $scene.spriteset.tilemap.mode7_redraw # 4. $game_system.map_opacity = VALUE # 5. $game_system.map_gradual_opacity = VALUE # 6. $game_system.map_tone = Color.new(RED, GREEN, BLUE) # 7. $game_system.map_gradual_tone = Tone.new(RED, GREEN, BLUE, GREY) # 8. $game_system.horizon = VALUE # 9. $game_system.reset # # 1. Redraws the map with a new angle which is specified by ANGLE # 2. Redraws the map progressively with a new angle which is specified by # ANGLE # 3. Redraws the map (can be useful with the following commands) # 4. Defines the opacity for Mode7 maps (it needs to redraw) # 5. Defines a gradual opacity for Mode7 maps (it needs to redraw) # (it bugs with horizontal looping) # 6. Defines the tone for Mode7 maps (it needs to redraw) # 7. Defines a gradual tone for Mode7 maps (it needs to redraw) # 8. Defines the view's distance (default : 960) (it needs to redraw) # 9. Re-initialize the previous options # # # Additional commands: # # 1) If you wish to obtain flat events, add a comment in the event's code # and type in the word "Flat" without the double quotes). # 2) You can handle the height of vertical events by adding a comment to the # event's code with the text "Height X" (without the double quotes). # Replace X with the height value. Example: If you use Height 1.5, then # the event will appear floating above its position in a height of 1.5 map # squares (48 pixels). # #============================================================================== # hash for predefined settings MODE7_SETTINGS = {} # access for map names $data_maps = load_data("Data/MapInfos.rxdata") #---------------------# # START Configuration # #---------------------# # The map is drawn from all the tiles of the three layers. You can define tiles # which are not being drawn flat, but vertical which creates the impression # that the objects would be standing upright. # To define such tiles, add one or more terrain tags to this array and separate # them with commas. In your tileset database gives those specific tiles one of # those terrain tags and the tile will be drawn vertically. VERTICAL_TILE_TERRAIN_TAGS = [1, 2] # You can create packages of settings which are automatically triggered if a # map name includes the text corresponding to the setting. Use following # template to create such settings: # # MODE7_SETTINGS['CORRESPONDING_TEXT'] = ['SETTING_1', 'SETTING_2', ...] # # CORRESPONDING_TEXT - text in map name # SETTING - one of the settings from the instructions WITHOUT the # [ and ] brackets (i.e. instead of [H], use just H) # # You can add as many settings as you want. There are two predefined settings # to make you understand easier how it works. MODE7_SETTINGS['World Map'] = ['#60', 'X', 'Y', 'H', 'P'] MODE7_SETTINGS['Smallslant'] = ['#20', 'A', 'S'] #---------------------# # END Configuration # #---------------------# #============================================================================ # ■ Game_System #---------------------------------------------------------------------------- # Add attributes to this class #============================================================================ class Game_System attr_accessor :mode7 # false : normal map / true : mode 7 attr_accessor :loop_x # true : horizontal-looping map attr_accessor :loop_y # true : vertical-looping map attr_accessor :always_scroll # true : to center the camera around the hero attr_accessor :map_tone # mode7 map's tone (Color) attr_accessor :map_opacity # mode7 map's opacity (0..255) attr_accessor :animated # true : animated autotiles for mode7 maps attr_accessor :white_horizon # true : white line horizon for mode7 maps attr_accessor :angle # mode7 map's slant angle (in degree) attr_accessor :horizon # horizon's distance attr_accessor :fixed_panorama # true : to fix the panorama (no scrolling any more) attr_accessor :ov # true : Overworld Sprite Resize (smaller hero's sprite) attr_accessor :ov_zoom # resize's value with ov attr_accessor :map_gradual_opacity # mode7 map's gradual opacity (0..255) attr_accessor :map_gradual_tone # mode7 map's gradual tone (Color) #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- alias initialize_mode7_game_system initialize def initialize initialize_mode7_game_system init_mode7 end #-------------------------------------------------------------------------- # * Mode 7 Initialization #-------------------------------------------------------------------------- def init_mode7 self.mode7 = true self.loop_x = false self.loop_y = false self.always_scroll = false self.animated = false self.white_horizon = false self.angle = 0 self.fixed_panorama = false self.ov = false self.ov_zoom = 0.6 reset end #-------------------------------------------------------------------------- # * Reset the values for opacity, tone and horizon's distance #-------------------------------------------------------------------------- def reset self.map_opacity = 255 self.map_tone = Color.new(0,0,0,0) self.horizon = 960 # default value, equivalent to 30 tiles self.map_gradual_opacity = 0 self.map_gradual_tone = Tone.new(0,0,0,0) end end #============================================================================ # ■ Tilemap_mode7 #---------------------------------------------------------------------------- # This new Tilemap class handles the drawing of a mode7 map #============================================================================ class Tilemap_mode7 attr_accessor :maps_list # contains map's graphics attr_accessor :map_ground # original map's graphic to handle flat events attr_accessor :tone_values # tone values for each line (Hash) attr_accessor :opacity_values # opacity values for each line (Hash) #-------------------------------------------------------------------------- # * Object Initialization # viewport : viewport #-------------------------------------------------------------------------- def initialize(viewport) @id = $game_map.map_id # map's ID : to load or save the map in Cache @maps_list = [] # contains map's drawings (Bitmap) @disp_y = $game_map.display_y # @disp_y : tilemap's display_y @disp_x = $game_map.display_x # @disp_x : tilemap's display_x @height = 32 * $game_map.height # @height : map's height (in pixel) @width = 32 * $game_map.width # @width : map's width (in pixel) $game_temp.height = @height # map's drawings are loaded if already in Cache if RPG::Cache_Carte.in_cache(@id) @map = RPG::Cache_Carte.load(@id) @maps_list.push(@map) @map_ground = RPG::Cache_Carte.load(@id, 4) # to handle flat events if $game_system.animated @map_2 = RPG::Cache_Carte.load(@id, 1) @map_3 = RPG::Cache_Carte.load(@id, 2) @map_4 = RPG::Cache_Carte.load(@id, 3) @maps_list.push(@map_2) @maps_list.push(@map_3) @maps_list.push(@map_4) end else # draw the map and save it in the Cache draw_map end # create vertical elements from tiles data_V = Data_Vertical_Sprites.new(viewport) # @sprites_V : list of vertical sprites (Sprite_V) @sprites_V = data_V.list_sprites_V # @sprites_V_animated : list of animated vertical sprites (Sprite_V) @sprites_V_animated = data_V.list_sprites_V_animated @angle = $game_system.angle # map's slant angle (in degree) @distance_h = 480 # distance between the map's center and the vanishing point @pivot = 256 # screenline's number of the slant's pivot @index_animated = 0 # 0..3 : index of animated tiles pattern @viewport = viewport @tone_values = {} # list of the tone values for each line @opacity_values = {} # list of the opacity values for each line init_sprites(@angle) # initialize screenlines sprites end #-------------------------------------------------------------------------- # * Dispose #-------------------------------------------------------------------------- def dispose # dispose of @sprites (scanlines), @sprites_V (vertical_sprites), and # @sprites_loop_x (additional scanlines for horizontal looping) (@sprites + @sprites_V + @sprites_loop_x).each {|sprite| sprite.dispose} [@sprites, @sprites_V, @sprites_loop_x, @sprites_V_animated, @maps_list].each {|obj| obj.clear} $game_system.angle = @angle end #-------------------------------------------------------------------------- # * Increase slant's angle #-------------------------------------------------------------------------- def increase_angle return if @angle == 88 @angle += 2 @angle = 88 if @angle > 88 @sprites.clear @sprites_loop_x.clear init_sprites(@angle) # reinitialize screenlines sprites end #-------------------------------------------------------------------------- # * Decrease slant's angle #-------------------------------------------------------------------------- def decrease_angle return if @angle == 0 @angle -= 2 @angle = 0 if @angle < 0 @sprites.clear @sprites_loop_x.clear init_sprites(@angle) # reinitialize screenlines sprites end #-------------------------------------------------------------------------- # * Slide from the current angle into the target value # value : target angle's value (in degree) #-------------------------------------------------------------------------- def mode7_set_p(value) while value > @angle increase_angle update Graphics.update end while value < @angle decrease_angle update Graphics.update end end #-------------------------------------------------------------------------- # * Redraw the map instantaneously with the new slant angle's value # value : target angle's value (in degree) #-------------------------------------------------------------------------- def mode7_set(value) if value < 0 @angle = 0 elsif value > 89 @angle = 89 else @angle = value end @sprites.clear @sprites_loop_x.clear init_sprites(@angle) # reinitialize screenlines sprites update Graphics.update end #-------------------------------------------------------------------------- # * Reinitialize screenlines sprites #-------------------------------------------------------------------------- def mode7_redraw @sprites.clear @sprites_loop_x.clear init_sprites(@angle) # reinitialize scanlines update Graphics.update end #-------------------------------------------------------------------------- # * Create sprites equivalent to scanlines # value : target angle's value (in degree) #-------------------------------------------------------------------------- def init_sprites(angle) @horizon = $game_system.horizon angle_rad = (Math::PI * angle) / 180 # angle in radian @sprites = [] # list of the scanlines sprites (Sprite) @sprites_loop_x = [] # list of the additionnal sprites (for X-looping) cos_angle = Math.cos(angle_rad) sin_angle = Math.sin(angle_rad) # save values in $game_temp $game_temp.distance_h = @distance_h $game_temp.pivot = @pivot $game_temp.cos_angle = cos_angle $game_temp.sin_angle = sin_angle # h0, z0 : intermediate values h0 = (- @distance_h * @pivot * cos_angle).to_f / (@distance_h + @pivot * sin_angle) + @pivot z0 = @distance_h.to_f / (@distance_h + @pivot * sin_angle) $game_temp.slope_value = (1.0 - z0) / (@pivot - h0) $game_temp.corrective_value = 1.0 - @pivot * $game_temp.slope_value last_line = - @pivot - @horizon # last_line : the highest line that is drawn height_limit = (@distance_h * last_line * cos_angle).to_f / (@distance_h - last_line * sin_angle) + @pivot # the line corresponding to # the last_line in the warped reference = horizon's line $game_temp.height_limit = height_limit # constant to handle gradual opacity k2lim = ((@distance_h * last_line).to_f / (@distance_h * cos_angle + last_line * sin_angle)).to_i # one sprite is created for each screenline (0..479).each {|j| next if j < height_limit # if the line is further than the horizon's line, # no sprite is created i = j - @pivot # y-reference is the pivot's line sprite = Sprite.new(@viewport) sprite.x = 320 # x-reference is the vertical line in the middle of the screen sprite.y = j sprite.z = - 99999 # map must not mask vertical elements sprite.y_origin_bitmap = (@distance_h * i).to_f / (@distance_h * cos_angle + i * sin_angle) + @pivot sprite.y_origin_bitmap_i = (sprite.y_origin_bitmap + 0.5).to_i sprite.y_origin_bitmap_i %= @height if $game_system.loop_y sprite.zoom_x = $game_temp.slope_value * j + $game_temp.corrective_value sprite.length = 2 + (640.to_f / sprite.zoom_x).to_i sprite.x_origin_bitmap_i = ((642 - sprite.length) / 2) sprite.x_origin_bitmap_i %= @width if $game_system.loop_x sprite.x_origin_bitmap = (sprite.x_origin_bitmap_i).to_f sprite.ox = sprite.length / 2 sprite.bitmap = @map # horizontal translation to center around the hero if @disp_x != 0 sprite.x_origin_bitmap += @disp_x / 4 sprite.x_origin_bitmap_i = (sprite.x_origin_bitmap).to_i sprite.x_origin_bitmap_i %= @width if $game_system.loop_x end # vertical translation to center around the hero if @disp_y != 0 sprite.y_origin_bitmap += @disp_y / 4 sprite.y_origin_bitmap_i = (sprite.y_origin_bitmap + 0.5).to_i sprite.y_origin_bitmap_i %= @height if $game_system.loop_y end # handle opacity and tone k2 = ((@distance_h * i).to_f / (@distance_h * cos_angle + i * sin_angle)).to_i k2 = 0 if k2 > 0 k_red = (- k2.to_f/k2lim * $game_system.map_gradual_tone.red).to_i k_green = (- k2.to_f/k2lim * $game_system.map_gradual_tone.green).to_i k_blue = (- k2.to_f/k2lim * $game_system.map_gradual_tone.blue).to_i k_gray = (- k2.to_f/k2lim * $game_system.map_gradual_tone.gray).to_i k2 = (- k2.to_f/k2lim * $game_system.map_gradual_opacity).to_i sprite.tone = Tone.new(k_red, k_green, k_blue, k_gray) sprite.opacity = 255 - k2 sprite.opacity *= ($game_system.map_opacity).to_f / 255 sprite.color = $game_system.map_tone # white horizon's line k = 500 / (j - height_limit) if $game_system.white_horizon tone_red = sprite.tone.red + k tone_green = sprite.tone.green + k tone_blue = sprite.tone.blue + k tone_gray = sprite.tone.gray + k sprite.tone = Tone.new(tone_red, tone_green, tone_blue, tone_gray) end @tone_values[j] = sprite.tone @opacity_values[j] = sprite.opacity # set sprite's graphics sprite.src_rect.set(sprite.x_origin_bitmap_i, sprite.y_origin_bitmap_i, sprite.length, 1) @sprites.push(sprite) if $game_system.loop_x && j < @pivot # additional sprite to handle horizontal looping sprite2 = Sprite.new(@viewport) sprite2.x = 320 sprite2.y = j sprite2.z = - 99999 sprite2.y_origin_bitmap = sprite.y_origin_bitmap sprite2.y_origin_bitmap_i = sprite.y_origin_bitmap_i sprite2.zoom_x = sprite.zoom_x sprite2.length = sprite.length sprite2.x_origin_bitmap_i = sprite.x_origin_bitmap_i - @width sprite2.x_origin_bitmap = sprite.x_origin_bitmap_i - @width sprite2.ox = sprite.ox sprite2.bitmap = @map sprite2.opacity = sprite.opacity sprite2.color = sprite.color sprite2.tone = sprite.tone sprite2.src_rect.set(sprite2.x_origin_bitmap_i, sprite2.y_origin_bitmap_i, sprite2.length, 1) @sprites_loop_x.push(sprite2) end} end #-------------------------------------------------------------------------- # * Update the screenlines sprites and the vertical sprites # compare tilemap's display with map's display #-------------------------------------------------------------------------- def update # update screenlines sprites if @disp_y < $game_map.display_y difference = $game_map.display_y - @disp_y @disp_y += difference (@sprites + @sprites_loop_x).each {|sprite| sprite.y_origin_bitmap += difference.to_f / 4 sprite.y_origin_bitmap_i = (sprite.y_origin_bitmap+0.5).to_i sprite.y_origin_bitmap_i %= @height if $game_system.loop_y sprite.src_rect.set(sprite.x_origin_bitmap_i, sprite.y_origin_bitmap_i, sprite.length, 1)} end if @disp_y > $game_map.display_y difference = @disp_y - $game_map.display_y @disp_y -= difference (@sprites + @sprites_loop_x).each {|sprite| sprite.y_origin_bitmap -= difference.to_f / 4 sprite.y_origin_bitmap_i = (sprite.y_origin_bitmap+0.5).to_i sprite.y_origin_bitmap_i %= @height if $game_system.loop_y sprite.src_rect.set(sprite.x_origin_bitmap_i, sprite.y_origin_bitmap_i, sprite.length, 1)} end if @disp_x < $game_map.display_x difference = $game_map.display_x - @disp_x @disp_x += difference @sprites.each {|sprite| sprite.x_origin_bitmap += difference.to_f / 4 sprite.x_origin_bitmap_i = (sprite.x_origin_bitmap).to_i sprite.x_origin_bitmap_i %= @width if $game_system.loop_x sprite.src_rect.set(sprite.x_origin_bitmap_i, sprite.y_origin_bitmap_i, sprite.length, 1)} @sprites_loop_x.each {|sprite| sprite.x_origin_bitmap += difference.to_f / 4 sprite.x_origin_bitmap_i = (sprite.x_origin_bitmap).to_i sprite.x_origin_bitmap_i %= @width sprite.x_origin_bitmap_i -= @width sprite.src_rect.set(sprite.x_origin_bitmap_i, sprite.y_origin_bitmap_i, sprite.length, 1)} end if @disp_x > $game_map.display_x difference = @disp_x - $game_map.display_x @disp_x -= difference @sprites.each {|sprite| sprite.x_origin_bitmap -= difference.to_f / 4 sprite.x_origin_bitmap_i = (sprite.x_origin_bitmap).to_i sprite.x_origin_bitmap_i %= @width if $game_system.loop_x sprite.src_rect.set(sprite.x_origin_bitmap_i, sprite.y_origin_bitmap_i, sprite.length, 1)} @sprites_loop_x.each {|sprite| sprite.x_origin_bitmap -= difference.to_f / 4 sprite.x_origin_bitmap_i = (sprite.x_origin_bitmap).to_i sprite.x_origin_bitmap_i %= @width sprite.x_origin_bitmap_i -= @width sprite.src_rect.set(sprite.x_origin_bitmap_i, sprite.y_origin_bitmap_i, sprite.length, 1)} end # update vertical sprites @sprites_V.each {|sprite| sprite.update} end #-------------------------------------------------------------------------- # * Update animation for animated tiles #-------------------------------------------------------------------------- def update_animated @index_animated += 1 @index_animated %= 4 map = @maps_list[@index_animated] # update screenlines sprites (@sprites + @sprites_loop_x).each {|sprite| sprite.bitmap = map sprite.src_rect.set(sprite.x_origin_bitmap_i, sprite.y_origin_bitmap_i, sprite.length, 1)} # update vertical sprites @sprites_V_animated.each {|sprite| sprite.update_animated(@index_animated)} end #-------------------------------------------------------------------------- # * Create bitmaps representing the map #-------------------------------------------------------------------------- def draw_map data = $game_map.data # Table where animated tiles are flagged data_animated = Table.new($game_map.width, $game_map.height) # bigger maps to handle horizontal looping offset = ($game_system.loop_x ? 640 : 0) @map = Bitmap.new(@width + offset, @height) @maps_list.push(@map) rect = Rect.new(0, 0, 32, 32) # create autotiles graphics RPG::Cache.clear @autotiles = [] (0..6).each {|i| autotile_name = $game_map.autotile_names fichier = RPG::Cache.autotile(autotile_name) (0..3).each {|l| data_autotile = Data_Autotiles.new(fichier,l) data_autotile.number = 4*i + l RPG::Cache.save_autotile(data_autotile, data_autotile.number) @autotiles.push(data_autotile)}} # scan map's data to draw it (0...$game_map.height).each {|i| (0...$game_map.width).each {|j| data_animated[j, i] = 0 # tile's ID for the first layer value1 = data[j, i, 0].to_i # prevent from drawing a vertical tile value1 = (VERTICAL_TILE_TERRAIN_TAGS.include?($game_map.terrain_tags[value1]) ? 0 : value1) # value1 != 0 if value1 != 0 # tile's ID for the second layer value2 = data[j, i, 1].to_i # prevent from drawing a vertical tile value2 = (VERTICAL_TILE_TERRAIN_TAGS.include?($game_map.terrain_tags[value2]) ? 0 : value2) # tile's ID for the third layer value3 = data[j, i, 2].to_i # prevent from drawing a vertical tile value3 = (VERTICAL_TILE_TERRAIN_TAGS.include?($game_map.terrain_tags[value3]) ? 0 : value3) # value1 != 0, value2 = 0 if value2 == 0 # value1 != 0, value2 = 0, value3 = 0 if value3 == 0 # value1 associated with a normal autotile if value1 > 383 bitmap = RPG::Cache.tile($game_map.tileset_name, value1, 0) @map.blt(32*j, 32*i, bitmap, rect) if $game_system.loop_x && j.between?(0, 19) @map.blt(32*(j+$game_map.width), 32*i, bitmap, rect) end # value1 associated with an autotile else num = 4*((value1 / 48) - 1) bitmap = RPG::Cache.autotile_base(num, value1) if @autotiles[num].animated data_animated[j, i] = 1 end @map.blt(32*j, 32*i, bitmap, rect) if $game_system.loop_x && j.between?(0, 19) @map.blt(32*(j+$game_map.width), 32*i, bitmap, rect) end end # value1 != 0, value2 = 0, value3 != 0 else bitmap = RPG::Cache_Tile.load(value1, value3) # value1 associated with an autotile if value1 < 384 num = 4*((value1 / 48) - 1) data_animated[j, i] = 1 if @autotiles[num].animated end # value3 associated with an autotile if value3 < 384 num = 4*((value3 / 48) - 1) data_animated[j, i] = 1 if @autotiles[num].animated end @map.blt(32*j, 32*i, bitmap, rect) if $game_system.loop_x && j.between?(0, 19) @map.blt(32*(j+$game_map.width), 32*i, bitmap, rect) end end # value1 != 0, value2 != 0, value3 = 0 elsif value3 == 0 bitmap = RPG::Cache_Tile.load(value1, value2) # value1 associated with an autotile if value1 < 384 num = 4*((value1 / 48) - 1) data_animated[j, i] = 1 if @autotiles[num].animated end # value2 associated with an autotile if value2 < 384 num = 4*((value2 / 48) - 1) data_animated[j, i] = 1 if @autotiles[num].animated end @map.blt(32*j, 32*i, bitmap, rect) if $game_system.loop_x && j.between?(0, 19) @map.blt(32*(j+$game_map.width), 32*i, bitmap, rect) end # value1 != 0, value2 != 0, value3 != 0 else bitmap = RPG::Cache_Tile.load2(value1, value2, value3) # value1 associated with an autotile if value1 < 384 num = 4*((value1 / 48) - 1) data_animated[j, i] = 1 if @autotiles[num].animated end # value2 associated with an autotile if value2 < 384 num = 4*((value2 / 48) - 1) data_animated[j, i] = 1 if @autotiles[num].animated end # value3 associated with an autotile if value3 < 384 num = 4*((value3 / 48) - 1) data_animated[j, i] = 1 if @autotiles[num].animated end @map.blt(32*j, 32*i, bitmap, rect) if $game_system.loop_x && j.between?(0, 19) @map.blt(32*(j+$game_map.width), 32*i, bitmap, rect) end end # value1 = 0 else value2 = data[j, i, 1].to_i value2 = (VERTICAL_TILE_TERRAIN_TAGS.include?($game_map.terrain_tags[value2]) ? 0 : value2) value3 = data[j, i, 2].to_i value3 = (VERTICAL_TILE_TERRAIN_TAGS.include?($game_map.terrain_tags[value3]) ? 0 : value3) # value1 = 0, value2 = 0 if value2 == 0 # value1 = 0, value2 = 0, value3 != 0 if value3 != 0 # value3 associated with a normal tile if value3 > 383 bitmap = RPG::Cache.tile($game_map.tileset_name, value3, 0) @map.blt(32*j, 32*i, bitmap, rect) if $game_system.loop_x && j.between?(0, 19) @map.blt(32*(j+$game_map.width), 32*i, bitmap, rect) end # value3 associated with an autotile else num = 4*((value3 / 48) - 1) bitmap = RPG::Cache.autotile_base(num, value3) if @autotiles[num].animated data_animated[j, i] = 1 end @map.blt(32*j, 32*i, bitmap, rect) if $game_system.loop_x && j.between?(0, 19) @map.blt(32*(j+$game_map.width), 32*i, bitmap, rect) end end end # value1 = 0, value2 != 0, value3 = 0 elsif value3 == 0 # value2 associated with a normal tile if value2 > 383 bitmap = RPG::Cache.tile($game_map.tileset_name, value2, 0) @map.blt(32*j, 32*i, bitmap, rect) if $game_system.loop_x && j.between?(0, 19) @map.blt(32*(j+$game_map.width), 32*i, bitmap, rect) end # value2 associated with an autotile else num = 4*((value2 / 48) - 1) bitmap = RPG::Cache.autotile_base(num, value2) if @autotiles[num].animated data_animated[j, i] = 1 end @map.blt(32*j, 32*i, bitmap, rect) if $game_system.loop_x && j.between?(0, 19) @map.blt(32*(j+$game_map.width), 32*i, bitmap, rect) end end # value1 = 0, value2 != 0, value3 != 0 else bitmap = RPG::Cache_Tile.load(value2, value3) # value2 associated with an autotile if value2 < 384 num = 4*((value2 / 48) - 1) data_animated[j, i] = 1 if @autotiles[num].animated end # value3 associated with an autotile if value3 < 384 num = 4*((value3 / 48) - 1) data_animated[j, i] = 1 if @autotiles[num].animated end @map.blt(32*j, 32*i, bitmap, rect) if $game_system.loop_x && j.between?(0, 19) @map.blt(32*(j+$game_map.width), 32*i, bitmap, rect) end end end}} # save the map's drawing in the Cache RPG::Cache_Carte.save(@id, @map) @map_ground = @map.clone # save a copy of the map to handle flat events RPG::Cache_Carte.save(@id, @map_ground, 4) return if !$game_system.animated # create 3 other maps in case of animated tiles @map_2 = @map.clone @map_3 = @map.clone @map_4 = @map.clone @maps_list.push(@map_2) @maps_list.push(@map_3) @maps_list.push(@map_4) (0...$game_map.height).each {|i| (0...$game_map.width).each {|j| next if data_animated[j, i].to_i == 0 # modify the tile if it is flagged as animated value1 = data[j, i, 0].to_i value2 = data[j, i, 1].to_i value3 = data[j, i, 2].to_i # prevent from drawing a vertical tile value1 = (VERTICAL_TILE_TERRAIN_TAGS.include?($game_map.terrain_tags[value3]) ? 0 : value3) value2 = (VERTICAL_TILE_TERRAIN_TAGS.include?($game_map.terrain_tags[value3]) ? 0 : value3) value3 = (VERTICAL_TILE_TERRAIN_TAGS.include?($game_map.terrain_tags[value3]) ? 0 : value3) if value1 != 0 if value2 == 0 if value3 == 0 num = 4*((value1 / 48) - 1) bitmap_2 = RPG::Cache.autotile_base(num+1, value1) bitmap_3 = RPG::Cache.autotile_base(num+2, value1) bitmap_4 = RPG::Cache.autotile_base(num+3, value1) @map_2.blt(32*j, 32*i, bitmap_2, rect) @map_3.blt(32*j, 32*i, bitmap_3, rect) @map_4.blt(32*j, 32*i, bitmap_4, rect) if $game_system.loop_x && j.between?(0, 19) @map_2.blt(32*(j+$game_map.width), 32*i, bitmap_2, rect) @map_3.blt(32*(j+$game_map.width), 32*i, bitmap_3, rect) @map_4.blt(32*(j+$game_map.width), 32*i, bitmap_4, rect) end else bitmap_2 = RPG::Cache_Tile.load(value1, value3, 1) bitmap_3 = RPG::Cache_Tile.load(value1, value3, 2) bitmap_4 = RPG::Cache_Tile.load(value1, value3, 3) @map_2.blt(32*j, 32*i, bitmap_2, rect) @map_3.blt(32*j, 32*i, bitmap_3, rect) @map_4.blt(32*j, 32*i, bitmap_4, rect) if $game_system.loop_x && j.between?(0, 19) @map_2.blt(32*(j+$game_map.width), 32*i, bitmap_2, rect) @map_3.blt(32*(j+$game_map.width), 32*i, bitmap_3, rect) @map_4.blt(32*(j+$game_map.width), 32*i, bitmap_4, rect) end end elsif value3 == 0 bitmap_2 = RPG::Cache_Tile.load(value1, value2, 1) bitmap_3 = RPG::Cache_Tile.load(value1, value2, 2) bitmap_4 = RPG::Cache_Tile.load(value1, value2, 3) @map_2.blt(32*j, 32*i, bitmap_2, rect) @map_3.blt(32*j, 32*i, bitmap_3, rect) @map_4.blt(32*j, 32*i, bitmap_4, rect) if $game_system.loop_x && j.between?(0, 19) @map_2.blt(32*(j+$game_map.width), 32*i, bitmap_2, rect) @map_3.blt(32*(j+$game_map.width), 32*i, bitmap_3, rect) @map_4.blt(32*(j+$game_map.width), 32*i, bitmap_4, rect) end else bitmap_2 = RPG::Cache_Tile.load2(value1, value2, value3, 1) bitmap_3 = RPG::Cache_Tile.load2(value1, value2, value3, 2) bitmap_4 = RPG::Cache_Tile.load2(value1, value2, value3, 3) @map_2.blt(32*j, 32*i, bitmap_2, rect) @map_3.blt(32*j, 32*i, bitmap_3, rect) @map_4.blt(32*j, 32*i, bitmap_4, rect) if $game_system.loop_x && j.between?(0, 19) @map_2.blt(32*(j+$game_map.width), 32*i, bitmap_2, rect) @map_3.blt(32*(j+$game_map.width), 32*i, bitmap_3, rect) @map_4.blt(32*(j+$game_map.width), 32*i, bitmap_4, rect) end end elsif value2 != 0 if value3 == 0 num = 4*((value2 / 48) - 1) bitmap_2 = RPG::Cache.autotile_base(num+1, value2) bitmap_3 = RPG::Cache.autotile_base(num+2, value2) bitmap_4 = RPG::Cache.autotile_base(num+3, value2) @map_2.blt(32*j, 32*i, bitmap_2, rect) @map_3.blt(32*j, 32*i, bitmap_3, rect) @map_4.blt(32*j, 32*i, bitmap_4, rect) if $game_system.loop_x && j.between?(0, 19) @map_2.blt(32*(j+$game_map.width), 32*i, bitmap_2, rect) @map_3.blt(32*(j+$game_map.width), 32*i, bitmap_3, rect) @map_4.blt(32*(j+$game_map.width), 32*i, bitmap_4, rect) end else bitmap_2 = RPG::Cache_Tile.load(value2, value3, 1) bitmap_3 = RPG::Cache_Tile.load(value2, value3, 2) bitmap_4 = RPG::Cache_Tile.load(value2, value3, 3) @map_2.blt(32*j, 32*i, bitmap_2, rect) @map_3.blt(32*j, 32*i, bitmap_3, rect) @map_4.blt(32*j, 32*i, bitmap_4, rect) if $game_system.loop_x && j.between?(0, 19) @map_2.blt(32*(j+$game_map.width), 32*i, bitmap_2, rect) @map_3.blt(32*(j+$game_map.width), 32*i, bitmap_3, rect) @map_4.blt(32*(j+$game_map.width), 32*i, bitmap_4, rect) end end elsif value3 != 0 num = 4*((value3 / 48) - 1) bitmap_2 = RPG::Cache.autotile_base(num+1, value3) bitmap_3 = RPG::Cache.autotile_base(num+2, value3) bitmap_4 = RPG::Cache.autotile_base(num+3, value3) @map_2.blt(32*j, 32*i, bitmap_2, rect) @map_3.blt(32*j, 32*i, bitmap_3, rect) @map_4.blt(32*j, 32*i, bitmap_4, rect) if $game_system.loop_x && j.between?(0, 19) @map_2.blt(32*(j+$game_map.width), 32*i, bitmap_2, rect) @map_3.blt(32*(j+$game_map.width), 32*i, bitmap_3, rect) @map_4.blt(32*(j+$game_map.width), 32*i, bitmap_4, rect) end end}} # save the three additional maps in the Cache RPG::Cache_Carte.save(@id, @map_2, 1) RPG::Cache_Carte.save(@id, @map_3, 2) RPG::Cache_Carte.save(@id, @map_4, 3) end end #============================================================================ # ■ Game_Map #---------------------------------------------------------------------------- # Methods modifications to handle map looping #============================================================================ class Game_Map #-------------------------------------------------------------------------- # * Scroll Down # distance : scroll distance #-------------------------------------------------------------------------- alias scroll_down_mode7_game_map scroll_down def scroll_down(distance) if !$game_system.mode7 scroll_down_mode7_game_map(distance) return end @display_y = @display_y + distance unless $game_system.loop_y || $game_system.always_scroll height = (self.height - 15) * 128 @display_y = height if @display_y > height end end #-------------------------------------------------------------------------- # * Scroll Left # distance : scroll distance #-------------------------------------------------------------------------- alias scroll_left_mode7_game_map scroll_left def scroll_left(distance) if !$game_system.mode7 scroll_left_mode7_game_map(distance) return end @display_x = @display_x - distance unless $game_system.loop_x || $game_system.always_scroll @display_x = 0 if @display_x < 0 end end #-------------------------------------------------------------------------- # * Scroll Right # distance : scroll distance #-------------------------------------------------------------------------- alias scroll_right_mode7_game_map scroll_right def scroll_right(distance) if !$game_system.mode7 scroll_right_mode7_game_map(distance) return end @display_x = @display_x + distance unless $game_system.loop_x || $game_system.always_scroll width = (self.width - 20) * 128 @display_x = width if @display_x > width end end #-------------------------------------------------------------------------- # * Scroll Up # distance : scroll distance #-------------------------------------------------------------------------- alias scroll_up_mode7_game_map scroll_up def scroll_up(distance) if !$game_system.mode7 scroll_up_mode7_game_map(distance) return end @display_y = @display_y - distance unless $game_system.loop_y || $game_system.always_scroll @display_y = 0 if @display_y < 0 end end #-------------------------------------------------------------------------- # * Determine Valid Coordinates # x : x-coordinate # y : y-coordinate # Allow the hero to go out of the map when map looping #-------------------------------------------------------------------------- alias valid_mode7_game_map? valid? def valid?(x, y) return (valid_mode7_game_map?(x, y)) if !$game_system.mode7 if $game_system.loop_x return ($game_system.loop_y || y >= 0 && y < height) elsif $game_system.loop_y return (x >= 0 && x < width) end return (x >= 0 && x < width && y >= 0 && y < height) end #-------------------------------------------------------------------------- # * Determine if Passable # x : x-coordinate # y : y-coordinate # d : direction (0,2,4,6,8,10) # * 0,10 = determine if all directions are impassable # self_event : Self (If event is determined passable) #-------------------------------------------------------------------------- alias passable_mode7_game_map? passable? def passable?(x, y, d, self_event = nil) if !$game_system.mode7 passable_mode7_game_map?(x, y, d, self_event) return(passable_mode7_game_map?(x, y, d, self_event)) end return false unless valid?(x, y) bit = (1 << (d / 2 - 1)) & 0x0f events.each_value {|event| if event.tile_id >= 0 && event != self_event && event.x == x && event.y == y && !event.through if @passages[event.tile_id] & bit != 0 return false elsif @passages[event.tile_id] & 0x0f == 0x0f return false elsif @priorities[event.tile_id] == 0 return true end end} [2, 1, 0].each {|i| tile_id = data[x % width, y % height, i] # handle map looping if tile_id == nil return false elsif @passages[tile_id] & bit != 0 return false elsif @passages[tile_id] & 0x0f == 0x0f return false elsif @priorities[tile_id] == 0 return true end} return true end end #============================================================================ # ■ Game_Character #---------------------------------------------------------------------------- # "update" method modifications to handle map looping #============================================================================ class Game_Character attr_accessor :x attr_accessor :y attr_accessor :real_x attr_accessor :real_y attr_reader :flat attr_reader :height #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- alias initialize_mode7_game_character initialize def initialize initialize_mode7_game_character init_mode7 end #-------------------------------------------------------------------------- # * Mode7 Initialization #-------------------------------------------------------------------------- def init_mode7 @flat = false @height = 0.0 end #-------------------------------------------------------------------------- # * Update #-------------------------------------------------------------------------- alias update_mode7_game_character update def update if !$game_system.mode7 update_mode7_game_character return end # if x-coordinate is out of the map if !(x.between?(0, $game_map.width - 1)) difference = 128 * x - real_x if self.is_a?(Game_Player) # increase or decrease map's number self.map_number_x += difference / (difference.abs) end # x-coordinate is equal to its equivalent in the map self.x %= $game_map.width self.real_x = 128 * x - difference end # if y-coordinate is out of the map if !(y.between?(0, $game_map.height - 1)) difference = 128 * y - real_y if self.is_a?(Game_Player) # increase or decrease map's number self.map_number_y += difference / (difference.abs) end # y-coordinate is equal to its equivalent in the map self.y %= $game_map.height self.real_y = 128 * y - difference end update_mode7_game_character end end #============================================================================== # ■ Game_Event #---------------------------------------------------------------------------- # Add methods to handle flat events and altitude for vertical event #============================================================================ class Game_Event < Game_Character #-------------------------------------------------------------------------- # * scan the event's commands list # page : the scanned page (RPG::Event::Page) #-------------------------------------------------------------------------- def check_commands(page) @height = 0.0 command_list = page.list (0..command_list.length - 2).each {|k| command = command_list[k] if (command.parameters[0].to_s).include?('Height') @height = (command.parameters[0][7,command.parameters[0].length-1]).to_f end @flat = (command.parameters[0].to_s).include?('Flat')} end #-------------------------------------------------------------------------- # * scan the event's commands list of the current page when refreshed #-------------------------------------------------------------------------- alias refresh_mode7_game_character refresh def refresh refresh_mode7_game_character check_commands(@page) if @page != nil end end #============================================================================ # ■ Game_Player #---------------------------------------------------------------------------- # Add attributes to have a well-working panorama's scrolling #============================================================================ class Game_Player < Game_Character attr_accessor :map_number_x # map's number with X-looping attr_accessor :map_number_y # map's number with Y-looping #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- alias initialize_mode7_game_player initialize def initialize initialize_mode7_game_player init_mode7 end #-------------------------------------------------------------------------- # * Mode 7 Initialization #-------------------------------------------------------------------------- def init_mode7 self.map_number_x = 0 self.map_number_y = 0 super end #-------------------------------------------------------------------------- # * Handle the option : center around the hero #-------------------------------------------------------------------------- alias center_mode7_game_player center def center(x, y) if !$game_system.mode7 || !$game_system.always_scroll center_mode7_game_player(x, y) return end $game_map.display_x = x * 128 - CENTER_X $game_map.display_y = y * 128 - CENTER_Y end end #============================================================================ # ■ Sprite #---------------------------------------------------------------------------- # Add attributes to work efficiently with scanlines sprites #============================================================================ class Sprite attr_accessor :y_origin_bitmap # bitmap's y-coordinate for the "src_rect.set" #method (float) attr_accessor :x_origin_bitmap # bitmap's x-coordinate for the "src_rect.set" #method (float) attr_accessor :y_origin_bitmap_i # bitmap's y-coordinate for the #"src_rect.set" method (integer) attr_accessor :x_origin_bitmap_i # bitmap's x-coordinate for the #"src_rect.set" method (integer) attr_accessor :length # sprite's width end #============================================================================ # ■ Sprite_Character #---------------------------------------------------------------------------- # Calculate x-coordinate and y-coordinate for a mode7 map #============================================================================ class Sprite_Character < RPG::Sprite attr_reader :flat_indicator # true if the event is flat-drawn #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- alias initialize_mode7_sprite_character initialize def initialize(viewport, character = nil) @flat_indicator = false initialize_mode7_sprite_character(viewport, character) end #-------------------------------------------------------------------------- # * Update #-------------------------------------------------------------------------- alias update_mode7_sprite_character update def update if !$game_system.mode7 update_mode7_sprite_character return end if @flat_indicator if (!@character.flat || @character.moving? || @tile_id != @character.tile_id || @character_name != @character.character_name || @character_hue != @character.character_hue) @flat_indicator = @character.flat # redraw the original ground maps_list = $scene.spriteset.tilemap.maps_list map_ground = $scene.spriteset.tilemap.map_ground rect = Rect.new(@flat_x_map, @flat_y_map, @flat_width, @flat_height) maps_list.each {|map| map.blt(@flat_x_map, @flat_y_map, map_ground, rect) if $game_system.loop_x && @flat_x_map.between?(0, 19 * 32) map.blt(@flat_x_map + 32 * $game_map.width, @flat_y_map, map_ground, rect) end} else return end end super if @tile_id != @character.tile_id || @character_name != @character.character_name || @character_hue != @character.character_hue @tile_id = @character.tile_id @character_name = @character.character_name @character_hue = @character.character_hue if @tile_id >= 384 self.bitmap = RPG::Cache.tile($game_map.tileset_name, @tile_id, @character.character_hue) self.src_rect.set(0, 0, 32, 32) self.ox = 16 self.oy = 32 else self.bitmap = RPG::Cache.character(@character.character_name, @character.character_hue) @cw = bitmap.width / 4 @ch = bitmap.height / 4 self.ox = @cw / 2 self.oy = @ch # pivot correction (intersection between the map and this sprite) self.oy -= 4 end end self.visible = (!@character.transparent) if @tile_id == 0 sx = @character.pattern * @cw sy = (@character.direction - 2) / 2 * @ch self.src_rect.set(sx, sy, @cw, @ch) end if @character.flat # event must be flat drawn return if $scene.spriteset == nil if @tile_id == 0 @flat_x_map = @character.real_x / 4 - (@cw - 32) / 2 @flat_y_map = @character.real_y / 4 - @ch + 32 @flat_x0 = sx @flat_y0 = sy @flat_width = @cw @flat_height = @ch else @flat_x_map = @character.real_x / 4 @flat_y_map = @character.real_y / 4 @flat_x0 = 0 @flat_y0 = 0 @flat_width = 32 @flat_height = 32 end # modify the maps graphics maps_list = $scene.spriteset.tilemap.maps_list rect = Rect.new(@flat_x0, @flat_y0, @flat_width, @flat_height) maps_list.each {|map| map.blt(@flat_x_map, @flat_y_map, bitmap, rect, @character.opacity) if $game_system.loop_x && @flat_x_map.between?(0, 19 * 32) map.blt(@flat_x_map + 32 * $game_map.width, @flat_y_map, bitmap, rect, @character.opacity) end} @flat_indicator = true self.opacity = 0 return end x_intermediate = @character.screen_x y_intermediate = @character.screen_y y_intermediate -= $game_temp.pivot + 4 if $game_system.mode7 # if vertical looping if $game_system.loop_y h = 32 * $game_map.height y_intermediate = (y_intermediate + h / 2) % h - h / 2 end # coordinates in a mode7 map self.y = (($game_temp.distance_h * y_intermediate * $game_temp.cos_angle).to_f / ($game_temp.distance_h - y_intermediate * $game_temp.sin_angle) + $game_temp.pivot) self.zoom_x = $game_temp.slope_value * y + $game_temp.corrective_value self.zoom_y = zoom_x self.x = 320 + zoom_x * (x_intermediate - 320) # if horizontal looping if $game_system.loop_x offset = ($game_map.width >= 24 ? 64 * zoom_x : 0) l = 32 * $game_map.width * zoom_x self.x = (x + offset) % l - offset end # Overworld Sprite Resize if @character.is_a?(Game_Player) && $game_system.ov self.zoom_x *= $game_system.ov_zoom self.zoom_y *= $game_system.ov_zoom end self.z = @character.screen_z(@ch) # hide the sprite if it is beyond the horizon's line self.opacity = (y < $game_temp.height_limit ? 0 : @character.opacity) self.y -= 32 * @character.height * zoom_y # height correction self.blend_type = @character.blend_type self.bush_depth = @character.bush_depth if @character.animation_id != 0 animation = $data_animations[@character.animation_id] animation(animation, true) @character.animation_id = 0 end end end #============================================================================ # ■ Sprite_V (Vertical Sprites) #---------------------------------------------------------------------------- # Sprites corresponding to the vertical elements formed by tiles #============================================================================ class Sprite_V < Sprite attr_accessor :x_map # sprite's x_coordinates (in squares) (Float) attr_accessor :y_map # sprite's y_coordinates (in squares) (Float) attr_accessor :square_y # sprite's y_coordinates (in squares) (Integer) attr_accessor :priority # sprite's priority attr_accessor :animated # True if animated attr_accessor :list_bitmap # list of sprite's bitmaps (Bitmap) #-------------------------------------------------------------------------- # * Update #-------------------------------------------------------------------------- def update square_y_corrected = square_y y_intermediate = 32 * y_map - $game_temp.pivot - $game_map.display_y / 4 y_intermediate_reference = y_intermediate # if vertical looping if $game_system.loop_y y_intermediate = (y_intermediate + $game_temp.height / 2) % $game_temp.height - $game_temp.height / 2 if y_intermediate_reference < y_intermediate square_y_corrected = square_y + $game_map.height elsif y_intermediate_reference > y_intermediate square_y_corrected = square_y - $game_map.height end end self.y = ($game_temp.distance_h * y_intermediate * $game_temp.cos_angle).to_f / ($game_temp.distance_h - y_intermediate * $game_temp.sin_angle) + $game_temp.pivot if y < $game_temp.height_limit # hide the sprite if it is beyond the horizon's line self.opacity = 0 return end self.opacity = 255 if $scene.spriteset != nil opacity_values = $scene.spriteset.tilemap.opacity_values tone_values = $scene.spriteset.tilemap.tone_values if opacity_values.has_key?(y) self.opacity = opacity_values[y] self.tone = tone_values[y] end end self.zoom_x = $game_temp.slope_value * y + $game_temp.corrective_value self.zoom_y = zoom_x x_intermediate = 32 * x_map - $game_map.display_x / 4 self.x = 320 + (zoom_x * (x_intermediate - 320)) # if horizontal looping if $game_system.loop_x offset = ($game_map.width >= 24 ? 64 * zoom_x : 0) l = 32 * $game_map.width * self.zoom_x self.x = (self.x + offset) % l - offset end self.z = (128 * square_y_corrected - $game_map.display_y + 3) / 4 + 32 + 32 * priority end #-------------------------------------------------------------------------- # * Update bitmap for animation # index : 0..3 : animation's index #-------------------------------------------------------------------------- def update_animated(index) self.bitmap = @list_bitmap[index] end end #============================================================================ # ■ Spriteset_Map #---------------------------------------------------------------------------- # Modifications to call a mode7 map #============================================================================ class Spriteset_Map attr_accessor :tilemap # just to be able to access the tilemap #-------------------------------------------------------------------------- # * Defines map's options from its name # Refer to Game_System class #-------------------------------------------------------------------------- def init_options map_data = $data_maps[$game_map.map_id] MODE7_SETTINGS.each_key {|keyword| if map_data.name2.include?(keyword) command_list = MODE7_SETTINGS[keyword] $game_system.mode7 = true $game_system.loop_x = command_list.include?("X") $game_system.loop_y = command_list.include?("Y") $game_system.always_scroll = command_list.include?("C") $game_system.animated = command_list.include?("A") $game_system.white_horizon = command_list.include?("H") $game_system.fixed_panorama = command_list.include?("P") $game_system.ov = command_list.include?("OV") command_list.each {|command| if command.include?("#") $game_system.angle = (command.slice(1, 2)).to_i if $game_system.angle < 0 $game_system.angle = 0 elsif $game_system.angle > 89 $game_system.angle = 89 end break end} return end} $game_system.mode7 = map_data.name2.include?("[M7]") $game_system.loop_x = map_data.name2.include?("[X]") $game_system.loop_y = map_data.name2.include?("[Y]") $game_system.always_scroll = map_data.name2.include?("[C]") $game_system.animated = map_data.name2.include?("[A]") $game_system.white_horizon = map_data.name2.include?("[H]") $game_system.fixed_panorama = map_data.name2.include?("[P]") $game_system.ov = map_data.name2.include?("[OV]") if $game_system.mode7 map_data.name2 =~ /\[#[ ]*([00-99]+)\]/i $game_system.angle = $1.to_i if $game_system.angle < 0 $game_system.angle = 0 elsif $game_system.angle > 89 $game_system.angle = 89 end end end #-------------------------------------------------------------------------- # * Initialize Object # Rewritten to call a map with mode7 #-------------------------------------------------------------------------- alias initialize_mode7_spriteset_map initialize def initialize if !$game_system.mode7 initialize_mode7_spriteset_map return end init_options @viewport1 = Viewport.new(0, 0, 640, 480) @viewport2 = Viewport.new(0, 0, 640, 480) @viewport3 = Viewport.new(0, 0, 640, 480) @viewport2.z = 200 @viewport3.z = 5000 # mode7 map @tilemap = Tilemap_mode7.new(@viewport1) @panorama = Plane.new(@viewport1) # sprites drawn at the horizon's level have a negative z, and with a z value # of -100000 the panorama is still below @panorama.z = ($game_system.mode7 ? -100000 : -1000) @fog = Plane.new(@viewport1) @fog.z = 3000 @character_sprites = [] $game_map.events.keys.sort.each {|i| sprite = Sprite_Character.new(@viewport1, $game_map.events) @character_sprites.push(sprite)} @character_sprites.push(Sprite_Character.new(@viewport1, $game_player)) @weather = RPG::Weather.new(@viewport1) @picture_sprites = [] (1..50).each {|i| @picture_sprites.push(Sprite_Picture.new(@viewport2, $game_screen.pictures))} @timer_sprite = Sprite_Timer.new update end #-------------------------------------------------------------------------- # * Dispose #-------------------------------------------------------------------------- alias dispose_mode7_spriteset_map dispose def dispose if !$game_system.mode7 dispose_mode7_spriteset_map return end @tilemap.dispose @panorama.dispose @fog.dispose @character_sprites.each {|sprite| sprite.dispose} @weather.dispose @picture_sprites.each {|sprite| sprite.dispose} @timer_sprite.dispose @viewport1.dispose @viewport2.dispose @viewport3.dispose end #-------------------------------------------------------------------------- # * Update #-------------------------------------------------------------------------- alias update_mode7_spriteset_map update def update if !$game_system.mode7 update_mode7_spriteset_map return end if @panorama_name != $game_map.panorama_name || @panorama_hue != $game_map.panorama_hue @panorama_name = $game_map.panorama_name @panorama_hue = $game_map.panorama_hue if @panorama.bitmap != nil @panorama.bitmap.dispose @panorama.bitmap = nil end if @panorama_name != "" @panorama.bitmap = RPG::Cache.panorama(@panorama_name, @panorama_hue) end Graphics.frame_reset end if @fog_name != $game_map.fog_name || @fog_hue != $game_map.fog_hue @fog_name = $game_map.fog_name @fog_hue = $game_map.fog_hue if @fog.bitmap != nil @fog.bitmap.dispose @fog.bitmap = nil end @fog.bitmap = RPG::Cache.fog(@fog_name, @fog_hue) if @fog_name != '' Graphics.frame_reset end # update animated tiles each 20 frames if Graphics.frame_count % 20 == 0 && $game_system.animated @tilemap.update_animated end @tilemap.update # if the panorama is fixed if $game_system.fixed_panorama @panorama.ox = 0 @panorama.oy = 0 # if it is a mode7 map else # to have a fluent panorama scrolling @panorama.ox = (128 * $game_map.width * $game_player.map_number_x + $game_player.real_x) / 8 @panorama.oy = - (128 * $game_map.height * $game_player.map_number_y + $game_player.real_y) / 32 end @fog.zoom_x = $game_map.fog_zoom / 100.0 @fog.zoom_y = $game_map.fog_zoom / 100.0 @fog.opacity = $game_map.fog_opacity @fog.blend_type = $game_map.fog_blend_type @fog.ox = $game_map.display_x / 4 + $game_map.fog_ox @fog.oy = $game_map.display_y / 4 + $game_map.fog_oy @fog.tone = $game_map.fog_tone @character_sprites.each {|sprite| sprite.update} @weather.type = $game_screen.weather_type @weather.max = $game_screen.weather_max @weather.ox = $game_map.display_x / 4 @weather.oy = $game_map.display_y / 4 @weather.update @picture_sprites.each {|sprite| sprite.update} @timer_sprite.update @viewport1.tone = $game_screen.tone @viewport1.ox = $game_screen.shake @viewport3.color = $game_screen.flash_color @viewport1.update @viewport3.update end end #============================================================================ # ■ Scene_Map #============================================================================ class Scene_Map attr_accessor :spriteset # just need to access the spriteset end #============================================================================ # ■ Data_Autotiles #---------------------------------------------------------------------------- # Creates the set of tiles from an autotile's file #============================================================================ class Data_Autotiles < Bitmap # data list to form tiles from an atotiles file Data_creation = [[27,28,33,34],[5,28,33,34],[27,6,33,34],[5,6,33,34], [27,28,33,12],[5,28,33,12],[27,6,33,12],[5,6,33,12],[27,28,11,34], [5,28,11,34],[27,6,11,34],[5,6,11,34],[27,28,11,12],[5,28,11,12], [27,6,11,12],[5,6,11,12],[25,26,31,32],[25,6,31,32],[25,26,31,12], [25,6,31,12],[15,16,21,22],[15,16,21,12],[15,16,11,22],[15,16,11,12], [29,30,35,36],[29,30,11,36],[5,30,35,36],[5,30,11,36],[39,40,45,46], [5,40,45,46],[39,6,45,46],[5,6,45,46],[25,30,31,36],[15,16,45,46], [13,14,19,20],[13,14,19,12],[17,18,23,24],[17,18,11,24],[41,42,47,48], [5,42,47,48],[37,38,43,44],[37,6,43,44],[13,18,19,24],[13,14,43,44], [37,42,43,48],[17,18,47,48],[13,18,43,48],[13,18,43,48]] attr_accessor :number # autotile's number to identify it attr_accessor :animated # TRUE if the autotile is animated #-------------------------------------------------------------------------- # * Initialize Object # file : autotiles file's bitmap (Bitmap) # l : 0..3 : pattern's number for animated autotiles #-------------------------------------------------------------------------- def initialize(file, l) super(8*32, 6*32) create(file, l) end #-------------------------------------------------------------------------- # * Create the tiles set # file : autotiles file's bitmap (Bitmap) # l : 0..3 : pattern's number for animated autotiles #-------------------------------------------------------------------------- def create(file, l) l = (file.width > 96 ? l : 0) self.animated = (file.width > 96) (0..5).each {|i| (0..7).each {|j| Data_creation[8 * i + j].each {|number| number -= 1 m = 16 * (number % 6) n = 16 * (number / 6) blt(32 * j + m % 32, 32 * i + n % 32, file, Rect.new(m + 96 * l, n, 16, 16))}}} end end #============================================================================ # ■ Data_Vertical_Sprites #---------------------------------------------------------------------------- # Create a list of vertical sprites for the three layers of a map # "V" for "Vertical" in the script # "num" for "number" #============================================================================ class Data_Vertical_Sprites attr_accessor :list_sprites_V # list of vertical sprites attr_accessor :list_sprites_V_animated # list of animated vertical sprites #-------------------------------------------------------------------------- # * A little method to compare terrain_tags # value : tile's ID # num : reference terrain_tag's value #-------------------------------------------------------------------------- def suitable?(value, num) return ($game_map.terrain_tags[value] == num) end #-------------------------------------------------------------------------- # * This algorithm scans each layer and create a sprites formed by tiles # in contact # viewport : Viewport #-------------------------------------------------------------------------- def initialize(viewport) @viewport = viewport # lists initialization self.list_sprites_V = [] self.list_sprites_V_animated = [] # @num_tiles : list of tiles coordinates that form a vertical sprite @num_tiles = [] # create copy of map's data @dataV = ($game_map.data).clone # scan each layer, row and column (0..2).each {|h| (0..$game_map.height).each {|i| (0..$game_map.width).each {|j| value = @dataV[j, i, h].to_i # if tile's terrain tag is declared to give vertical sprites if VERTICAL_TILE_TERRAIN_TAGS.include?($game_map.terrain_tags[value]) @reference_terrain_tag = $game_map.terrain_tags[value] @num_tiles.push([j, i]) # the following algorithm is so complex that I really don't know how # it works exactly list_end = 0 length = 0 while j + length + 1 < $game_map.width && suitable?(@dataV[j +length+ 1, i, h].to_i, @reference_terrain_tag) @num_tiles.push([j + length+ 1,i]) length += 1 end list_start = j list_end = length + j indicator = true row = 0 j2 = j while indicator row += 1 break if (i + row) == $game_map.height list_start2 = j2 length2 = 0 indicator = false if length >= 2 ((j2 + 1)..(j2 + length -1)).each {|k| if suitable?(@dataV[k, i + row, h].to_i, @reference_terrain_tag) if !indicator list_start2 = k else length2 = k - list_start2 end indicator = true @num_tiles.push([k, i + row]) elsif !indicator length2 -= 1 end} end if suitable?(@dataV[j2 + length, i + row, h].to_i, @reference_terrain_tag) length2 = j2 + length - list_start2 indicator = true @num_tiles.push([j2 + length, i + row]) length3 = 1 while j2 + length + length3 < $game_map.width && suitable?(@dataV[j2 + length + length3, i + row, h].to_i, @reference_terrain_tag) @num_tiles.push([j2 + length + length3, i + row]) length3 += 1 length2 += 1 if j2 + length + length3 > list_end list_end = j2 + length + length3 end end end if suitable?(@dataV[j2, i + row, h].to_i, @reference_terrain_tag) list_start3 = list_start2 - j2 length2 = length2 + list_start3 list_start2 = j2 indicator = true @num_tiles.push([j2, i + row]) length3 = 1 while j2 - length3 >= 0 && suitable?(@dataV[j2 - length3, i + row, h].to_i, @reference_terrain_tag) @num_tiles.push([j2 - length3, i + row]) length3 += 1 length2 += 1 list_start2 -= 1 list_start = list_start2 if list_start2 < list_start end end length = length2 j2 = list_start2 end row -= 1 # create a bitmap and a sprite from the tiles listed in @num_tiles create_bitmap(i, list_start, row, list_end - list_start, h) # clear the used tiles clear_data(h) # reinitialize the list of tiles @num_tiles = [] end}}} end #-------------------------------------------------------------------------- # * Clear the used data to prevent from reusing them # layer : current scanned layer #-------------------------------------------------------------------------- def clear_data(layer) @num_tiles.each {|num| @dataV[num[0], num[1], layer] = 0} end #-------------------------------------------------------------------------- # * Create a Bitmap from the listed tiles in @num_tiles and its associated # sprite (Sprite_V) # row : start row's value # column : start column's value # height : sprite's height (in tiles) # width : sprite's width (in tiles) # layer : current scanned layer #-------------------------------------------------------------------------- def create_bitmap(row, column, height, width, layer) bmp = Bitmap.new(32*(1+width), 32*(1+height)) rect = Rect.new(0, 0, 32, 32) @num_tiles.sort! {|a, b| -(a[1] - b[1])} sprite = Sprite_V.new(@viewport) # initialize sprite's attributes sprite.animated = false sprite.list_bitmap = [] # draw the bitmap @num_tiles.each {|tile_coordinates| value = @dataV[tile_coordinates[0], tile_coordinates[1], layer].to_i # if tile is a normal tile if value > 383 bitmap = RPG::Cache.tile($game_map.tileset_name, value, 0) else # tile is an autotile file = (value / 48) - 1 num_file = 4 * file if !sprite.animated autotile_name = $game_map.autotile_names[file] fichier = RPG::Cache.autotile(autotile_name) sprite.animated = (fichier.width > 96 ? true : false) end bitmap = RPG::Cache.autotile_base(num_file, value) end bmp.blt(32 * (tile_coordinates[0] - column), 32 * (tile_coordinates[1] - row), bitmap, rect)} sprite.list_bitmap.push(bmp) # create 3 additionnal bitmaps for animated sprites if sprite.animated (1..3).each {|j| bmp = Bitmap.new(32 * (1 + width), 32 * (1 + height)) @num_tiles.each {|tile_coordinates| value = @dataV[tile_coordinates[0], tile_coordinates[1], layer].to_i if value > 383 bitmap = RPG::Cache.tile($game_map.tileset_name, value, 0) else num_file = 4 * ((value / 48) - 1) bitmap = RPG::Cache.autotile_base(num_file + j, value) end bmp.blt(32 * (tile_coordinates[0] - column), 32 * (tile_coordinates[1] - row), bitmap, rect)} sprite.list_bitmap.push(bmp)} end value = @dataV[@num_tiles[0][0], @num_tiles[0][1], layer].to_i # set sprite's priority sprite.priority = $game_map.priorities[value] # set sprite's coordinates (in squares (32 * 32 pixels)) sprite.x_map = (column.to_f) + bmp.width / 64 sprite.x_map += 0.5 if width % 2 == 0 sprite.y_map = (row + height).to_f + 0.5 sprite.square_y = sprite.y_map.to_i # Integer # set the y_pivot (intersection between the map and the sprite) sprite.oy = bmp.height - 16 sprite.ox = bmp.width / 2 sprite.bitmap = sprite.list_bitmap[0] self.list_sprites_V.push(sprite) self.list_sprites_V_animated.push(sprite) if sprite.animated end end #============================================================================ # ■ RPG::Cache_Tile #---------------------------------------------------------------------------- # The tiles resulting in a superimposing of several tiles are kept in memory # for a faster call # valueX : tile's ID #============================================================================ module RPG::Cache_Tile @cache = {} #-------------------------------------------------------------------------- # * Superimposing of two tiles, offset = pattern's number for animated # autotiles #-------------------------------------------------------------------------- def self.load(value1, value2, offset=0) if !@cache.include?([value1, value2, offset]) bitmap = Bitmap.new(32, 32) rect = Rect.new(0, 0, 32, 32) if value1 > 383 # normal tile bitmap.blt(0, 0, RPG::Cache.tile($game_map.tileset_name, value1, 0), rect) else # autotile num = 4*((value1 / 48) - 1) + offset bitmap.blt(0, 0, RPG::Cache.autotile_base(num, value1), rect) end if value2 > 383 # normal tile bitmap.blt(0, 0, RPG::Cache.tile($game_map.tileset_name, value2, 0), rect) else # autotile num = 4*((value2 / 48) - 1) + offset bitmap.blt(0, 0, RPG::Cache.autotile_base(num, value2), rect) end ###@cache[[value1, value2, offset]] = bitmap return bitmap end @cache[[value1, value2, offset]] end #-------------------------------------------------------------------------- # * Superimposing of three tiles #-------------------------------------------------------------------------- def self.load2(value1, value2, value3, offset = 0) if !@cache.include?([value1, value2, value3, offset]) bitmap = Bitmap.new(32, 32) rect = Rect.new(0, 0, 32, 32) if value1 > 383 # normal tile bitmap.blt(0, 0, RPG::Cache.tile($game_map.tileset_name, value1, 0), rect) else # autotile num = 4*((value1 / 48) - 1) + offset bitmap.blt(0, 0, RPG::Cache.autotile_base(num, value1), rect) end if value2 > 383 # normal tile bitmap.blt(0, 0, RPG::Cache.tile($game_map.tileset_name, value2, 0), rect) else # autotile num = 4*((value2 / 48) - 1) + offset bitmap.blt(0, 0, RPG::Cache.autotile_base(num, value2), rect) end if value3 > 383 # normal tile bitmap.blt(0, 0, RPG::Cache.tile($game_map.tileset_name, value3, 0), rect) else # autotile num = 4*((value3 / 48) - 1) + offset bitmap.blt(0, 0, RPG::Cache.autotile_base(num, value3), rect) end ###@cache[[value1, value2, value3, offset]] = bitmap return bitmap end @cache[[value1, value2, value3, offset]] end #-------------------------------------------------------------------------- # * Clear the Cache #-------------------------------------------------------------------------- def self.clear @cache = {} GC.start end end #============================================================================ # ■ RPG::Cache_Carte #---------------------------------------------------------------------------- # Maps drawn with mode7 are kept in memory to have a faster call the next # times they need to be drawn #============================================================================ module RPG::Cache_Carte @cache = {} #-------------------------------------------------------------------------- # * Check if the map is in the Cache # map_id : map's ID #-------------------------------------------------------------------------- def self.in_cache(map_id) return @cache.include?(map_id) end #-------------------------------------------------------------------------- # * Return the map's drawing (Bitmap) # map_id : map's ID # num : pattern's number for animated autotiles #-------------------------------------------------------------------------- def self.load(map_id, num = 0) return @cache[map_id][num] end #-------------------------------------------------------------------------- # * Save the map's drawing in the Cache # map_id : map's ID # bitmap : map's drawing (Bitmap) # num : pattern's number for animated autotiles #-------------------------------------------------------------------------- def self.save(map_id, bitmap, num = 0) @cache[map_id] = [] if !self.in_cache(map_id) @cache[map_id][num] = bitmap end #-------------------------------------------------------------------------- # * Clear the Cache #-------------------------------------------------------------------------- def self.clear @cache = {} GC.start end end #============================================================================ # ■ RPG::Cache #---------------------------------------------------------------------------- # The tiles from autotiles files are kept in memory for a faster call #============================================================================ module RPG::Cache #-------------------------------------------------------------------------- # * Check if the map is in the Cache # num : autotiles file's ID # value : tile's ID #-------------------------------------------------------------------------- def self.autotile_base(num, value) key = [num, value] if !@cache.include?(key) || @cache[key].disposed? @cache[key] = Bitmap.new(32, 32) num_tile = value % 48 sx = 32 * (num_tile % 8) sy = 32 * (num_tile / 8) rect = Rect.new(sx, sy, 32, 32) @cache[key].blt(0, 0, self.load_autotile(num), rect) end @cache[key] end #-------------------------------------------------------------------------- # * Save the tile's drawing in the Cache # bitmap : tile's drawing (Bitmap) # key : tile's ID #-------------------------------------------------------------------------- def self.save_autotile(bitmap, key) @cache[key] = bitmap end #-------------------------------------------------------------------------- # * Return the tile's drawing (Bitmap) # key : tile's ID #-------------------------------------------------------------------------- def self.load_autotile(key) @cache[key] end end #============================================================================ # ■ RPG::MapInfo #============================================================================ class RPG::MapInfo # defines the map's name as the name without anything within brackets, # including brackets def name return @name.gsub(/\[.*\]/) {""} end #-------------------------------------------------------------------------- # the original name with the codes def name2 return @name end end #============================================================================ # ■ Game_Temp #---------------------------------------------------------------------------- # Add attributes to this class / Avoid using too many global variables #============================================================================ class Game_Temp attr_accessor :pivot # screenline's number of the slant's pivot attr_accessor :cos_angle # cosinus of the slant's angle attr_accessor :sin_angle # sinus of the slant's angle attr_accessor :height_limit # horizon's line attr_accessor :distance_h # distance between the map's center and the vanishing point attr_accessor :slope_value # intermediate value attr_accessor :corrective_value # intermediate value attr_accessor :height # map's height (in pixel) #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- alias initialize_mode7_game_temp initialize def initialize initialize_mode7_game_temp self.pivot = 0 self.cos_angle = 0.0 self.sin_angle = 0.0 self.height_limit = 0 self.distance_h = 0 self.slope_value = 0.0 self.corrective_value = 0.0 self.height = 0 end end Any other thoughts? If it is limited to just one template it should be writable to add more. Share this post Link to post Share on other sites
0 SonicBounty50 0 Report post Posted February 26, 2011 Come on you RGSS masters out there! Share this post Link to post Share on other sites
0 Broken Messiah 20 Report post Posted February 26, 2011 By sprites do you mean like npcs or objects? Share this post Link to post Share on other sites
0 SonicBounty50 0 Report post Posted February 26, 2011 By sprites do you mean like npcs or objects? Hmm, seems to be just objects.. Yeah, just objects and stuff I create. No matter what layer I put them on they all seem flat when I play my game. Share this post Link to post Share on other sites
0 Midnite Reaper 2 Report post Posted February 26, 2011 If the 'object' you speak of is from a tileset, you need to change the terrain flag to a 1 or 2. (or at least thats what you do with the version I have) I believe they have a slightly different effect, but have yet to find out what it is. Share this post Link to post Share on other sites
0 SonicBounty50 0 Report post Posted February 26, 2011 If the 'object' you speak of is from a tileset, you need to change the terrain flag to a 1 or 2. (or at least thats what you do with the version I have) I believe they have a slightly different effect, but have yet to find out what it is. Let me try that out. I think that might do it. Share this post Link to post Share on other sites
0 SonicBounty50 0 Report post Posted February 26, 2011 Yes! It is working, thank you very much! =] Share this post Link to post Share on other sites
0 Midnite Reaper 2 Report post Posted February 26, 2011 (edited) You are welcome. The version I have is only very slightly different. Same scripter and version, oddly. Just remember, instead of double posting, please use the 'edit' button down in the lower right corner of your post. Edited February 26, 2011 by Midnite Reaper Share this post Link to post Share on other sites
0 SonicBounty50 0 Report post Posted February 27, 2011 (edited) Does anyone know how to create stairs that work? Or Mountains that work somewhat? Edited February 27, 2011 by SonicBounty50 Share this post Link to post Share on other sites
0 SonicBounty50 0 Report post Posted February 27, 2011 bump! Share this post Link to post Share on other sites
0 Midnite Reaper 2 Report post Posted February 27, 2011 Please wait 72 hours before bumping. Share this post Link to post Share on other sites
0 SonicBounty50 0 Report post Posted February 27, 2011 Please wait 72 hours before bumping. Stay on topic! ;D Just joking.. Got it. Do you know how to fix it? Share this post Link to post Share on other sites
0 Midnite Reaper 2 Report post Posted February 27, 2011 Not this time, I'm afraid. I never used mode7 because I never found a workaround for this... Share this post Link to post Share on other sites
0 Dark Den 4 Report post Posted February 27, 2011 What happens when u try to walk on the stairs/mountains ? Share this post Link to post Share on other sites
0 Fateofdawn 0 Report post Posted February 27, 2011 What happens when u try to walk on the stairs/mountains ? mode 7 is one of the hardest scrips 2 work with i tried it but i lost motivation for it. Share this post Link to post Share on other sites
0 SonicBounty50 0 Report post Posted March 2, 2011 What happens when u try to walk on the stairs/mountains ? I walk right through them. Quite disappointing. =/ Share this post Link to post Share on other sites
I am not a noob with RPG Maker XP at all, but I just started using Mode 7 script and I am lost on how to make my sprites on my maps vertical. Could anyone help me? They all come out flat. It must be something very easy.
Thank you,
Share this post
Link to post
Share on other sites