#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=: # [VX-A] XP Map Loader # Version: 1.16 # Author : LiTTleDRAgo #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=: ($imported ||= {})[:drg_xp_map_loader] = 1.16 #============================================================================== # ** Game_Map #------------------------------------------------------------------------------ # This class handles maps. It includes scrolling and passage determination # functions. The instance of this class is referenced by $game_map. #============================================================================== class Game_Map #-------------------------------------------------------------------------- # * Public Instance Variables #-------------------------------------------------------------------------- attr_accessor :tileset_name # tileset file name attr_accessor :autotile_names # autotile file name attr_accessor :panorama_name # panorama file name attr_accessor :panorama_hue # panorama hue attr_accessor :fog_name # fog file name attr_accessor :fog_hue # fog hue attr_accessor :fog_opacity # fog opacity level attr_accessor :fog_blend_type # fog blending method attr_accessor :fog_zoom # fog zoom rate attr_accessor :fog_sx # fog sx attr_accessor :fog_sy # fog sy attr_accessor :battleback_name # battleback file name attr_reader :tileset_id # tileset id attr_reader :passages # passage table attr_reader :priorities # priority table attr_reader :terrain_tags # terrain tag table attr_reader :fog_ox # fog x-coordinate starting point attr_reader :fog_oy # fog y-coordinate starting point attr_reader :fog_tone # fog color tone attr_reader :map_type #-------------------------------------------------------------------------- # * Constant #-------------------------------------------------------------------------- VXA = defined?(Window_BattleActor) #-------------------------------------------------------------------------- # * Alias Method #-------------------------------------------------------------------------- alias game_map_vxaxp_update update alias game_map_vxaxp_passable passable? alias game_map_vxaxp_bush bush? alias game_map_vxaxp_counter counter? alias game_map_vxaxp_refresh_vehicles referesh_vehicles alias game_map_vxaxp_terrain_tag terrain_tag if method_defined?(:terrain_tag) #-------------------------------------------------------------------------- # * Aliased Method : referesh_vehicles #-------------------------------------------------------------------------- def referesh_vehicles decide_map_type decide_map_layer game_map_vxaxp_refresh_vehicles end #-------------------------------------------------------------------------- # * New Method : decide_xpvx_map #-------------------------------------------------------------------------- def decide_map_type map = sprintf("Map%03d", @map_id) ext = VXA ? 'rvdata2' : 'rvdata' if File.exist?("Data/#{map}.#{:rxdata}") $data_tilesets_xp = load_data("Data/Tilesets.#{:rxdata}") @map = load_map_data(@map_id) @mapxp_data = load_map_data(@map_id,:rxdata) @map_type = 'XP' mapsize = [@map,@mapxp_data].collect {|m| [m.width,m.height]} if mapsize.uniq.size > 1 raise "The dimension on #{map}.rxdata #{mapsize[0].inspect} \n"+ "and #{map}.#{ext} #{mapsize[1].inspect} is not same" end @tilesetxp_id = @mapxp_data.tileset_id @tileset_name = tileset_xp.tileset_name @autotile_names = tileset_xp.autotile_names @panorama_name = tileset_xp.panorama_name @panorama_hue = tileset_xp.panorama_hue @fog_name = tileset_xp.fog_name @fog_hue = tileset_xp.fog_hue @fog_opacity = tileset_xp.fog_opacity @fog_blend_type = tileset_xp.fog_blend_type @fog_zoom = tileset_xp.fog_zoom @fog_sx = tileset_xp.fog_sx @fog_sy = tileset_xp.fog_sy @battleback_name = tileset_xp.battleback_name @passages = tileset_xp.passages @priorities = tileset_xp.priorities @terrain_tags = tileset_xp.terrain_tags if ext == 'rvdata2' tileset_xp.tileset_names = tileset.tileset_names tileset_xp.flags = tileset.flags tileset_xp.mode = tileset.mode tileset_xp.note = tileset.note end else @map = load_map_data(@map_id) @mapxp_data = @map @map_type = 'VX' @tileset_name = '' @autotile_names = ['']*7 @battleback_name = '' @passages = Table.new(384) if ext == 'rvdata2' @priorities = Table.new(384) @terrain_tags = Table.new(384) clear_panorama clear_fog end reset_fog_variable end #-------------------------------------------------------------------------- # * New Method : decide_map_layer #-------------------------------------------------------------------------- def decide_map_layer(*args) return if ($imported[:drg_core_engine]||0) < 1.16 map_name = mapInfo[$game_map.map_id].name child_ids.each do |submap_id| map_info = mapInfo[submap_id] unless map_info.nil? if map_info.parent_id == map_id && map_info.name.include?("[" + 'join' + "]") then ext = VXA ? 'rvdata2' : 'rvdata' map = sprintf("Data/Map%03d.rxdata", submap_id) if @map_type == 'XP' map = sprintf("Data/Map%03d.#{ext}", submap_id) if @map_type == 'VX' unless File.exist?("#{map}") msgbox "File #{map} doesn't exist" next end submap = load_data(map) old_zsize = data.zsize data.resize(data.xsize, data.ysize, old_zsize + 3) for x in 0...data.xsize for y in 0...data.ysize data[x, y, old_zsize] = submap.data[x, y, 0] data[x, y, old_zsize + 1] = submap.data[x, y, 1] data[x, y, old_zsize + 2] = submap.data[x, y, 2] end end end end end end #-------------------------------------------------------------------------- # * Aliased Method : passable? #-------------------------------------------------------------------------- def passable?(x, y, d, self_event = nil) return game_map_vxaxp_passable(x,y,d) if @map_type == 'VX' return false unless valid?(x, y) bit = (1 << (d / 2 - 1)) & 0x0f tile = tile_events_xy(x, y).select {|e| e != self_event } tile.collect {|ev| ev.tile_id }.each do |tile_id| flag = tileset.flags[tile_id] if flag & bit != 0 return false elsif flag & 0x0f == 0x0f return false elsif @priorities[tile_id] == 0 return true end end z_data.each do |i| tile_id = data[x, y, i] 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 end return true end #-------------------------------------------------------------------------- # * Aliased Method : bush? #-------------------------------------------------------------------------- def bush?(x, y) return game_map_vxaxp_bush(x,y) if @map_type == 'VX' if @map_id != 0 for i in z_data tile_id = data[x, y, i] if tile_id == nil || @passages.nil? return false elsif @passages[tile_id] & 0x40 == 0x40 return true end end end return false end #-------------------------------------------------------------------------- # * Aliased Method : counter? #-------------------------------------------------------------------------- def counter?(x, y) return game_map_vxaxp_counter(x,y) if @map_type == 'VX' if @map_id != 0 for i in z_data tile_id = data[x, y, i] if tile_id == nil || @passages.nil? return false elsif @passages[tile_id] & 0x80 == 0x80 return true end end end return false end #-------------------------------------------------------------------------- # * Aliased Method : terrain_tag #-------------------------------------------------------------------------- def terrain_tag(x, y) return game_map_vxaxp_terrain_tag(x,y) if @map_type == 'VX' if @map_id != 0 for i in z_data tile_id = data[x, y, i] if tile_id == nil || @terrain_tags.nil? return 0 elsif @terrain_tags[tile_id] > 0 return @terrain_tags[tile_id] end end end return 0 end #-------------------------------------------------------------------------- # * Overwriten Method : data #-------------------------------------------------------------------------- def data if @map_type == 'VX' @map.data else @mapxp_data.data end end #-------------------------------------------------------------------------- # * Overwriten Method : layered_tiles #-------------------------------------------------------------------------- def layered_tiles(x, y) #msgbox z_data _z_data = z_data.reject {|s| s == 3 } _z_data.collect {|z| tile_id(x, y, z) } end #-------------------------------------------------------------------------- # * Overwriten Method : change_tileset #-------------------------------------------------------------------------- def change_tileset(tileset_id) if @map_type == 'VX' @tileset_id = tileset_id elsif @map_type == 'XP' @tilesetxp_id = tileset_id @tileset_name = tileset.tileset_name @autotile_names = tileset.autotile_names end refresh end #-------------------------------------------------------------------------- # ● New method: load_map_data #-------------------------------------------------------------------------- unless method_defined?(:load_map_data) def load_map_data(mapid, ext = nil) if ext.nil? || ext.empty? ext = :rxdata ext = :rvdata if LiTTleDRAgo::VX ext = :rvdata2 if LiTTleDRAgo::VXA end map = sprintf("Data/Map%03d.#{ext}", mapid) load_data(map) end end #-------------------------------------------------------------------------- # * New Method : z_data #-------------------------------------------------------------------------- unless method_defined?(:z_data) def z_data (0...data.zsize).to_a.reverse end end #-------------------------------------------------------------------------- # * Aliased Method : update #-------------------------------------------------------------------------- def update(*args) game_map_vxaxp_update(*args) update_fog end #-------------------------------------------------------------------------- # * Get Array of Tile-Handling Events at Designated Coordinates # (Except Pass-Through) #-------------------------------------------------------------------------- unless method_defined?(:tile_events_xy) def tile_events_xy(x, y) tile_event = @events.values.select {|event| event.tile? } tile_event.select {|event| event.pos_nt?(x, y) } end end #-------------------------------------------------------------------------- # * New Method : tileset_xp #-------------------------------------------------------------------------- def tileset_xp decide_map_type if @tilesetxp_id.nil? || $data_tilesets_xp.nil? $data_tilesets_xp[@tilesetxp_id] end #-------------------------------------------------------------------------- # * New Method : decide_xpvx_map #-------------------------------------------------------------------------- def decide_map_type map = sprintf("Map%03d", @map_id) ext = VXA ? 'rvdata2' : 'rvdata' if File.exist?("Data/#{map}.rxdata") $data_tilesets_xp = load_data("Data/Tilesets.rxdata") @map = load_data("Data/#{map}.#{ext}") @mapxp_data = load_data("Data/#{map}.rxdata") @map_type = 'XP' mapsize = [@map,@mapxp_data].collect {|m| [m.width,m.height]} if mapsize.uniq.size > 1 raise "The dimension on #{map}.rxdata #{mapsize[0].inspect} \n"+ "and #{map}.#{ext} #{mapsize[1].inspect} is not same" end @tilesetxp_id = @mapxp_data.tileset_id @tileset_name = tileset_xp.tileset_name @autotile_names = tileset_xp.autotile_names @panorama_name = tileset_xp.panorama_name @panorama_hue = tileset_xp.panorama_hue @fog_name = tileset_xp.fog_name @fog_hue = tileset_xp.fog_hue @fog_opacity = tileset_xp.fog_opacity @fog_blend_type = tileset_xp.fog_blend_type @fog_zoom = tileset_xp.fog_zoom @fog_sx = tileset_xp.fog_sx @fog_sy = tileset_xp.fog_sy @battleback_name = tileset_xp.battleback_name @passages = tileset_xp.passages @priorities = tileset_xp.priorities @terrain_tags = tileset_xp.terrain_tags if ext == 'rvdata2' tileset_xp.tileset_names = tileset.tileset_names tileset_xp.flags = tileset.flags tileset_xp.mode = tileset.mode tileset_xp.note = tileset.note end else @map = load_data("Data/#{map}.#{ext}") @mapxp_data = @map @map_type = 'VX' @tileset_name = '' @autotile_names = ['']*7 @battleback_name = '' @passages = Table.new(384) if ext == 'rvdata2' @priorities = Table.new(384) @terrain_tags = Table.new(384) clear_panorama clear_fog end reset_fog_variable end #-------------------------------------------------------------------------- # * New Method : reset_fog_variable #-------------------------------------------------------------------------- def reset_fog_variable @fog_ox = 0 @fog_oy = 0 @fog_tone = Tone.new(0, 0, 0, 0) @fog_tone_target = Tone.new(0, 0, 0, 0) @fog_tone_duration = 0 @fog_opacity_duration = 0 @fog_opacity_target = 0 end #-------------------------------------------------------------------------- # * New Method : start_fog_tone_change #-------------------------------------------------------------------------- def start_fog_tone_change(tone, duration) @fog_tone_target = tone.clone @fog_tone_duration = duration if @fog_tone_duration == 0 @fog_tone = @fog_tone_target.clone end end #-------------------------------------------------------------------------- # * New Method : start_fog_opacity_chang #-------------------------------------------------------------------------- def start_fog_opacity_change(opacity, duration) @fog_opacity_target = opacity * 1.0 @fog_opacity_duration = duration if @fog_opacity_duration == 0 @fog_opacity = @fog_opacity_target end end #-------------------------------------------------------------------------- # * New Method : change_panorama #-------------------------------------------------------------------------- def change_panorama(panorama_name = '',panorama_hue = 0) @panorama_name = panorama_name @panorama_hue = panorama_hue end #-------------------------------------------------------------------------- # * New Method : clear_panorama #-------------------------------------------------------------------------- def clear_panorama(*args) change_panorama end #-------------------------------------------------------------------------- # * New Method : change_fog #-------------------------------------------------------------------------- def change_fog(fog_name = '',fog_hue = 0,fog_opacity = 60, fog_blend_type = 0,fog_zoom = 1.0,fog_sx = 0,fog_sy = 0) @fog_name = fog_name @fog_hue = fog_hue @fog_opacity = fog_opacity @fog_blend_type = fog_blend_type @fog_zoom = fog_zoom @fog_sx = fog_sx @fog_sy = fog_sy end #-------------------------------------------------------------------------- # * New Method : clear_fog #-------------------------------------------------------------------------- def clear_fog(*args) change_fog end #-------------------------------------------------------------------------- # * New Method : update_fog #-------------------------------------------------------------------------- def update_fog return reset_fog_variable if @fog_ox.nil? @fog_ox -= @fog_sx / 8.0 @fog_oy -= @fog_sy / 8.0 if @fog_tone_duration >= 1 d = @fog_tone_duration target = @fog_tone_target @fog_tone.red = (@fog_tone.red * (d - 1) + target.red) / d @fog_tone.green = (@fog_tone.green * (d - 1) + target.green) / d @fog_tone.blue = (@fog_tone.blue * (d - 1) + target.blue) / d @fog_tone.gray = (@fog_tone.gray * (d - 1) + target.gray) / d @fog_tone_duration -= 1 end if @fog_opacity_duration >= 1 d = @fog_opacity_duration @fog_opacity = (@fog_opacity * (d - 1) + @fog_opacity_target) / d @fog_opacity_duration -= 1 end end end #============================================================================== # ** Game_Character #------------------------------------------------------------------------------ # A character class with mainly movement route and other such processing # added. It is used as a super class of Game_Player, Game_Follower, # GameVehicle, and Game_Event. #============================================================================== class Game_Character #-------------------------------------------------------------------------- # * Overwriten Method : map_passable? #-------------------------------------------------------------------------- def map_passable?(*args) args << 0 if args.size == 2 && $game_map.map_type == 'XP' test = $game_map.passable?(*args) end #-------------------------------------------------------------------------- # * Determine Tile #-------------------------------------------------------------------------- unless method_defined?(:tile?) def tile? @tile_id > 0 && @priority_type == 0 end end #-------------------------------------------------------------------------- # * Aliased Method: screen_z #-------------------------------------------------------------------------- alias map_xp_screen_z screen_z def screen_z result = map_xp_screen_z # result += 156 if $game_map.map_type == 'XP' return result end end #============================================================================== # ** Game_Player #------------------------------------------------------------------------------ # This class handles the player. It includes event starting determinants and # map scrolling functions. The instance of this class is referenced by # $game_player. #============================================================================== class Game_Player < Game_Character #-------------------------------------------------------------------------- # * Alias Method #-------------------------------------------------------------------------- alias xploader_map_passable map_passable? #-------------------------------------------------------------------------- # * Determine if Map is Passable # d: Direction (2,4,6,8) #-------------------------------------------------------------------------- def map_passable?(*args) if !Game_Map::VXA && $game_map.map_type == 'XP' && ![0,1,2].include?(@vehicle_type) return super(*args) end xploader_map_passable(*args) end end #============================================================================== # ** Spriteset_Map #------------------------------------------------------------------------------ # This class brings together map screen sprites, tilemaps, etc. It's used # within the Scene_Map class. #============================================================================== class Spriteset_Map #-------------------------------------------------------------------------- # * Public Instance Variables #-------------------------------------------------------------------------- attr_reader :tilemap, :viewport1 #-------------------------------------------------------------------------- # * Constant Variables #-------------------------------------------------------------------------- @@ltileset_exist = method_defined?(:load_tileset) #-------------------------------------------------------------------------- # * Alias Method #-------------------------------------------------------------------------- alias spriteset_map_vxaxp_create_tilemap create_tilemap alias spriteset_map_vxaxp_dispose_tilemap dispose_tilemap alias spriteset_map_vxaxp_dispose_viewports dispose_viewports alias spriteset_map_vxaxp_update_tilemap update_tilemap alias spriteset_map_vxaxp_update_tileset update_tileset if @@ltileset_exist alias spriteset_map_vxaxp_load_tileset load_tileset if @@ltileset_exist #-------------------------------------------------------------------------- # * Aliased Method : create_tilemap #-------------------------------------------------------------------------- def create_tilemap @map_type = $game_map.map_type if @map_type == 'VX' spriteset_map_vxaxp_create_tilemap else if $game_temp.tilemap == nil load_tileset else @tilemap = $game_temp.tilemap.clone @viewport1.dispose if !@viewport1.nil? @viewport1 = @tilemap.viewport $game_temp.tilemap = nil end end end #-------------------------------------------------------------------------- # * Aliased Method : load_tileset #-------------------------------------------------------------------------- def load_tileset if @map_type == 'VX' spriteset_map_vxaxp_load_tileset if @@ltileset_exist else @tilemap.dispose if @tilemap autotiles = [] for i in 0..6 autotile_name = $game_map.autotile_names[i].dup autotiles << Cache.autotile(autotile_name) end tileset = Cache.tileset($game_map.tileset_name) @tilemap = Tilemap_New.new(@viewport1,tileset,autotiles) update_tilemap_position @tilemap.update_all end end #-------------------------------------------------------------------------- # * Aliased Method : dispose_tilemap #-------------------------------------------------------------------------- def dispose_tilemap if @map_type == 'VX' spriteset_map_vxaxp_dispose_tilemap else @tilemap.tileset.dispose @tilemap.autotiles.compact.each {|autotile| autotile.dispose } if $game_temp.store_tilemap == true $game_temp.tilemap = @tilemap.clone $game_temp.store_tilemap = false else @tilemap.dispose @viewport1.dispose end end dispose_fog dispose_panorama end #-------------------------------------------------------------------------- # * Aliased Method : dispose_viewports #-------------------------------------------------------------------------- def dispose_viewports if @map_type == 'VX' spriteset_map_vxaxp_dispose_viewports else @viewport2.dispose @viewport3.dispose end end #-------------------------------------------------------------------------- # * Aliased Method : update_tileset #-------------------------------------------------------------------------- def update_tileset if @map_type == 'VX' spriteset_map_vxaxp_update_tileset elsif @map_id != $game_map.map_id @map_id = $game_map.map_id load_tileset refresh_characters end end #-------------------------------------------------------------------------- # * Aliased Method : update_tilemap #-------------------------------------------------------------------------- def update_tilemap if @map_type == 'VX' spriteset_map_vxaxp_update_tilemap end if @map_type != 'VX' update_tilemap_position @tilemap.update end update_panorama update_fog end #-------------------------------------------------------------------------- # * New Method : update_tilemap_position #-------------------------------------------------------------------------- def update_tilemap_position @tilemap.ox = $game_map.display_x / 4 @tilemap.oy = $game_map.display_y / 4 @tilemap.ox = $game_map.display_x / 8 @tilemap.oy = $game_map.display_y / 8 @tilemap.ox = $game_map.display_x * 32 if Game_Map::VXA @tilemap.oy = $game_map.display_y * 32 if Game_Map::VXA end #-------------------------------------------------------------------------- # * New Method : create_fog #-------------------------------------------------------------------------- def create_fog @fog = Plane.new(@viewport1) @fog.z = 3000 end #-------------------------------------------------------------------------- # * New Method : create_panorama #-------------------------------------------------------------------------- def create_panorama @panorama = Plane.new(@viewport1) @panorama.z = -1000 end #-------------------------------------------------------------------------- # * New Method : dispose_fog #-------------------------------------------------------------------------- def dispose_fog @fog.dispose if !@fog.nil? && !@fog.disposed? end #-------------------------------------------------------------------------- # * New Method : dispose_panorama #-------------------------------------------------------------------------- def dispose_panorama @panorama.dispose if !@panorama.nil? && !@panorama.disposed? end #-------------------------------------------------------------------------- # * New Method : update_panorama #-------------------------------------------------------------------------- def update_panorama if @panorama_name != $game_map.panorama_name or @panorama_hue != $game_map.panorama_hue or @panorama.nil? @panorama_name = $game_map.panorama_name @panorama_hue = $game_map.panorama_hue dispose_panorama create_panorama if @panorama_name != "" @panorama.bitmap = Cache.panorama(@panorama_name, @panorama_hue) end Graphics.frame_reset end return if @panorama_name == '' disp_x = $game_map.display_x / 4 disp_y = $game_map.display_y / 4 disp_x = $game_map.display_x / 8 disp_y = $game_map.display_y / 8 disp_x = $game_map.display_x * 32 if Game_Map::VXA disp_y = $game_map.display_y * 32 if Game_Map::VXA @panorama.ox = $game_map.display_x / 8 @panorama.oy = $game_map.display_y / 8 end #-------------------------------------------------------------------------- # * New Method : update_fog #-------------------------------------------------------------------------- def update_fog if @fog_name != $game_map.fog_name or @fog_hue != $game_map.fog_hue or @fog.nil? @fog_name = $game_map.fog_name @fog_hue = $game_map.fog_hue dispose_fog create_fog if @fog_name != "" @fog.bitmap = Cache.fog(@fog_name, @fog_hue) end Graphics.frame_reset end return if @fog_name == '' zoom = $game_map.fog_zoom zoom /= 100 if zoom.is_a?(Integer) @fog.zoom_x = zoom @fog.zoom_y = zoom @fog.opacity = $game_map.fog_opacity @fog.blend_type = $game_map.fog_blend_type disp_x = $game_map.display_x / 4 disp_y = $game_map.display_y / 4 disp_x = $game_map.display_x / 8 disp_y = $game_map.display_y / 8 disp_x = $game_map.display_x * 32 if Game_Map::VXA disp_y = $game_map.display_y * 32 if Game_Map::VXA @fog.ox = disp_x + $game_map.fog_ox @fog.oy = disp_y + $game_map.fog_oy @fog.tone = $game_map.fog_tone end end #============================================================================== # ** Game_Temp EDIT #------------------------------------------------------------------------------ # Addon for saving the tilemap upon switching scene. #============================================================================== class Game_Temp #-------------------------------------------------------------------------- # * Public Instance Variable #-------------------------------------------------------------------------- attr_accessor :store_tilemap attr_accessor :tilemap #-------------------------------------------------------------------------- # * Alias Initialize EDIT (flag & slot for temporarily storing the tilemap) #-------------------------------------------------------------------------- alias init_later initialize #-------------------------------------------------------------------------- # * Initialize #-------------------------------------------------------------------------- def initialize init_later setup_map_type_change end #-------------------------------------------------------------------------- # * setup_map_type_change #-------------------------------------------------------------------------- def setup_map_type_change @store_tilemap = false # Storage flag @tilemap = nil # Storage slot end end #============================================================================== # ** Game_Map EDIT (extra) #------------------------------------------------------------------------------ # Enhances the class Game_Map in order to presort tiles by priority; used for # tilemap tone. #============================================================================== class Game_Map #-------------------------------------------------------------------------- # * Public Instance Variables #-------------------------------------------------------------------------- attr_reader :map # Map-Daten attr_reader :tone # Color-Tone attr_accessor :need_redraw #-------------------------------------------------------------------------- # * Alias Method #-------------------------------------------------------------------------- alias init_later initialize alias setup_later setup alias upd_later update #-------------------------------------------------------------------------- # * Aliased Method : initialize #-------------------------------------------------------------------------- def initialize init_later @tone = Tone.new(0,0,0,0) # Tilemap-tone @tone_duration = 0 # Tone-duration @need_redraw = false end #-------------------------------------------------------------------------- # * Aliased Method : setup #-------------------------------------------------------------------------- def setup(map_id) setup_later(map_id) sort_priority # Sort tiles after setup end #-------------------------------------------------------------------------- # * Aliased Method : update (executes tone change) #-------------------------------------------------------------------------- def update(*args) update_tone_change upd_later(*args) update_need_redraw end #-------------------------------------------------------------------------- # * New Method : update_tone_change #-------------------------------------------------------------------------- def update_tone_change if @tone_duration && @tone_duration >= 1 d = @tone_duration @tone.red = (@tone.red * (d - 1) + @tone_target.red) / d @tone.green = (@tone.green * (d - 1) + @tone_target.green) / d @tone.blue = (@tone.blue * (d - 1) + @tone_target.blue) / d @tone.gray = (@tone.gray * (d - 1) + @tone_target.gray) / d @tone_duration -= 1 end end #-------------------------------------------------------------------------- # * New Method : update_need_redraw #-------------------------------------------------------------------------- def update_need_redraw if @need_redraw && SceneManager.scene.is_a?(Scene_Map) sort_priority SceneManager.scene.load_tileset @need_redraw = false end end #-------------------------------------------------------------------------- # * New Method : sort_priority #-------------------------------------------------------------------------- def sort_priority # One hash for every priority @priority0 = {} @priority1 = {} @priority2 = {} @priority3 = {} @priority4 = {} @priority5 = {} # Iterate through tiles on x-axis for x in 0...width # Iterate through tiles on y-axis for y in 0...height # Check layers from map editor top->bottom for z in $game_map.z_data#[2,1,0] # Tile ID tile = data[x,y,z] || 0 # If tile is not empty if tile != 0 # Get & check priority for tile, set in according hash case @priorities[tile] when 0 @priority0[y] = {} if @priority0[y] == nil @priority0[y][x] = {} if @priority0[y][x] == nil @priority0[y][x][z] = tile when 1 @priority1[y] = {} if @priority1[y] == nil @priority1[y][x] = {} if @priority1[y][x] == nil @priority1[y][x][z] = tile when 2 @priority2[y] = {} if @priority2[y] == nil @priority2[y][x] = {} if @priority2[y][x] == nil @priority2[y][x][z] = tile when 3 @priority3[y] = {} if @priority3[y] == nil @priority3[y][x] = {} if @priority3[y][x] == nil @priority3[y][x][z] = tile when 4 @priority4[y] = {} if @priority4[y] == nil @priority4[y][x] = {} if @priority4[y][x] == nil @priority4[y][x][z] = tile when 5 @priority5[y] = {} if @priority5[y] == nil @priority5[y][x] = {} if @priority5[y][x] == nil @priority5[y][x][z] = tile end end end end end end #-------------------------------------------------------------------------- # * New Method : priority_data #-------------------------------------------------------------------------- def priority_data(priority) # Check priority and return appropriate sorted hash case priority when 0 return @priority0 when 1 return @priority1 when 2 return @priority2 when 3 return @priority3 when 4 return @priority4 when 5 return @priority5 else # Invalid priority: return hash 0 return @priority0 end end #-------------------------------------------------------------------------- # * New Method : start_tone_change #-------------------------------------------------------------------------- def start_tone_change(tone, duration) @tone_target = tone.clone @tone_duration = duration if @tone_duration == 0 @tone = @tone_target.clone end end #-------------------------------------------------------------------------- # * New Method : change_tile #-------------------------------------------------------------------------- def change_tile(x,y,i,new_tile) return if data[x,y,i] == new_tile data[x,y,i] = new_tile @need_redraw = true end end #============================================================================== # ** Scene_Map #------------------------------------------------------------------------------ # This class performs the map screen processing. #============================================================================== class Scene_Map < Scene_Base #-------------------------------------------------------------------------- # * Constant #-------------------------------------------------------------------------- @@post_transfer = method_defined?(:post_transfer) #-------------------------------------------------------------------------- # * Alias Method #-------------------------------------------------------------------------- alias spriteset_switch_terminate terminate alias spriteset_switch_post_transfer post_transfer if @@post_transfer alias spriteset_switch_pre_transfer pre_transfer if @@post_transfer alias spriteset_switch_pre_transfer update_transfer_player if !@@post_transfer #-------------------------------------------------------------------------- # * Aliased Method : update_transfer_player #-------------------------------------------------------------------------- if !@@post_transfer def update_transfer_player return unless $game_player.transfer? pre_transfer end end #-------------------------------------------------------------------------- # * Aliased Method : terminate #-------------------------------------------------------------------------- def terminate $game_temp.store_tilemap = true spriteset_switch_terminate end #-------------------------------------------------------------------------- # * Aliased Method : pre_transfer #-------------------------------------------------------------------------- def pre_transfer if @new_map_id == $game_map.map_id $game_temp.store_tilemap = true end @map_type = $game_map.map_type spriteset_switch_pre_transfer end #-------------------------------------------------------------------------- # * Aliased Method : post_transfer #-------------------------------------------------------------------------- def post_transfer if @map_type != $game_map.map_type dispose_spriteset create_spriteset @map_type = $game_map.map_type end spriteset_switch_post_transfer end #-------------------------------------------------------------------------- # * New Method : load_tileset #-------------------------------------------------------------------------- def load_tileset @spriteset.load_tileset end end #============================================================================ # ** Tilemap Enchance v.0.75 (RGSS3 Version) #============================================================================ # # HEAVILY EDITED !!!!! # # # This script serves as a complete standard tilemap class replacement and # enables you to access single layers. It's got some new special features # as well. # Basically the script works flawlessly, something that can't be said of most # other tilemap rewrites. # # 1. Installation # # Paste the script above main but below the standard scripts. # # 2. Functional Principle # # Upon entering a map the script loads the new class Tilemap_New instead of Tilemap. # A sprite with bitmap is created for every row of the map in y (from 0 to the # bottom). There's an additional distinction between the single priority settings and # tiles/autotiles. So the tiles are pre-cached and not drawn new during the game. # This requires lots of RAM and increases the maps' load times slightly but improves # performance as well! # # 3. Benefit # # You can directly modify the display process of tiles now, or modify the tile # graphics themselves. Three built-in features are: # Blend types for autotiles (normal, add, sub; useful for certain water/light effects) # Changeable animation speed of autotiles as well as a color tone for the tilemap alone. # Other purposes would be a screen size script. My tilemap class is especially suited # for those due to the performance not diminishing at higher resolutions, or just # marginally. # # 4. Usage # # The script is automatically used after inserting it, however special # features need to be activated seperately: # # - Autotile blend_type/speed: # Configuration via the module Autotile below this introduction. # Possible values for blend_type are 0 (normal), 1 (add), 2 (sub), for # speed every integer can be used. Small numbers mean faster animation # (0 = each frame). # Configuration like so: MAP_ID=>{AUTOTILE_ID=>BLEND_TYPE/BLEND_SPEED} in the # respective section BLEND_TYPE respectively SPEED. Examples are given. # ID goes from 0 to 6 (left to right in the tileset). # # DEFAULT_SPEED is the speed used in case SPEED doesn't contain a value for a map # or an autotile. # # - Tilemap-Tone: # Can be accessed via Call Script or in a script. Use this command: # # $game_map.start_tone_change(tone,duration) # # Whereas tone = Tone.new(r,g,b,gr). This tone affects tiles and autotiles only, # screen color tone can still be added seperately. # # 5. Restrictions # # - Post hoc changes of tile data in the script doesn't have an effect # in this version yet (e.g. via $game_map.data) # # - High memory consumption. Depending on the map size and usage of autotiles # the memory needed can add up to 800 MB. (200*200 map, 1 layer filled with # normal tiles, 1 layer filled with 4 frames autotile) # Realistic footprint accounts to 500 MB max, 512 MB RAM recommended for maps # bigger than 100*100! # # - Increased loading time. Depending on the map size and usage of autotiles # loading time ranges from 0 to 6 seconds. Small maps (30*30) are loaded # instantly, 60*60 with autotiles ca. 1 second, 100*100 with autotiles 2 seconds, # 200*200 map, 1 layer filled with normal tiles, 1 layer filled with 4 frames # autotiles 6 seconds. # # - A teleport to the current map leads to a graphical glitch. # # 6. Pros # # - Full access to all sprites on a map # - Autotile Blend_types and variable speed # - Autotile-Blend_types und variable Geschwindigkeit # - Great performance at memory's cost # - Full functionality (see Restrictions for exceptions) # - Lag doesn't increase when using higher resolutions # # # 7. Credits # # Credits to GodLike for the Cache extension # English translation by Terv (that's me!) # Feel free to use and modify as you like, however be sure to give credit. # # 8. Changelog # # V 0.75: # # - Compatibility for RGSS3 added # - Load time slightly decreased # - General performance improved # - Small display errors caused by specific autotile combinations fixed # # 9. Contact # # Questions, ideas, bug reports? Please drop me an email: admin@envile-media.at # # #============================================================================ #============================================================================== # ** Module Autotile #------------------------------------------------------------------------------ # # This module contains autotile configurations. # #============================================================================== module AUTOTILE # MAP_ID => { AUTOTILE_ID => BLEND_TYPE,.. } BLEND_TYPE = { 4=>{5=>1,6=>2}, } # MAP_ID => { AUTOTILE_ID => SPEED,.. } SPEED = { 4=>{4=>2}, } # DEFAULT_SPEED DEFAULT_SPEED = 4 end #============================================================================== # ** Sprite_Auto NEW #------------------------------------------------------------------------------ # # This class manages autotiles layers. Every layer contains multiple sprites, # one for each autotile column. Furthermore generates respective bitmaps for # the layer. # #============================================================================== class Sprite_Auto #-------------------------------------------------------------------------- # * Public Instance Variables #-------------------------------------------------------------------------- attr_reader :cache2 #-------------------------------------------------------------------------- # * Initialize (read tiles, create sprites & bitmaps) #-------------------------------------------------------------------------- def initialize(viewport,tiles,speed,autotile_frames,priority,blend_type) # Store autotile data @tiles = tiles @tileset_id = $game_map.tileset_id @tileset = Cache.tileset($game_map.tileset_name) @speed = speed @priority = priority @autotile_frames = autotile_frames @frames = autotile_frames[tiles[0]] @priorities = $game_map.priorities @blend_type = blend_type @viewport = viewport # Animation variables @time = 0 @state = -1 # Get number of tiles on x/y axis @width = $game_map.width @height = $game_map.height # Set layer border variables to l<->r and u<->d (changed max/min values) @border_lx = @width @border_ty = @height @border_rx = 0 @border_by = 0 # Set row borders @border_lx_row = @width @border_rx_row = 0 # Create table for row borders @rows = Table.new(@height,2) # Hash for sprites & cache @sprites = {} @cache = {} @cache2 = {} # If special blend_type if @blend_type != 0 # Setup tiles accordingly setup_tiles_blend # Else: normal blendig else # Setup tiles setup_tiles end # Return if not valid return if !valid? # Otherwise, create sprites & bitmaps create_sprites # If special blend_type if @blend_type != 0 # Draw blended tiles draw_tiles_blend else # Draw tiles draw_tiles end @tileset = nil end #-------------------------------------------------------------------------- # * Valid? (checks whether found in tiles for this layer) #-------------------------------------------------------------------------- def valid? # If right border greater or equal to left border and # top border greater or equal to bottom border then true return @border_rx >= @border_lx && @border_by >= @border_ty end #-------------------------------------------------------------------------- # * Row_valid? (checks whether found in tiles in column y) #-------------------------------------------------------------------------- def row_valid?(y) # If right border of row equal or greater to left border of row # then true return @rows[y,1] > @rows[y,0] end #-------------------------------------------------------------------------- # * Setup_tiles_blend (reads tiles for this layer and defines the borders. # Makes use of special rules for reading) #-------------------------------------------------------------------------- def setup_tiles_blend # Get pre-sorted tile data with priority of the layer @data_link = $game_map.priority_data(@priority) # Clone hashs, needed for functionally interation while deleting stuff # from the data @data = @data_link.dup @data_link.each_pair do |dx,data_x| dat_x = @data[dx] dat_x = data_x.dup data_x.each_pair do |dz,data_z| dat_x[dz] = data_z.dup end end tiles_found = false layer = 0 # Iterate through sorted tiles on y-axis @data.each_pair do |y,data_y| # Iterate through sorted tiles on x-axis data_y.each_pair do |x,data_x| # Iterate through map editor layers downwards data_x.each_pair do |z,t| # Get Tile ID # Skip to next if there no tile next if t == nil # If tile fits properties of layer, only true if t is a autotile if @tiles.include?(t/48-1) # Add tile id to cache @cache[y] = {} if @cache[y] == nil @cache[y][x] = {} if @cache[y][x] == nil @cache[y][x][z] = t # Extend borders border(x,y) # Delete from map data list @data_link[y][x].delete(z) @data_link[y].delete(x) if @data_link[y][x].size == 0 @data_link.delete(y) if @data_link[y].size == 0 tiles_found = true layer = z end end if tiles_found == true if layer == 0 for z in [1,2] t = data_x[z] next if t == nil || t < 384 || @priorities[t] != @priority @cache2[y] = {} if @cache2[y] == nil @cache2[y][x] = {} if @cache2[y][x] == nil @cache2[y][x][z] = t @data_link[y][x].delete(z) @data_link[y].delete(x) if @data_link[y][x].size == 0 @data_link.delete(y) if @data_link[y].size == 0 end elsif layer == 1 t = data_x[2] next if t == nil || t < 384 || @priorities[t] != @priority @cache2[y] = {} if @cache2[y] == nil @cache2[y][x] = {} if @cache2[y][x] == nil @cache2[y][x][z] = t @data_link[y][x].delete(z) @data_link[y].delete(x) if @data_link[y][x].size == 0 @data_link.delete(y) if @data_link[y].size == 0 end end end # Set row borders @rows[y,0] = @border_lx_row @rows[y,1] = @border_rx_row # Re-Initialize row border temporaries for next iteraton @border_lx_row = @width/32 @border_rx_row = 0 end end #-------------------------------------------------------------------------- # * Setup_tiles (reads tiles for this layer and defines the borders. # Makes use of special rules for reading) #-------------------------------------------------------------------------- def setup_tiles # Get pre-sorted tile data with priority of the layer @data_link = $game_map.priority_data(@priority) # Clone hashs, needed for functionally interation while deleting stuff # from the data @data = @data_link.dup @data_link.each_pair do |dx,data_x| dat_x = @data[dx] dat_x = data_x.dup data_x.each_pair do |dz,data_z| dat_x[dz] = data_z.dup end end # Iterate through sorted tiles on y-axis @data.each_pair do |y,data_y| # Iterate through sorted tiles on x-axis data_y.each_pair do |x,data_x| # Initialize autotile found flag to false autotile_found = false # Iterate through map editor layers downwards data_x.each_pair do |z,t| # Iterate through map editor layers # Get tile id # Store whether tile fits layer properties or not # only true if t is a autotile tiles_include = @tiles.include?(t/48-1) # If tile is included or tile is from tileset or tile is autotile # with 1 frame if tiles_include || (t >= 384 || @autotile_frames[t/48-1] <= 1) # Store in cache @cache[y] = {} if @cache[y] == nil @cache[y][x] = {} if @cache[y][x] == nil @cache[y][x][z] = t # If tile is a autotile and is included if t < 384 && tiles_include # Delete from map data list @data_link[y][x].delete(z) @data_link[y].delete(x) if @data_link[y][x].size == 0 @data_link.delete(y) if @data_link[y].size == 0 # Extend borders border(x,y) # Set autotile found flag to true autotile_found = true end end end # If no autotile was found & row at y is not empty and x-position is not empty if autotile_found == false && @cache[y] != nil && @cache[y][x] != nil # Delete all tiles on x-position from cache @cache[y].delete(x) @cache.delete(y) if @data_link[y].size == 0 end end # Set row borders @rows[y,0] = @border_lx_row @rows[y,1] = @border_rx_row # Re-Initialize row border temporaries for next iteration @border_lx_row = @width/32 @border_rx_row = 0 end end #-------------------------------------------------------------------------- # * Create_Sprites (creates sprites & mitmaps for every row) #-------------------------------------------------------------------------- def create_sprites # Iterate through tiles on y-axis for y in @cache.keys # If row is not valid if !row_valid?(y) # skip to next next end # Calculate row width distx = @rows[y,1] - @rows[y,0] # Create sprite sprite = Sprite.new(@viewport) # Create bitmap with row-width*count of frames sprite.bitmap = Bitmap.new(distx*32*@frames,32) sprite.x = @rows[y,0]*32-$game_map.display_x/4 sprite.y = y*32-$game_map.display_y/4 # Set source rect to frame 0 sprite.src_rect = Rect.new(0,0,distx*32,32) sprite.blend_type = @blend_type # If priority equals 0 if @priority == 0 # Set z to 0, always beyond later created layers sprite.z = 0 else # Set z to base + priority + dosition - display-Position sprite.z = 32 + 32*@priority + 32*y - $game_map.display_y/4 end # Add sprite to hash @sprites[y] = sprite end end #-------------------------------------------------------------------------- # * Border (enhances the borders of the layer and the current row) #-------------------------------------------------------------------------- def border(x,y) # If X is outside left border if x < @border_lx # Extend left border to x @border_lx = x end # If X is outside right border if x > @border_rx # Extend right border to x+1 @border_rx = x+1 end # If Y is outside top border if y < @border_ty # Extend top border to y @border_ty = y end # If Y is outside bottom border if y > @border_by # Extend bottom_border to y @border_by = y end # If X is outside left row border if x < @border_lx_row # Extend left row border to x @border_lx_row = x end # If X is outside right row border if x+1 > @border_rx_row # Extend right row border to y @border_rx_row = x+1 end end #-------------------------------------------------------------------------- # * Update (updates row's position in the image as well as animations) #-------------------------------------------------------------------------- def update(ox,oy) # Get first and last row 1 outside screen dy = oy/32.0 l = [dy.to_i-1,@border_ty].max r = [dy.to_i+17,@border_by].min # If time exceedes speed if @time > @speed # Reinit time, advance state @time = 0 @state += 1 # Iterate through every row on screen for i in l..r # Skip to next If row has no sprite sprite = @sprites[i] next if sprite == nil || sprite.disposed? || !$game_map.tone # Set sprite properties sprite.tone = $game_map.tone# if @blend_type == 0 sprite.x = @rows[i,0]*32-ox sprite.y = i*32-oy # If priority equals 0 if @priority == 0 # Set Z to 0, always beyond later created tiles sprite.z = 0 else # Set Z to Base + Priority + Position - Tilemap position sprite.z = 32 + 32*@priority + i*32 - oy end # Get row width lx = @rows[i,0] w = @rows[i,1] - lx # Set animation frame sprite.src_rect = Rect.new(@state*w*32,0,w*32,32) end # If state exceeded frame count if @state >= @frames-1 # Reset state @state = -1 end # Else: just update position else # Iterate through every row on screen for i in l..r # Skip to next if row has no sprite sprite = @sprites[i] next if sprite == nil || sprite.disposed? || !$game_map.tone # Set sprite properties sprite.tone = $game_map.tone# if @blend_type == 0 sprite.x = @rows[i,0]*32-ox sprite.y = i*32-oy # If priority equals 0 if @priority == 0 # Set Z to 0, always beyond later created tiles sprite.z = 0 else # Set Z to Base + Priority + Position - Tilemap position sprite.z = 32 + 32*@priority + i*32 - oy end end end # Advance time @time += 1 end #-------------------------------------------------------------------------- # * Update All (updates row's position in the image as well as animations) #-------------------------------------------------------------------------- def update_all(ox,oy) # Get first and last row 1 outside screen dy = oy/32.0 l = [dy.to_i-1,@border_ty].max r = [dy.to_i+17,@border_by].min # If time exceedes speed if @time > @speed # Reinit time, advance state @time = 0 @state += 1 # Iterate through every row on screen @sprites.each_key do |i| # Skip to next If row has no sprite sprite = @sprites[i] next if sprite == nil || sprite.disposed? || !$game_map.tone # Set sprite properties sprite.tone = $game_map.tone# if @blend_type == 0 sprite.x = @rows[i,0]*32-ox sprite.y = i*32-oy # If priority equals 0 if @priority == 0 # Set Z to 0, always beyond later created tiles sprite.z = 0 else # Set Z to Base + Priority + Position - Tilemap position sprite.z = 32 + 32*@priority + i*32 - oy end # Get row width lx = @rows[i,0] w = @rows[i,1] - lx # Set animation frame sprite.src_rect = Rect.new(@state*w*32,0,w*32,32) end # If state exceeded frame count if @state >= @frames-1 # Reset state @state = -1 end # Else: just update position else # Iterate through every row on screen @sprites.each_key do |i| # Skip to next if row has no sprite sprite = @sprites[i] next if sprite == nil || sprite.disposed? || !$game_map.tone # Set sprite properties sprite.tone = $game_map.tone# if @blend_type == 0 sprite.x = @rows[i,0]*32-ox sprite.y = i*32-oy # If priority equals 0 if @priority == 0 # Set Z to 0, always beyond later created tiles sprite.z = 0 else # Set Z to Base + Priority + Position - Tilemap position sprite.z = 32 + 32*@priority + i*32 - oy end end end # Advance time @time += 1 end #-------------------------------------------------------------------------- # * Refresh (refreshes all row's properties) #-------------------------------------------------------------------------- def refresh # Iterate through all sprites for y in @cache.keys # Skip if sprite doesn't exist sprite = @sprites[y] next if sprite == nil sprite.tone = $game_map.tone # If priority equals 0 sprite.x = @rows[y,0]*32-$game_map.display_x/4 sprite.y = y*32-$game_map.display_y/4 if @priority == 0 # Set z to 0, always beyond sprite.z = 0 else # Set Z to Base + Priority + Position - Screen Position sprite.z = 32+32*@priority+y*32-$game_map.display_y/4 end end end #-------------------------------------------------------------------------- # * Draw_tiles_blend (draws the complete layer in the single rows. Makes # use of special rules for 1/2-blended autotiles) #-------------------------------------------------------------------------- def draw_tiles_blend # Iterate through cached tiles on y axis @cache.each_pair do |y,cache_y| sprite = @sprites[y] next if cache_y == nil lx = @rows[y,0] w = @rows[y,1]-lx cache_y.each_pair do |x,cache_x| values_x = LiTTleDRAgo::RGSS3 ? cache_x.values.reverse : cache_x.values #cache_x.values.each do |t| #cache_x.values.reverse.each do |t| #RGSS3 values_x.each do |t| #RGSS3 file = (t / 48) - 1 a = t - (file+1)*48 for f in 0...@frames autotile = Cache.atile($game_map.autotile_names[file],a,f) sprite.bitmap.blt(-lx*32+x*32+f*w*32,0,autotile,autotile.rect) end end end end Cache.clear_auto end #-------------------------------------------------------------------------- # * Draw Tiles #-------------------------------------------------------------------------- def draw_tiles @cache.each_pair do |y,cache_y| sprite = @sprites[y] lx = @rows[y,0] w = @rows[y,1]-lx cache_y.each_pair do |x,cache_x| values_x = LiTTleDRAgo::RGSS3 ? cache_x.keys.reverse : cache_x.keys #cache_x.keys.each do |z| #cache_x.keys.reverse.each do |z| #RGSS3 values_x.each do |z| #RGSS3 t = cache_x[z] if t < 384 file = (t / 48) - 1 a = t - (file+1)*48 for f in 0...@frames autotile = Cache.atile($game_map.autotile_names[file],a,f) sprite.bitmap.blt(-lx*32+x*32+f*w*32,0,autotile,autotile.rect) end if @autotile_frames[file] <= 1 @data_link[y][x].delete(z) @data_link[y].delete(x) if @data_link[y][x].size == 0 @data_link.delete(y) if @data_link[y].size == 0 end else t -=384 xt = t%8 yt = t/8 r = Rect.new(xt*32,yt*32,32,32) for f in 0...@frames sprite.bitmap.blt(-lx*32+x*32+f*w*32,0,@tileset,r) end @data_link[y][x].delete(z) @data_link[y].delete(x) if @data_link[y][x].size == 0 @data_link.delete(y) if @data_link[y].size == 0 end end end end Cache.clear_auto end #-------------------------------------------------------------------------- # * Dispose Frame #-------------------------------------------------------------------------- def dispose for sprite in @sprites.values sprite.dispose end end end #============================================================================== # ** Cache #------------------------------------------------------------------------------ # This module loads graphics, creates bitmap objects, and retains them. # To speed up load times and conserve memory, this module holds the # created bitmap object in the internal hash, allowing the program to # return preexisting objects when the same bitmap is requested again. #============================================================================== module Cache #-------------------------------------------------------------------------- # * Constant #-------------------------------------------------------------------------- @auto_cache = {} [[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]] AUTOTILES = [26, 27, 32, 33, 4, 27, 32, 33, # 1 26, 5, 32, 33, 4, 5, 32, 33, # 3 26, 27, 32, 11, 4, 27, 32, 11, # 5 26, 5, 32, 11, 4, 5, 32, 11, # 7 26, 27, 10, 33, 4, 27, 10, 33, # 9 26, 5, 10, 33, 4, 5, 10, 33, # 11 26, 27, 10, 11, 4, 27, 10, 11, # 13 26, 5, 10, 11, 4, 5, 10, 11, # 15 24, 25, 30, 31, 24, 5, 30, 31, # 17 24, 25, 30, 11, 24, 5, 30, 11, # 19 14, 15, 20, 21, 14, 15, 20, 11, # 21 14, 15, 10, 21, 14, 15, 10, 11, # 23 28, 29, 34, 35, 28, 29, 10, 35, # 25 4, 29, 34, 35, 4, 29, 10, 35, # 27 38, 39, 44, 45, 4, 39, 44, 45, # 29 38, 5, 44, 45, 4, 5, 44, 45, # 31 24, 29, 30, 35, 14, 15, 44, 45, # 33 12, 13, 18, 19, 12, 13, 18, 11, # 35 16, 17, 22, 23, 16, 17, 10, 23, # 37 40, 41, 46, 47, 4, 41, 46, 47, # 39 36, 37, 42, 43, 36, 5, 42, 43, # 41 12, 17, 18, 23, 12, 13, 42, 43, # 43 36, 41, 42, 47, 16, 17, 46, 47, # 45 12, 17, 42, 47, 0, 1, 6, 7] # 47 module_function #-------------------------------------------------------------------------- # * Get Automatic Tile #-------------------------------------------------------------------------- def atile(file, id , offset) if @auto_cache[[file,id,offset]] == nil autotile_bitmap = Bitmap.new(32, 32) autotiles_bitmap = autotile(file) if autotiles_bitmap.height == 32 if offset*32 >= autotiles_bitmap.width autotile_bitmap.blt(0,0,autotiles_bitmap,Rect.new(0,0,32,32)) else autotile_bitmap.blt(0,0,autotiles_bitmap,Rect.new(offset*32,0,32,32)) end @auto_cache[[file,id,offset]] = autotile_bitmap return autotile_bitmap end real_id = id*4 off = offset*96 if off>=autotiles_bitmap.width off = 0 end auto1 = AUTOTILES[real_id + 0] auto2 = AUTOTILES[real_id + 1] auto3 = AUTOTILES[real_id + 2] auto4 = AUTOTILES[real_id + 3] rect1 = Rect.new(auto1 % 6 * 16 + off, auto1 / 6 * 16, 16, 16) rect2 = Rect.new(auto2 % 6 * 16 + off, auto2 / 6 * 16, 16, 16) rect3 = Rect.new(auto3 % 6 * 16 + off, auto3 / 6 * 16, 16, 16) rect4 = Rect.new(auto4 % 6 * 16 + off, auto4 / 6 * 16, 16, 16) autotile_bitmap.blt(0, 0, autotiles_bitmap, rect1) autotile_bitmap.blt(16, 0, autotiles_bitmap, rect2) autotile_bitmap.blt(0, 16, autotiles_bitmap, rect3) autotile_bitmap.blt(16, 16, autotiles_bitmap, rect4) @auto_cache[[file,id,offset]] = autotile_bitmap return autotile_bitmap else return @auto_cache[[file,id,offset]] end end #-------------------------------------------------------------------------- # * Get Autotile Graphic #-------------------------------------------------------------------------- def self.autotile(filename) self.load_bitmap("Graphics/Autotiles/", filename) end #-------------------------------------------------------------------------- # * Get Fog Graphic #-------------------------------------------------------------------------- def self.fog(filename, hue = 0) self.load_bitmap("Graphics/Fogs/", filename, hue) end #-------------------------------------------------------------------------- # * Get Panorama Graphic #-------------------------------------------------------------------------- def self.panorama(filename, hue = 0) self.load_bitmap("Graphics/Panoramas/", filename, hue) end #-------------------------------------------------------------------------- # * Get Tileset Graphic #-------------------------------------------------------------------------- def self.tileset(filename) self.load_bitmap("Graphics/Tilesets/", filename) end #-------------------------------------------------------------------------- # * Get Tile Graphic #-------------------------------------------------------------------------- def self.tile(filename, tile_id, hue) key = [filename, tile_id, hue] if not @cache.include?(key) or @cache[key].disposed? @cache[key] = Bitmap.new(32, 32) x = (tile_id - 384) % 8 * 32 y = (tile_id - 384) / 8 * 32 rect = Rect.new(x, y, 32, 32) @cache[key].blt(0, 0, self.tileset(filename), rect) @cache[key].hue_change(hue) end @cache[key] end #-------------------------------------------------------------------------- # * Clear auto #-------------------------------------------------------------------------- def clear_auto @auto_cache.values.each {|bitmap| bitmap.dispose} @auto_cache.clear #GC.start end end module RPG class Map attr_accessor :tileset_id end class Tileset alias init_tileset initialize def initialize init_tileset @tileset_name = "" @autotile_names = [""]*7 @panorama_name = "" @panorama_hue = 0 @fog_name = "" @fog_hue = 0 @fog_opacity = 64 @fog_blend_type = 0 @fog_zoom = 200 @fog_sx = 0 @fog_sy = 0 @battleback_name = "" @passages = Table.new(384) @priorities = Table.new(384) @priorities[0] = 5 @terrain_tags = Table.new(384) end attr_accessor :tileset_name, :autotile_names, :panorama_name, :panorama_hue, :fog_name, :fog_hue, :fog_opacity, :fog_blend_type, :fog_zoom, :fog_sx, :fog_sy, :battleback_name, :passages, :priorities, :terrain_tags end end #============================================================================== # ** Sprite_Layer NEW #------------------------------------------------------------------------------ # This class manages tile layers. Every layer contains multipe sprites, one # for each tile row. Furthermore creates the respective bitmaps for the layer. #============================================================================== class Sprite_Layer #-------------------------------------------------------------------------- # * Initialize (read tiles, create sprites & bitmaps) #-------------------------------------------------------------------------- def initialize(viewport,priority,autotile_frames,cache=nil) # Get Tileset ID @tileset_id = $game_map.map.tileset_id # Class variables @priority = priority @autotile_frames = autotile_frames @viewport = viewport # Calculate number of tiles on x and y axis @width = $game_map.width @height = $game_map.height # Cache for the tiles if cache == nil @cache = {} else @cache = cache end # Set layer border variables to l<->r and u<->d (changed max/min values) @border_lx = @width @border_ty = @height @border_rx = 0 @border_by = 0 # Row border @border_lx_row = @width @border_rx_row = 0 # Table to store left and right border of every row @rows = Table.new(@height,2) # Hash for the sprites @sprites = {} # Setup tiles if @cache.size == 0 setup_tiles else setup_tiles_cache end # If not valid, return return if !valid? # Otherwise, create sprites create_sprites # Get tileset graphic @tileset = Cache.tileset($game_map.tileset_name) # Draw tiles draw_tiles @tileset = nil end #-------------------------------------------------------------------------- # * Valid? (checks whether found in tiles for this layer) #-------------------------------------------------------------------------- def valid? # If right border greater or equal to left border and # top border greater or equal to bottom border then true return @border_rx >= @border_lx && @border_by >= @border_ty end #-------------------------------------------------------------------------- # * Row_valid? (checks whether found in tiles in row y) #-------------------------------------------------------------------------- def row_valid?(y) # If right row border is greater than left row border true return @rows[y,1]>@rows[y,0] end #-------------------------------------------------------------------------- # * Setup_tiles (reads tiles for this layer and defines the borders) #-------------------------------------------------------------------------- def setup_tiles # Get pre-sorted Tile data with priority of the layer @data_link = $game_map.priority_data(@priority) # Clone hashs, needed for functionally interation while deleting stuff # from the data @data = @data_link.clone @data_link.each_pair do |dx,data_x| dat_x = @data[dx] dat_x = data_x.dup data_x.each_pair do |dz,data_z| dat_x[dz] = data_z.dup end end # Iterate through sorted tiles on y-axis @data.each_pair do |y,data_y| # Iterate through sorted tiles on x-axis data_y.each_pair do |x,data_x| # Iterate through map editor layers downwards data_x.each_pair do |z,t| # Get Tile ID # If tile is from tileset or autotile with 1 frame if t >= 384 || @autotile_frames[t/48-1] <= 1 # Store in cache @cache[y] = {} if @cache[y] == nil @cache[y][x] = {} if @cache[y][x] == nil @cache[y][x][z] = t # Extend border border(x,y) # Delete from sorted tile list #@data_link[y][x].delete(z) #@data_link[y].delete(x) if @data_link[y][x].size == 0 #@data_link.delete(y) if @data_link[y].size == 0 end end end # Set row borders @rows[y,0] = @border_lx_row @rows[y,1] = @border_rx_row # Re-Initialize row borders for next iteration @border_lx_row = @width/32 @border_rx_row = 0 end end #-------------------------------------------------------------------------- # * Setup_tiles_cache #-------------------------------------------------------------------------- def setup_tiles_cache # Get pre-sorted Tile data with priority of the layer @data_link = $game_map.priority_data(@priority) # Clone hashs, needed for functionally interation while deleting stuff # from the data @data = @data_link.clone @data_link.each_pair do |dx,data_x| dat_x = @data[dx] dat_x = data_x.dup data_x.each_pair do |dz,data_z| dat_x[dz] = data_z.dup end end # Iterate through sorted tiles on y-axis @cache.each_pair do |y,cache_y| # Iterate through sorted tiles on x-axis cache_y.each_pair do |x,cache_x| # Iterate through map editor layers border(x,y) if cache_x.size > 0 end # Set row borders @rows[y,0] = @border_lx_row @rows[y,1] = @border_rx_row # Re-Initialize row borders for next iteration @border_lx_row = @width/32 @border_rx_row = 0 end end #-------------------------------------------------------------------------- # * Create_Sprites (creates sprites & bitmaps for each row) #-------------------------------------------------------------------------- def create_sprites # Iterate from upper border to lower border for y in @border_ty..@border_by # If row is not valid if !row_valid?(y) # Skip to next next end # Otherwise, calculate distance from left to right border distx = @rows[y,1] - @rows[y,0] # Create sprite sprite = Sprite.new(@viewport) # Create bitmap in row-size sprite.bitmap = Bitmap.new(distx*32,32) # Set x-coordinate to left border sprite.x = @rows[y,0]*32-$game_map.display_x/4 # Set y-coordinate to row y sprite.y = y*32-$game_map.display_y/4 sprite.blend_type = 0 # If priority equals 0 if @priority == 0 # Set Z to 0, Sprite always beyond later created sprite.z = 0 else # Set Z to Base + Priority + Position - Screen Position sprite.z = 32 + 32*@priority + y*32 - $game_map.display_y/4 end # Add sprite to hash @sprites[y] = sprite end end #-------------------------------------------------------------------------- # * Border (enhances borders of layer and current row) #-------------------------------------------------------------------------- def border(x,y) # If X is outside left border if x < @border_lx # Extend left border to x @border_lx = x end # If X is outside right border if x > @border_rx # Extend right border to x+1 @border_rx = x+1 end # If Y is outside top border if y < @border_ty # Extend top border to y @border_ty = y end # If Y is outside bottom border if y > @border_by # Extend bottom_border to y @border_by = y end # If X is outside left row border if x < @border_lx_row # Extend left row border to x @border_lx_row = x end # If X is outside right row border if x+1 > @border_rx_row # Extend right row border to y @border_rx_row = x+1 end end #-------------------------------------------------------------------------- # * Update (updates position of image's rows) #-------------------------------------------------------------------------- def update(ox,oy) # Get uppermost row 1 block outside of screen y = [((oy*4-224)/128).to_i,@border_ty].max # Get lowermost row 1 block outside of screen y2 = [y+17,@border_by].min # Iterate from uppermost to lowermost row for i in y..y2 # Skip if row has no sprite sprite = @sprites[i] next if sprite == nil || sprite.disposed? || !$game_map.tone sprite.tone = $game_map.tone # If priority equals 0 sprite.x = @rows[i,0]*32-ox sprite.y = i*32-oy if @priority == 0 # Set z to 0, always beyond sprite.z = 0 else # Set Z to Base + Priority + Position - Screen Position sprite.z = 32+32*@priority+i*32-oy end end end #-------------------------------------------------------------------------- # * Update All (updates position of image's rows) #-------------------------------------------------------------------------- def update_all(ox,oy) # Get uppermost row 1 block outside of screen y = [((oy*4-224)/128).to_i,@border_ty].max # Get lowermost row 1 block outside of screen y2 = [y+17,@border_by].min # Iterate from uppermost to lowermost row @sprites.each_key do |i| # Skip if row has no sprite sprite = @sprites[i] next if sprite == nil || sprite.disposed? || !$game_map.tone sprite.tone = $game_map.tone # If priority equals 0 sprite.x = @rows[i,0]*32-ox sprite.y = i*32-oy if @priority == 0 # Set z to 0, always beyond sprite.z = 0 else # Set Z to Base + Priority + Position - Screen Position sprite.z = 32+32*@priority+i*32-oy end end end #-------------------------------------------------------------------------- # * Refresh (refreshes all sprites' properties) #-------------------------------------------------------------------------- def refresh # Iterate through all sprites for y in @cache.keys sprite = @sprites[y] # Skip if sprite doesn't exist next if sprite == nil sprite.tone = $game_map.tone # If priority equals 0 sprite.x = @rows[y,0]*32-$game_map.display_x/4 sprite.y = y*32-$game_map.display_y/4 if @priority == 0 # Set z to 0, always beyond sprite.z = 0 else # Set Z to Base + Priority + Position - Screen Position sprite.z = 32+32*@priority+y*32-$game_map.display_y/4 end end end #-------------------------------------------------------------------------- # * Draw_tiles (draws the complete layer into the single rows) #-------------------------------------------------------------------------- def draw_tiles # Iterate through all cached tiles on y-axis @cache.each_pair do |y,cache_y| # Iterate through all cached tiles on x-axis sprite = @sprites[y] cache_y.each_pair do |x,cache_x| # Iterate through all cached tile layers (map-editor) # ! Lowest z first ! values_x = LiTTleDRAgo::RGSS3 ? cache_x.values.reverse : cache_x.values #cache_x.values.each do |t| #cache_x.values.reverse.each do |t| #RGSS3 values_x.each do |t| #RGSS3 # Get tile ID from cache # Get left border of row lx = @rows[y,0] # If tile is from tileset if t >= 384 # Calculate x/y-position on tileset t -= 384 xt = t%8 yt = t/8 # Source rect r = Rect.new(xt*32,yt*32,32,32) # Blt tile from tileset to row on -border+x sprite.bitmap.blt(-lx*32+x*32,0,@tileset,r) # Else: Tile is an autotile (with 1 frame) else # Calculate file id and autotile id file = (t / 48) - 1 a = t - (file+1)*48 # Get autotile bitmap from Cache autotile = Cache.atile($game_map.autotile_names[file],a,0) # Blt autotile to row on -border+x sprite.bitmap.blt(-lx*32+x*32,0,autotile,autotile.rect) end end end end # Clear autotile cache Cache.clear_auto end #-------------------------------------------------------------------------- # * Dispose (delete row sprites) #-------------------------------------------------------------------------- def dispose # Dispose every sprite for sprite in @sprites.values sprite.dispose end end end #============================================================================== # ** Tilemap_New NEW #------------------------------------------------------------------------------ # This is the script's core, the new tilemap class. Currently contains methods # for updating and deleting, mostly self-managing. # Creates up to 5 layers and 6 autotile layers. Layers are created depending # on priority and mapping, autotile layer depending on properties of autotiles # (speed,frames,blend mode). #============================================================================== class Tilemap_New #-------------------------------------------------------------------------- # * Public Instance Variable #-------------------------------------------------------------------------- attr_accessor :tileset,:autotiles,:viewport attr_reader :autotile_frames #-------------------------------------------------------------------------- # * Initialize (create layer) #-------------------------------------------------------------------------- def initialize(viewport,tileset,autiles) # Save tileset & autotiles @viewport = viewport @tileset = tileset @autotiles = autiles # Get number of frames per autotile @autotile_frames = [] for autotile in @autotiles # If autotiles height exceeds 32 if autotile.height > 32 @autotile_frames << autotile.width/96 # Else: autotiles in X*32 format else @autotile_frames << autotile.width/32 end end # Tileset ID id = $game_map.tileset_id # Temporaries autotiles = [] done = [] autotiles_later = {} # Class variables @autotile_layers = [] @layers = [] @ox = 0 @oy = 0 # Iterate through autotiles for i in 0..6 # Get frames frames = @autotile_frames[i] # If only one frame => static, skip next if frames <= 1 || done.include?(i) # Get properties speed = AUTOTILE::SPEED[id][i] if AUTOTILE::SPEED[id] != nil speed = AUTOTILE::DEFAULT_SPEED if speed == nil blend_type = AUTOTILE::BLEND_TYPE[id][i] if AUTOTILE::BLEND_TYPE[id] != nil blend_type = 0 if blend_type == nil priority = $game_map.priorities[(i+1)*48] # Iterate through all autotiles >= current one # Batches similar autotiles in the same layer -> less memody/lag for j in i..6 # Get 2nd autotile properties speed2 = AUTOTILE::SPEED[id][j] if AUTOTILE::SPEED[id] != nil speed2 = AUTOTILE::DEFAULT_SPEED if speed2 == nil frames2 = @autotile_frames[j] blend_type2 = AUTOTILE::BLEND_TYPE[id][j] if AUTOTILE::BLEND_TYPE[id] != nil blend_type2 = 0 if blend_type2 == nil priority2 = $game_map.priorities[(j+1)*48] # If properties of both autotiles match if speed2 == speed && frames2 == frames && blend_type2 == blend_type && priority2 == priority # Store autotile id autotiles << j # Store properties speed3 = speed frames3 = frames priority3 = priority blend_type3 = blend_type # Autotile id is done done << j end end # If special blended autotiles if blend_type3 >= 1 # Store autotile ids & properties for later creation (z-priority) autotiles_later[priority3] = [] if autotiles_later[priority3] == nil autotiles_later[priority3] << Command_Autotile.new(autotiles,speed3,@autotile_frames,priority3,blend_type3) # Else : Normal blended tile else # Create autotile-Layer @autotile_layers << Sprite_Auto.new(@viewport,autotiles,speed3,@autotile_frames,priority3,blend_type3) # Delete if not valid @autotile_layers.delete_at(@autotile_layers.size-1) if !@autotile_layers[@autotile_layers.size-1].valid? end autotiles.clear end # Iterate through all priority layers for i in 0..5 # Create layer sprite sprite = Sprite_Layer.new(@viewport,i,@autotile_frames) # Keep sprite onty if valid? @layers << sprite if sprite.valid? # If blended autotile waits for creation at current priority if autotiles_later[i] != nil # Iterate through autotile commands for c in autotiles_later[i] # Create autotile-layer @autotile_layers << Sprite_Auto.new(@viewport,c.autotiles,c.speed,c.frames,c.priority,c.blend_type) # Delete if not valid @autotile_layers.delete_at(@autotile_layers.size-1) if !@autotile_layers[@autotile_layers.size-1].valid? end # Delete command layer autotiles_later.delete(i) end end end #-------------------------------------------------------------------------- # * Ox (returns tilemap x-position) #-------------------------------------------------------------------------- def ox return @ox end #-------------------------------------------------------------------------- # * Oy (returns tilemap y-position) #-------------------------------------------------------------------------- def oy return @oy end #-------------------------------------------------------------------------- # * Ox= (sets tilemap x-position) #-------------------------------------------------------------------------- def ox=(ox) # Return if position is equal to new position #return if @ox == ox @ox = ox end #-------------------------------------------------------------------------- # * Oy= (sets tilemap y-position) #-------------------------------------------------------------------------- def oy=(oy) # Return if position is equal to new position #return if @oy == oy @oy = oy end #-------------------------------------------------------------------------- # * Frame Update #-------------------------------------------------------------------------- def update # Update viewport. Corrupts standard x/y positions of fog,characters,weather, # panorama, corrected in the corresponding method #@viewport.ox = $game_map.display_x/4 #@viewport.oy = $game_map.display_y/4 # Update autotile_layers @autotile_layers.each {|layer| layer.update(@ox,@oy)} # Update_layers @layers.each {|layer| layer.update(@ox,@oy)} end #-------------------------------------------------------------------------- # * Update_all #-------------------------------------------------------------------------- def update_all # Update viewport. Corrupts standard x/y positions of fog,characters,weather, # panorama, corrected in the corresponding method #@viewport.ox = $game_map.display_x/4 #@viewport.oy = $game_map.display_y/4 # Update autotile_layers @autotile_layers.each {|layer| layer.update_all(@ox,@oy)} # Update_layers @layers.each {|layer| layer.update_all(@ox,@oy)} end #-------------------------------------------------------------------------- # * Dispose (delete layer & autotile layer) #-------------------------------------------------------------------------- def dispose # Dispose autotile layers @autotile_layers.each {|layer| layer.dispose } @autotile_layers = [] # Dispose layers @layers.each {|layer| layer.dispose } @layers = [] end #-------------------------------------------------------------------------- # * Initialize (updates all rows of all layers) #-------------------------------------------------------------------------- def refresh @autotile_layers.each {|layer| layer.refresh } @layers.each {|layer| layer.refresh } end end #============================================================================== # ** Command_Autotile NEW #------------------------------------------------------------------------------ # This class saves all autotile data. Used in order to create autotiles with # blend-mode 1/2 after normal tile layer. #============================================================================== class Command_Autotile #-------------------------------------------------------------------------- # * Public Instance Variable #-------------------------------------------------------------------------- attr_reader :autotiles,:speed,:frames,:blend_type,:priority #-------------------------------------------------------------------------- # * Initialize #-------------------------------------------------------------------------- def initialize(autotiles,speed,frames,priority,blend_type) @autotiles = autotiles.clone #Autotile list @speed = speed #Animation speed @frames = frames #Nr. of frames @blend_type = blend_type #Blend type @priority = priority #Priority end end #============================================================================== # ** Graphics #------------------------------------------------------------------------------ # This module handles all Graphics #============================================================================== module Graphics #-------------------------------------------------------------------------- # ● class << self #-------------------------------------------------------------------------- class << self #-------------------------------------------------------------------------- # ● Alias Method #-------------------------------------------------------------------------- unless self.method_defined?(:atilemap_update) alias_method(:atilemap_update, :update) #------------------------------------------------------------------------- # ● Update #------------------------------------------------------------------------- def update atilemap_update scene = ($imported[:drg_core_engine]||0) >= 1.19 ? LiTTleDRAgo.scene : SceneManager.scene return if scene.is_a?(Scene_Map) spriteset = scene.instance_variables.any? {|var| scene.instance_variable_get(var).is_a?(Spriteset_Map)} $game_temp.instance_variable_set(:@store_tilemap,true) if spriteset end end end end