Neo Mode 7
Descrizione
Una nuova versione della Mode7, che permette di creare mappe in 3D e isometriche, basta incollare questo codice nel nome della mappa [NM/] [E]
Autore
MGCaladtogel
Codice modificato da
Nocoldin
Allegati
La demo
http://www.mediafire.com/?jodyjwmndwd
Istruzioni per l'uso
Copiate il codice in una nuova classe chiamata Neo Mode.
#============================================================================ # This script emulates the snes mode 7 feature. # Written by MGCaladtogel # Neo Mode 7 - 12/05/08 #---------------------------------------------------------------------------- # Instructions : # You must add to the map's name : #- [NM7] : to activate Neo Mode 7 #- [#XX] : XX is the angle of slant (in degree) : 0 -> 89 #- [%XXX]: XXX is the angle of rotation (in degree) : 0 -> 359 #- [L] : to enable map looping #- [A] : animated autotiles (with 4 patterns) #- [H] : to have a white horizon #- [RX] : X = 1 -> high resolution (default) # : X = 2 -> medium resolution (to increase performance) # : X = 3 -> low resolution (to increase performance) #- [F] : activate the filer (to increase performance) : strongly recommanded # # OR : # see the "$mode7_maps_settings" below (l.68) to prepare your settings #---------------------------------------------------------------------------- # - To set a new angle of slant (0~89) : # $scene.spriteset.tilemap.set_alpha(new angle) # To slide progressively into a new angle of slant : # $scene.spriteset.tilemap.to_alpha(new angle, speed) # To increase/decrease the slant : # $scene.spriteset.tilemap.increase_alpha(value) # - To set a new angle of rotation (0~379) : # $scene.spriteset.tilemap.set_theta(new angle) # To slide progressively into a new angle of rotation : # $scene.spriteset.tilemap.to_theta(angle, speed, dir) # To increase/decrease the angle of rotation : # $scene.spriteset.tilemap.increase_theta(value) # - To set a new zoom level : # $scene.spriteset.tilemap.set_zoom(new value) # To slide progressively into a new zoom level : # $scene.spriteset.tilemap.to_zoom(value, speed) # To increase/decrease the zoom level : # $scene.spriteset.tilemap.increase_zoom(value) # - The pivot's value (32~480) represents the screenline's number considered # as the axis for map trasformations. # By default its value is 256. # To set a new value : # $scene.spriteset.tilemap.set_pivot(new value) # To slide progressively into a new pivot's value : # $scene.spriteset.tilemap.to_pivot(value, speed) # To increase/decrease the pivot's value : # $scene.spriteset.tilemap.increase_pivot(value) # - Pivot's value and zoom level are saved from # one map to another. You have to reinitialize # them manually if you need it. # # - To set the altitude of a vertical event : # add a comment in the event's commands list with : "Heigth X", where X is the # height value ("Heigth 2" will draw the event 64 pixels above its original # position - you can use floats) # - To set the altitude of the player : # use : $game_player.height = X #============================================================================ # The map is drawn from all the tiles of the three layers that do not have a # terrain_tag's value of 1 or 2. # The other tiles (terrain_tag = 1 or 2) form elements that are drawn vertically, # like the 3rd-layer elements in the old version. # The 2 terrains ID used to form vertical elements $terrain_tags_vertical_tiles = [1, 2] # You can modify these values # To access maps names $data_maps = load_data("Data/MapInfos.rxdata") $neoM7_maps_settings = {} # Prepare your own settings for mode7 maps # Just put the first parameter in a map's name # For example : $neoM7_maps_settings["Worldmap"] = ["#60", "L", "A", "H", "F"] # -> will be called when "Worldmap" is included in the name $neoM7_maps_settings["Smallslant"] = ["#20", "A", "F"] # Add any number of settings you want # enable/disable mode7 for mode7 maps (not on the fly, just when the map is loaded), enabled by default $enable_neoM7_number = 15 # switch number : change this value ! # - Number of directions for the player on mode 7 maps : $player_directions = 4 # you can change this value ! # the character set used in that case must have the default name + "_m7" # - To set the number of directions of a vertical event : # add a comment in the event's commands list with : "Directions X" # rows of character sets : the first represents the character that faces the screen, # then the character rotates in the trigonometric direction $dirs = {} # 4 directions : $dirs[4] = [0, 2, 3, 1] # 8 directions : $dirs[8] = [0, 6, 2, 7, 3, 5, 1, 4] # you can change these values or add directions #============================================================================ # Neo Mode 7 # Written by MGCaladtogel # 12/05/08 # # Part 1 # # class Game_Switches # initialize : aliased # # class Game_System # initialize : aliased # neoM7_reset : new method # # class Game_Temp # initialize : aliased # #============================================================================ #============================================================================ # ■ Game_Switches #============================================================================ class Game_Switches #-------------------------------------------------------------------------- # * Aliased methods (F12 compatibility) #-------------------------------------------------------------------------- if !@already_aliased alias initialize_neoM7_game_player initialize @already_aliased = true end #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize initialize_neoM7_game_player self[$enable_neoM7_number] = true end end #============================================================================ # ■ Game_System #---------------------------------------------------------------------------- # Add attributes to this class #============================================================================ class Game_System #-------------------------------------------------------------------------- # * Aliased methods (F12 compatibility) #-------------------------------------------------------------------------- if !@already_aliased alias initialize_neoM7_game_system initialize @already_aliased = true end #-------------------------------------------------------------------------- # * Attributes #-------------------------------------------------------------------------- attr_accessor :neoM7 # true : neo mode 7 attr_accessor :neoM7_loop # true : map looping in x and y attr_accessor :neoM7_animated # true : animated autotiles for neoM7 maps attr_accessor :neoM7_white_horizon # true : white line horizon for neoM7 maps attr_accessor :neoM7_alpha # angle of slant (in degree) attr_accessor :neoM7_theta # angle of rotation (in degree) attr_accessor :neoM7_horizon # horizon's distance attr_accessor :neoM7_resolution # 1:max, 2:med, 3:low attr_accessor :neoM7_filter # true : enable filter (increase perf., blurry when moving) attr_accessor :neoM7_pivot # screenline's number of the slant/rotation pivot attr_accessor :neoM7_zoom # zoom level (percentage, 100 = no zoom) attr_accessor :neoM7_center_y # center screen y-coordinate (depend on pivot) #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize initialize_neoM7_game_system self.neoM7 = false self.neoM7_loop = false self.neoM7_animated = false self.neoM7_white_horizon = false self.neoM7_alpha = 0 self.neoM7_theta = 0 self.neoM7_horizon = 960 self.neoM7_resolution = 1 self.neoM7_filter = false neoM7_reset end #-------------------------------------------------------------------------- # * Reset zoom, pivot, and screen's center_y #-------------------------------------------------------------------------- def neoM7_reset self.neoM7_pivot = 256 self.neoM7_zoom = 100 self.neoM7_center_y = Game_Player::CENTER_Y end end #============================================================================ # ■ Game_Temp #---------------------------------------------------------------------------- # Add attributes to this class / Avoid using too many global variables #============================================================================ class Game_Temp #-------------------------------------------------------------------------- # * Aliased methods (F12 compatibility) #-------------------------------------------------------------------------- if !@already_aliased alias initialize_neoM7_game_temp initialize @already_aliased = true end #-------------------------------------------------------------------------- # * Attributes #-------------------------------------------------------------------------- attr_accessor :pivot # screenline's number of the pivot attr_accessor :pivot_map # same as pivot (depend of resolution) attr_accessor :neoM7_height_limit # horizon attr_accessor :height_limit_sprites # horizon for vertical sprites attr_accessor :distance_h # distance between the center of the map (halfwidth, pivot) and the point of view attr_accessor :slope_value # intermediate value used to calculate x-coordinate attr_accessor :slope_value_map # same as slope_value (depend of resolution) (* 262144) attr_accessor :corrective_value # intermediate value used to calculate x-coordinate attr_accessor :corrective_value_map # same as corrective_value (depend of resolution) (* 262144) attr_accessor :cos_alpha # cosinus of the angle of slant (* 4096) attr_accessor :sin_alpha # sinus of the angle of slant (* 4096) attr_accessor :cos_theta # cosinus of the angle of rotation (* 4096) attr_accessor :sin_theta # sinus of the angle of rotation (* 4096) attr_accessor :distance_p # distance between the center of the map (halfwidth, pivot) and the projection plane surface attr_accessor :zoom_map # zoom level (map) (percentage * 4096) attr_accessor :zoom_sprites # same as zoom_map (ratio) #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize initialize_neoM7_game_temp self.pivot = 0 self.pivot_map = 0 self.neoM7_height_limit = 0 self.height_limit_sprites = 0 self.distance_h = 0 self.slope_value = 0.0 self.slope_value = 0 self.corrective_value = 0.0 self.corrective_value_map = 0 self.cos_alpha = 0 self.sin_alpha = 0 self.cos_theta = 0 self.sin_theta = 0 self.distance_p = 0 self.zoom_map = 1 self.zoom_sprites = 1.0 end end #============================================================================ # Neo Mode 7 # Written by MGCaladtogel # 12/05/08 # # Part 2 # # class Game_Map # scroll_down : aliased # scroll_left : aliased # scroll_right : aliased # scroll_up : aliased # valid? : aliased # passable? : aliased # setup : aliased # # class Game_Character # initialize : aliased # update : aliased # # class Game_Event # check_commands : new method # refresh : aliased # # class Game_player # initialize : aliased # center : aliased # update : aliased # #============================================================================ #============================================================================ # ■ Game_Map #---------------------------------------------------------------------------- # Methods modifications to handle map looping #============================================================================ class Game_Map #-------------------------------------------------------------------------- # * Aliased methods (F12 compatibility) #-------------------------------------------------------------------------- if !@already_aliased alias scroll_down_neoM7_game_map scroll_down alias scroll_left_neoM7_game_map scroll_left alias scroll_right_neoM7_game_map scroll_right alias scroll_up_neoM7_game_map scroll_up alias valid_neoM7_game_map? valid? alias passable_neoM7_game_map? passable? alias old_setup_neoM7 setup @already_aliased = true end #-------------------------------------------------------------------------- # * Scroll Down # distance : scroll distance #-------------------------------------------------------------------------- def scroll_down(distance) if !$game_system.neoM7 scroll_down_neoM7_game_map(distance) return end @display_y = @display_y + distance end #-------------------------------------------------------------------------- # * Scroll Left # distance : scroll distance #-------------------------------------------------------------------------- def scroll_left(distance) if !$game_system.neoM7 scroll_left_neoM7_game_map(distance) return end @display_x = @display_x - distance end #-------------------------------------------------------------------------- # * Scroll Right # distance : scroll distance #-------------------------------------------------------------------------- def scroll_right(distance) if !$game_system.neoM7 scroll_right_neoM7_game_map(distance) return end @display_x = @display_x + distance end #-------------------------------------------------------------------------- # * Scroll Up # distance : scroll distance #-------------------------------------------------------------------------- def scroll_up(distance) if !$game_system.neoM7 scroll_up_neoM7_game_map(distance) return end @display_y = @display_y - distance end #-------------------------------------------------------------------------- # * Determine Valid Coordinates # x : x-coordinate # y : y-coordinate # Allow the hero to go out of the map when map looping #-------------------------------------------------------------------------- def valid?(x, y) if !$game_system.neoM7 return (valid_neoM7_game_map?(x, y)) end return true if $game_system.neoM7_loop return (x >= 0 and x < width and y >= 0 and 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) #-------------------------------------------------------------------------- def passable?(x, y, d, self_event = nil) if !$game_system.neoM7 return(passable_neoM7_game_map?(x, y, d, self_event)) end unless valid?(x, y) return false end bit = (1 << (d / 2 - 1)) & 0x0f for event in events.values if event.tile_id >= 0 and event != self_event and event.x == x and event.y == y and not 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 end for i in [2, 1, 0] 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 end return true end #-------------------------------------------------------------------------- # * Setup # map_id : map ID #-------------------------------------------------------------------------- def setup(map_id) old_setup_neoM7(map_id) if !$game_switches[$enable_neoM7_number] $game_system.neoM7 = false $game_system.neoM7_loop = false $game_system.neoM7_animated = false $game_system.neoM7_white_horizon = false $game_system.neoM7_alpha = 0 $game_system.neoM7_theta = 0 $game_system.neoM7_horizon = 960 $game_system.neoM7_resolution = 1 $game_system.neoM7_filter = false return end map_data = $data_maps[$game_map.map_id] for keyword in $neoM7_maps_settings.keys if map_data.name2.include?(keyword) command_list = $neoM7_maps_settings[keyword] $game_system.neoM7 = map_data.name2.include?("[NM7]") $game_system.neoM7_loop = map_data.name2.include?("[L]") $game_system.neoM7_animated = map_data.name2.include?("[A]") $game_system.neoM7_white_horizon = map_data.name2.include?("[H]") $game_system.neoM7_filter = map_data.name2.include?("[F]") for command in command_list if command.include?("R") $game_system.neoM7_resolution = (command.slice(1, 1)).to_i $game_system.neoM7_resolution = [[$game_system.neoM7_resolution, 1].max, 3].min end if command.include?("#") $game_system.neoM7_alpha = (command.slice(1, 2)).to_i $game_system.neoM7_alpha = [[$game_system.neoM7_alpha, 0].max, 89].min end if command.include?("%") $game_system.neoM7_theta = (command.slice(1, 3)).to_i $game_system.neoM7_theta = [[$game_system.neoM7_theta, 0].max, 359].min end end return end end $game_system.neoM7 = map_data.name2.include?("[NM7]") $game_system.neoM7_loop = map_data.name2.include?("[L]") $game_system.neoM7_animated = map_data.name2.include?("[A]") $game_system.neoM7_white_horizon = map_data.name2.include?("[H]") $game_system.neoM7_filter = map_data.name2.include?("[F]") if $game_system.neoM7 map_data.name2 =~ /\[R[ ]*([1-3]+)\]/i $game_system.neoM7_resolution = $1.to_i $game_system.neoM7_resolution = [[$game_system.neoM7_resolution, 1].max, 3].min map_data.name2 =~ /\[#[ ]*([00-99]+)\]/i $game_system.neoM7_alpha = $1.to_i $game_system.neoM7_alpha = [[$game_system.neoM7_alpha, 0].max, 89].min map_data.name2 =~ /\[%[ ]*([000-999]+)\]/i $game_system.neoM7_theta = $1.to_i $game_system.neoM7_theta = [[$game_system.neoM7_theta, 0].max, 359].min end end end #============================================================================ # ■ Game_Character #---------------------------------------------------------------------------- # "update" method modifications to handle map looping #============================================================================ class Game_Character #-------------------------------------------------------------------------- # * Aliased methods (F12 compatibility) #-------------------------------------------------------------------------- if !@already_aliased alias initialize_neoM7_game_character initialize alias update_neoM7_game_character update @already_aliased = true end #-------------------------------------------------------------------------- # * Attributes #-------------------------------------------------------------------------- attr_accessor :x attr_accessor :y attr_accessor :real_x attr_accessor :real_y attr_accessor :height # altitude attr_accessor :directions # number of directions attr_accessor :map_number_x # map's number with X-looping attr_accessor :map_number_y # map's number with Y-looping #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize initialize_neoM7_game_character self.height = 0.0 self.map_number_x = 0 self.map_number_y = 0 self.directions = 4 end #-------------------------------------------------------------------------- # * Update : handle map looping #-------------------------------------------------------------------------- def update if !$game_system.neoM7 update_neoM7_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_neoM7_game_character end end #============================================================================== # ■ Game_Event #---------------------------------------------------------------------------- # Add methods to handle altitude and directions number for vertical event #============================================================================ class Game_Event < Game_Character #-------------------------------------------------------------------------- # * Aliased methods (F12 compatibility) #-------------------------------------------------------------------------- if !@already_aliased alias refresh_neoM7_game_character refresh @already_aliased = true end #-------------------------------------------------------------------------- # * scan the event's commands list # page : the scanned page (RPG::Event::Page) #-------------------------------------------------------------------------- def check_commands(page) @height = 0.0 command_list = page.list for k in 0..command_list.length - 2 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 if (command.parameters[0].to_s).include?("Directions") self.directions = (command.parameters[0][11,command.parameters[0].length-1]).to_i end end end #-------------------------------------------------------------------------- # * scan the event's commands list of the current page when refreshed #-------------------------------------------------------------------------- def refresh refresh_neoM7_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 #-------------------------------------------------------------------------- # * Aliased methods (F12 compatibility) #-------------------------------------------------------------------------- if !@already_aliased alias initialize_neoM7_game_player initialize alias center_neoM7_game_player center alias update_neoM7_game_player update @already_aliased = true end #-------------------------------------------------------------------------- # * Object Initialization : add "directions" attribute #-------------------------------------------------------------------------- def initialize initialize_neoM7_game_player self.directions = $player_directions end #-------------------------------------------------------------------------- # * Always center around the hero in mode 7 #-------------------------------------------------------------------------- def center(x, y) if !$game_system.neoM7 center_neoM7_game_player(x, y) return end $game_map.display_x = x * 128 - CENTER_X $game_map.display_y = y * 128 - $game_system.neoM7_center_y end #-------------------------------------------------------------------------- # * Frame Update : CENTER_Y replaced by $game_system.neoM7_center_y # to handle pivot's values different from 256 #-------------------------------------------------------------------------- def update if !$game_system.neoM7 update_neoM7_game_player return end # Remember whether or not moving in local variables last_moving = moving? # If moving, event running, move route forcing, and message window # display are all not occurring unless moving? or $game_system.map_interpreter.running? or @move_route_forcing or $game_temp.message_window_showing # Move player in the direction the directional button is being pressed case Input.dir4 when 2 move_down when 4 move_left when 6 move_right when 8 move_up end end # Remember coordinates in local variables last_real_x = @real_x last_real_y = @real_y super # If character moves down and is positioned lower than the center # of the screen if @real_y > last_real_y and @real_y - $game_map.display_y > $game_system.neoM7_center_y # Scroll map down $game_map.scroll_down(@real_y - last_real_y) end # If character moves left and is positioned more let on-screen than # center if @real_x < last_real_x and @real_x - $game_map.display_x < CENTER_X # Scroll map left $game_map.scroll_left(last_real_x - @real_x) end # If character moves right and is positioned more right on-screen than # center if @real_x > last_real_x and @real_x - $game_map.display_x > CENTER_X # Scroll map right $game_map.scroll_right(@real_x - last_real_x) end # If character moves up and is positioned higher than the center # of the screen if @real_y < last_real_y and @real_y - $game_map.display_y < $game_system.neoM7_center_y # Scroll map up $game_map.scroll_up(last_real_y - @real_y) end # If not moving unless moving? # If player was moving last time if last_moving # Event determinant is via touch of same position event result = check_event_trigger_here([1,2]) # If event which started does not exist if result == false # Disregard if debug mode is ON and ctrl key was pressed unless $DEBUG and Input.press?(Input::CTRL) # Encounter countdown if @encounter_count > 0 @encounter_count -= 1 end end end end # If C button was pressed if Input.trigger?(Input::C) # Same position and front event determinant check_event_trigger_here([0]) check_event_trigger_there([0,1,2]) end end end end #============================================================================ # Neo Mode 7 # Written by MGCaladtogel # 12/05/08 # # Part 3 # # class Sprite # neoM7_x : new method # neoM7_y : new method # neoM7 : new method # neoM7_zoom : new method # on_screen_x : new method # on_screen_y : new method # neoM7_character_x : new method # neoM7_character_y : new method # neoM7_character : new method # # class RPG::Sprite # animation_set_sprites : redefined # # class Sprite_Character # update : aliased # refresh : aliased # # class Sprite_V : new class # # class Spriteset_Map # initialize : aliased # dispose : redefined # update : aliased # #============================================================================ #============================================================================ # ■ Sprite #============================================================================ class Sprite #-------------------------------------------------------------------------- # * Attributes #-------------------------------------------------------------------------- attr_accessor :length # sprite's width attr_accessor :height # sprite's height #-------------------------------------------------------------------------- # calculate x_coordinate in mode 7 for a vertical sprite #-------------------------------------------------------------------------- def neoM7_x(x_map, y_map) x_map = 32 * x_map y_map = 32 * y_map y_init = $game_temp.zoom_sprites * (y_map - $game_temp.pivot - $game_map.display_y.to_i / 4) x_init = $game_temp.zoom_sprites * (x_map - 320 - $game_map.display_x.to_i / 4) y_intermediate = (((y_init * $game_temp.cos_theta - x_init * $game_temp.sin_theta).to_i) >> 12) x_intermediate = (((x_init * $game_temp.cos_theta + y_init * $game_temp.sin_theta).to_i) >> 12) y_int_2 = $game_temp.pivot + ($game_temp.distance_h * y_intermediate * $game_temp.cos_alpha) / ((($game_temp.distance_h) << 12) - y_intermediate * $game_temp.sin_alpha) return (320 + ($game_temp.slope_value * y_int_2 + $game_temp.corrective_value) * x_intermediate) end #-------------------------------------------------------------------------- # calculate y_coordinate in mode 7 for a vertical sprite #-------------------------------------------------------------------------- def neoM7_y(x_map, y_map) x_map = 32 * x_map y_map = 32 * y_map y_init = $game_temp.zoom_sprites * (y_map - $game_temp.pivot - $game_map.display_y.to_i / 4) x_init = $game_temp.zoom_sprites * (x_map - 320 - $game_map.display_x.to_i / 4) y_intermediate = (((y_init * $game_temp.cos_theta - x_init * $game_temp.sin_theta).to_i) >> 12) return ($game_temp.pivot + ($game_temp.distance_h * y_intermediate * $game_temp.cos_alpha) / ((($game_temp.distance_h) << 12) - y_intermediate * $game_temp.sin_alpha)) end #-------------------------------------------------------------------------- # calculate x and y coordinates in mode 7 for a vertical sprite #-------------------------------------------------------------------------- def neoM7(x_map, y_map) x_map = 32 * x_map y_map = 32 * y_map y_init = $game_temp.zoom_sprites * (y_map - $game_temp.pivot - $game_map.display_y.to_i / 4) x_init = $game_temp.zoom_sprites * (x_map - 320 - $game_map.display_x.to_i / 4) y_intermediate = (((y_init * $game_temp.cos_theta - x_init * $game_temp.sin_theta).to_i) >> 12) x_intermediate = (((x_init * $game_temp.cos_theta + y_init * $game_temp.sin_theta).to_i) >> 12) self.y = $game_temp.pivot + ($game_temp.distance_h * y_intermediate * $game_temp.cos_alpha) / ((($game_temp.distance_h) << 12) - y_intermediate * $game_temp.sin_alpha) self.x = (320 + ($game_temp.slope_value * y + $game_temp.corrective_value) * x_intermediate) end #-------------------------------------------------------------------------- # calculate the zoom level in mode 7 for a vertical sprite #-------------------------------------------------------------------------- def neoM7_zoom(x_screen, y_screen) self.zoom_x = $game_temp.zoom_sprites * ($game_temp.slope_value * y + $game_temp.corrective_value) self.zoom_y = zoom_x end #-------------------------------------------------------------------------- # check if value_x (in pixels) is on screen #-------------------------------------------------------------------------- def on_screen_x(value_x) return (value_x.between?(- self.length / 2, 640 + self.length / 2)) end #-------------------------------------------------------------------------- # check if value_y (in pixels) is on screen #-------------------------------------------------------------------------- def on_screen_y(value_y) return (value_y.between?($game_temp.height_limit_sprites, 480 + self.height)) end #-------------------------------------------------------------------------- # calculate x_coordinate in mode 7 for a character sprite #-------------------------------------------------------------------------- def neoM7_character_x(x_screen, y_screen) y_init = $game_temp.zoom_sprites * (y_screen - $game_temp.pivot) x_init = $game_temp.zoom_sprites * (x_screen - 320) y_intermediate = (((y_init * $game_temp.cos_theta - x_init * $game_temp.sin_theta).to_i)>>12) x_intermediate = (((x_init * $game_temp.cos_theta + y_init * $game_temp.sin_theta).to_i)>>12) y_int_2 = $game_temp.pivot + ($game_temp.distance_h * y_intermediate * $game_temp.cos_alpha) / ((($game_temp.distance_h) << 12) - y_intermediate * $game_temp.sin_alpha) return (320 + ($game_temp.slope_value * y_int_2 + $game_temp.corrective_value) * x_intermediate) end #-------------------------------------------------------------------------- # calculate y_coordinate in mode 7 for a character sprite #-------------------------------------------------------------------------- def neoM7_character_y(x_screen, y_screen) y_init = $game_temp.zoom_sprites * (y_screen - $game_temp.pivot) x_init = $game_temp.zoom_sprites * (x_screen - 320) y_intermediate = (((y_init * $game_temp.cos_theta - x_init * $game_temp.sin_theta).to_i)>>12) return ($game_temp.pivot + ($game_temp.distance_h * y_intermediate * $game_temp.cos_alpha) / ((($game_temp.distance_h) << 12) - y_intermediate * $game_temp.sin_alpha)) end #-------------------------------------------------------------------------- # calculate x and y coordinates in mode 7 for a character sprite #-------------------------------------------------------------------------- def neoM7_character(x_screen, y_screen) y_init = $game_temp.zoom_sprites * (y_screen - $game_temp.pivot) x_init = $game_temp.zoom_sprites * (x_screen - 320) y_intermediate = (((y_init * $game_temp.cos_theta - x_init * $game_temp.sin_theta).to_i)>>12) x_intermediate = (((x_init * $game_temp.cos_theta + y_init * $game_temp.sin_theta).to_i)>>12) self.y = $game_temp.pivot + ($game_temp.distance_h * y_intermediate * $game_temp.cos_alpha) / ((($game_temp.distance_h) << 12) - y_intermediate * $game_temp.sin_alpha) self.x = (320 + ($game_temp.slope_value * y + $game_temp.corrective_value) * x_intermediate) end end #============================================================================ # ■ RPG::Sprite #============================================================================ module RPG class Sprite < ::Sprite #-------------------------------------------------------------------------- # * Rewritten method : the sprite's zoom level is applied to its animations #-------------------------------------------------------------------------- def animation_set_sprites(sprites, cell_data, position) for i in 0..15 sprite = sprites[i] pattern = cell_data[i, 0] if sprite == nil or pattern == nil or pattern == -1 sprite.visible = false if sprite != nil next end sprite.visible = true sprite.src_rect.set(pattern % 5 * 192, pattern / 5 * 192, 192, 192) if position == 3 if self.viewport != nil sprite.x = self.viewport.rect.width / 2 sprite.y = self.viewport.rect.height - 160 else sprite.x = 320 sprite.y = 240 end else sprite.x = self.x - self.ox + self.src_rect.width / 2 sprite.y = self.y - self.oy + self.src_rect.height / 2 sprite.y -= self.src_rect.height / 4 if position == 0 sprite.y += self.src_rect.height / 4 if position == 2 end sprite.x += zoom_x * cell_data[i, 1] sprite.y += zoom_y * cell_data[i, 2] sprite.z = z sprite.ox = 96 sprite.oy = 96 sprite.zoom_x = zoom_x * cell_data[i, 3] / 100.0 sprite.zoom_y = zoom_y * cell_data[i, 3] / 100.0 sprite.angle = cell_data[i, 4] sprite.mirror = (cell_data[i, 5] == 1) sprite.opacity = cell_data[i, 6] * self.opacity / 255.0 sprite.blend_type = cell_data[i, 7] end end end end #============================================================================ # ■ Sprite_Character #---------------------------------------------------------------------------- # Calculate x-coordinate and y-coordinate for a neoM7 map #============================================================================ class Sprite_Character < RPG::Sprite #-------------------------------------------------------------------------- # * Aliased methods (F12 compatibility) #-------------------------------------------------------------------------- if !@already_aliased alias update_neoM7_sprite_character update @already_aliased = true end #-------------------------------------------------------------------------- # * Update #-------------------------------------------------------------------------- def update if !$game_system.neoM7 update_neoM7_sprite_character return end super if @tile_id != @character.tile_id or @character_name != @character.character_name or @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 if @character.is_a?(Game_Player) and FileTest.exist?("Graphics/Characters/" + @character.character_name + "_m7.png") self.bitmap = RPG::Cache.character(@character.character_name + "_m7", @character.character_hue) else self.bitmap = RPG::Cache.character(@character.character_name, @character.character_hue) end @cw = bitmap.width / 4 @ch = bitmap.height / @character.directions self.ox = @cw / 2 self.oy = @ch # pivot correction (intersection between the map and this sprite) self.oy -= 4 end end self.visible = (not @character.transparent) if @tile_id == 0 sx = @character.pattern * @cw current_direction = (@character.direction - 2) / 2 if $scene.spriteset != nil and $scene.spriteset.tilemap.is_a?(Tilemap_neoM7) directions_list = $dirs[@character.directions] list_size = directions_list.size current_direction = directions_list[(directions_list.index(current_direction) + (($scene.spriteset.tilemap.theta + (180 / list_size)) % 360) / (360 / list_size)) % list_size] end sy = current_direction * @ch self.src_rect.set(sx, sy, @cw, @ch) self.length = @cw self.height = @ch end x_intermediate = @character.screen_x y_intermediate = @character.screen_y - 4 if $game_system.neoM7_loop diff_y = ($game_player.y - @character.y).to_i offset_y = ($game_map.height << 5) * (diff_y >= 0 ? (diff_y / ($game_map.height >> 1)) : (diff_y / ($game_map.height >> 1)) + 1) diff_x = ($game_player.x - @character.x).to_i offset_x = ($game_map.width << 5) * (diff_x >= 0 ? (diff_x / ($game_map.width >> 1)) : (diff_x / ($game_map.width >> 1)) + 1) neoM7_character(x_intermediate + offset_x, y_intermediate + offset_y) else neoM7_character(x_intermediate, y_intermediate) end if !on_screen_x(x) or !on_screen_y(y) self.opacity = 0 return end neoM7_zoom(x, y) self.opacity = 255 self.z = 4 * y 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 if $game_system.neoM7_loop diff_y = ($game_player.y - y_map).to_i offset_y = $game_map.height * (diff_y >= 0 ? (diff_y / ($game_map.height >> 1)) : (diff_y / ($game_map.height >> 1)) + 1) diff_x = ($game_player.x - x_map).to_i offset_x = $game_map.width * (diff_x >= 0 ? (diff_x / ($game_map.width >> 1)) : (diff_x / ($game_map.width >> 1)) + 1) neoM7(x_map + offset_x, y_map + offset_y) else neoM7(x_map, y_map) end if !on_screen_x(x) or !on_screen_y(y) self.opacity = 0 return end neoM7_zoom(x, y) self.opacity = 255 self.z = 4 * y + 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 neoM7 map #============================================================================ class Spriteset_Map #-------------------------------------------------------------------------- # * Aliased methods (F12 compatibility) #-------------------------------------------------------------------------- if !@already_aliased alias initialize_neoM7_spriteset_map initialize alias update_neoM7_spriteset_map update @already_aliased = true end #-------------------------------------------------------------------------- # * Attributes #-------------------------------------------------------------------------- attr_accessor :tilemap # just to be able to access the tilemap #-------------------------------------------------------------------------- # * Initialize Object # Rewritten to call a map with neoM7 #-------------------------------------------------------------------------- def initialize if !$game_system.neoM7 initialize_neoM7_spriteset_map return end @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 # neoM7 map @tilemap = Tilemap_neoM7.new(@viewport1, self) @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.neoM7 ? -100000 : -1000) @fog = Plane.new(@viewport1) @fog.z = 3000 @character_sprites = [] for i in $game_map.events.keys.sort sprite = Sprite_Character.new(@viewport1, $game_map.events[i]) @character_sprites.push(sprite) end @character_sprites.push(Sprite_Character.new(@viewport1, $game_player)) @weather = RPG::Weather.new(@viewport1) @picture_sprites = [] for i in 1..50 @picture_sprites.push(Sprite_Picture.new(@viewport2, $game_screen.pictures[i])) end @timer_sprite = Sprite_Timer.new update update if $game_system.neoM7_filter end #-------------------------------------------------------------------------- # * Dispose #-------------------------------------------------------------------------- def dispose if @tilemap.tileset != nil @tilemap.tileset.dispose for i in 0..6 @tilemap.autotiles[i].dispose end end @tilemap.dispose @panorama.dispose @fog.dispose for sprite in @character_sprites sprite.dispose end @weather.dispose for sprite in @picture_sprites sprite.dispose end @timer_sprite.dispose @viewport1.dispose @viewport2.dispose @viewport3.dispose end #-------------------------------------------------------------------------- # * Update #-------------------------------------------------------------------------- def update if !$game_system.neoM7 update_neoM7_spriteset_map return end if @panorama_name != $game_map.panorama_name or @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 or @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 if @fog_name != "" @fog.bitmap = RPG::Cache.fog(@fog_name, @fog_hue) end Graphics.frame_reset end # update animated tiles each 20 frames if Graphics.frame_count % 20 == 0 and $game_system.neoM7_animated @tilemap.update_animated end @tilemap.update # to have a fluent panorama scrolling @panorama.ox = 6 * ((tilemap.theta * 4.0 / 3).to_i) @panorama.oy = - $game_temp.neoM7_height_limit @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 for sprite in @character_sprites sprite.update end @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 for sprite in @picture_sprites sprite.update end @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 #============================================================================ # Neo Mode 7 # Written by MGCaladtogel # 12/05/08 # # Part 4 # # class Scene_Map : spriteset = attr_accessor # # class Bitmap # neoM7 : new method # clean_limit : new method # # class Data_Autotiles : new class # # class Data_Vertical_Sprites : new class # # class RPG::Cache_Tile : new class # # class RPG::Cache_Datamap : new class # # class RPG::Cache_Tileset : new class # # class RPG::Cache # self.autotile_base : new method # self.save_autotile : new method # self.load_autotile : new method # # class RPG::MapInfo # name : redefined # name2 : new method # #============================================================================ #============================================================================ # ■ Scene_Map #============================================================================ class Scene_Map #-------------------------------------------------------------------------- # * Attributes #-------------------------------------------------------------------------- attr_accessor :spriteset # just need to access the spriteset end #============================================================================ # ■ Bitmap #---------------------------------------------------------------------------- # Add neoM7 functions (dll calls) #============================================================================ class Bitmap #-------------------------------------------------------------------------- # mode 7 transformation #-------------------------------------------------------------------------- def neoM7(function, tileset, data, map_width, map_height, off_x, off_y) raise RGSSError.new("Disposed bitmap") if disposed? func=Win32API.new("MGCmode7.dll", function, "llllllllllllllll", "") func.call(self.__id__, tileset.__id__, data.__id__, off_x, off_y, $game_temp.cos_alpha, $game_temp.sin_alpha, $game_temp.distance_h, $game_temp.pivot_map, $game_temp.slope_value_map, $game_temp.corrective_value_map, $game_temp.neoM7_height_limit, $game_temp.cos_theta, $game_temp.sin_theta, $game_temp.distance_p, $game_temp.zoom_map) end #-------------------------------------------------------------------------- # delete pixels beyond the horizon #-------------------------------------------------------------------------- def clean_limit(old_limit, new_limit) raise RGSSError.new("Disposed bitmap") if disposed? func=Win32API.new("MGCmode7.dll", "CleanHeightLimit", "lll", "") func.call(self.__id__, old_limit, new_limit) end 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]] #-------------------------------------------------------------------------- # * Attributes #-------------------------------------------------------------------------- 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) for i in 0..5 for j in 0..7 data = Data_creation[8 * i + j] for number in data 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 end 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 #-------------------------------------------------------------------------- # * Attributes #-------------------------------------------------------------------------- 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 for h in 0..2 # scan each row for i in 0..$game_map.height # scan each column for j in 0..$game_map.width value = @dataV[j, i, h].to_i # if tile's terrain tag is declared to give vertical sprites if $terrain_tags_vertical_tiles.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 and 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 for k in (j2 + 1)..(j2 + length -1) 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 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 and 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 and 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 if list_start2 < list_start list_start = list_start2 end 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 end end end #-------------------------------------------------------------------------- # * Clear the used data to prevent from reusing them # layer : current scanned layer #-------------------------------------------------------------------------- def clear_data(layer) for num in @num_tiles @dataV[num[0], num[1], layer] = 0 end 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((1+width)<<5, (1+height)<<5) 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 for tile_coordinates in @num_tiles 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) end sprite.list_bitmap.push(bmp) # create 3 additionnal bitmaps for animated sprites if sprite.animated for j in 1..3 bmp = Bitmap.new((1 + width)<<5, (1 + height)<<5) for tile_coordinates in @num_tiles 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((tile_coordinates[0] - column)<<5, (tile_coordinates[1] - row)<<5, bitmap, rect) end sprite.list_bitmap.push(bmp) end 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)>>6) 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.height = bmp.height sprite.length = bmp.width 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 module Cache_Tile @cache = {} #------------------------------------------------------------------------ # * Superimposing of two tiles, offset = pattern's number for animated # autotiles #------------------------------------------------------------------------ def self.load(value1, value2, offset=0) if not @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 = ((value1 / 48) - 1)<<2 + 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 = ((value2 / 48) - 1)<<2 + offset bitmap.blt(0, 0, RPG::Cache.autotile_base(num, value2), rect) end @cache[[value1, value2, offset]] = bitmap end @cache[[value1, value2, offset]] end #------------------------------------------------------------------------ # * Superimposing of three tiles #------------------------------------------------------------------------ def self.load2(value1, value2, value3, offset = 0) if not @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 = ((value1 / 48) - 1)<<2 + 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 = ((value2 / 48) - 1)<<2 + 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 = ((value3 / 48) - 1)<<2 + offset bitmap.blt(0, 0, RPG::Cache.autotile_base(num, value3), rect) end @cache[[value1, value2, value3, offset]] = bitmap end @cache[[value1, value2, value3, offset]] end #------------------------------------------------------------------------ # * Clear the Cache #------------------------------------------------------------------------ def self.clear @cache = {} GC.start end end end #============================================================================ # ■ RPG::Cache_Datamap #---------------------------------------------------------------------------- # Maps drawn with neoM7 are kept in memory to have a faster call the next # times they need to be drawn #============================================================================ module RPG module Cache_Datamap @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 end #============================================================================ # ■ RPG::Cache_Tileset #---------------------------------------------------------------------------- # Maps drawn with neoM7 are kept in memory to have a faster call the next # times they need to be drawn #============================================================================ module RPG module Cache_Tileset @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 end #============================================================================ # ■ RPG::Cache #---------------------------------------------------------------------------- # The tiles from autotiles files are kept in memory for a faster call #============================================================================ module RPG module 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 not @cache.include?(key) or @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 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 #============================================================================ # Neo Mode 7 # Written by MGCaladtogel # 12/05/08 # # Part 5 # # class Tilemap_neoM7 : new class # #============================================================================ #============================================================================ # ■ Tilemap_neoM7 #---------------------------------------------------------------------------- # This new Tilemap class handles the drawing of a neo neoM7 map #============================================================================ class Tilemap_neoM7 #-------------------------------------------------------------------------- # * Attributes #-------------------------------------------------------------------------- attr_accessor :tilesets_list # contains tilesets graphics attr_reader :spriteset # spriteset that called this class attr_accessor :sprite # sprite used to contain the map's drawing attr_accessor :alpha # angle of slant attr_accessor :theta # angle of rotation #-------------------------------------------------------------------------- # * Object Initialization # viewport : viewport #-------------------------------------------------------------------------- def initialize(viewport, spriteset) @even = true @viewport = viewport @spriteset = spriteset @id = $game_map.map_id # map's ID : used to load or save the map in Cache self.tilesets_list = [] # contains tilesets (Bitmap) @height = $game_map.height << 5 # @height : map's height (in pixel) @width = $game_map.width << 5 # @width : map's width (in pixel) @function_name = "BitmapMode7" # dll's function called to apply mode 7 @function_name += "Loop" if $game_system.neoM7_loop @current_function_name = @function_name @zoom = $game_system.neoM7_zoom # zoom level of the map $game_temp.zoom_sprites = @zoom.to_f / 100 $game_temp.zoom_map = (4096 * (1.0 / $game_temp.zoom_sprites)).to_i # tilesets graphics and data map are loaded if already in Cache if RPG::Cache_Datamap.in_cache(@id) @bitmap_data = RPG::Cache_Datamap.load(@id) @map_tileset = RPG::Cache_Tileset.load(@id) self.tilesets_list.push(@map_tileset) if $game_system.neoM7_animated @map_tileset_2 = RPG::Cache_Tileset.load(@id, 1) @map_tileset_3 = RPG::Cache_Tileset.load(@id, 2) @map_tileset_4 = RPG::Cache_Tileset.load(@id, 3) self.tilesets_list.push(@map_tileset_2) self.tilesets_list.push(@map_tileset_3) self.tilesets_list.push(@map_tileset_4) end else # draw the data map and the tileset and save them in the Cache draw_map end # create vertical elements from tiles data_V = Data_Vertical_Sprites.new(viewport) # @vertical_sprites : list of vertical sprites (Sprite_V) @vertical_sprites = data_V.list_sprites_V # @vertical_sprites_animated : list of animated vertical sprites (Sprite_V) @vertical_sprites_animated = data_V.list_sprites_V_animated # angle of rotation (theta) self.theta = $game_system.neoM7_theta theta_rad = (Math::PI * theta) / 180 # easier to work with integer value than floats ('>>' and '<<' operations) $game_temp.cos_theta = (4096 * Math.cos(theta_rad)).to_i $game_temp.sin_theta = (4096 * Math.sin(theta_rad)).to_i # offsets : equivalent to display_x and display_y @offset_x = 0 @offset_y = 0 $game_temp.distance_h = 480 # distance between the center of the map (halfwidth, pivot) and the point of view # screenline's number of the slant's pivot = y-coordinate of the rotation center $game_temp.pivot = $game_system.neoM7_pivot # character sprites $game_temp.pivot_map = $game_temp.pivot / ($game_system.neoM7_resolution == 1 ? 1 : ($game_system.neoM7_resolution == 2 ? 1.33 : 2)) # map sprite # distance between the center of the map (halfwidth, pivot) and the projection plane surface $game_temp.distance_p = $game_temp.distance_h - $game_temp.distance_h / ($game_system.neoM7_resolution == 1 ? 1 : ($game_system.neoM7_resolution == 2 ? 1.334 : 2)) # zoom value of the map sprite @coeff_resolution = ($game_system.neoM7_resolution == 1 ? 1 : ($game_system.neoM7_resolution == 2 ? 1.334 : 2)) # x-offset for the 3 resolutions @offset_x_res = ($game_system.neoM7_resolution == 1 ? 0 : ($game_system.neoM7_resolution == 2 ? 80 : 160)) # y-offset for the 3 resolutions @offset_y_res = $game_temp.pivot - $game_temp.pivot_map @index_animated = 0 # 0..3 : index of animated tiles pattern # map sprite self.sprite = Sprite.new(@viewport) self.sprite.x = 0 self.sprite.y = 0 self.sprite.z = - 99999 # map must not mask vertical elements if $game_system.neoM7_resolution != 1 self.sprite.bitmap = ($game_system.neoM7_resolution == 2 ? Bitmap.new(480, 360) : Bitmap.new(320, 240)) else self.sprite.bitmap = Bitmap.new(640, 480) # screen dimensions end # angle of slant (alpha) self.alpha = $game_system.neoM7_alpha refresh_alpha end #-------------------------------------------------------------------------- # * Dispose #-------------------------------------------------------------------------- def dispose # dispose of map sprite and vertical sprites self.sprite.dispose for sprite in @vertical_sprites + @vertical_sprites_animated sprite.dispose end @vertical_sprites.clear @vertical_sprites_animated.clear @tilesets_list.clear end #-------------------------------------------------------------------------- # * Refresh all the parameters dependent on the angle of slant #-------------------------------------------------------------------------- def refresh_alpha # angle of slant alpha_rad = (Math::PI * alpha) / 180 $game_temp.cos_alpha = (4096 * Math.cos(alpha_rad)).to_i $game_temp.sin_alpha = (4096 * Math.sin(alpha_rad)).to_i $game_system.neoM7_alpha = alpha $game_system.neoM7_pivot = $game_temp.pivot # h0, z0 : intermediate values used to calculate the slope h0 = (- ($game_temp.distance_h) * $game_temp.pivot * $game_temp.cos_alpha) / ((($game_temp.distance_h) << 12) + $game_temp.pivot * $game_temp.sin_alpha) + $game_temp.pivot z0 = (($game_temp.distance_h) << 12).to_f / ((($game_temp.distance_h) << 12) + $game_temp.pivot * $game_temp.sin_alpha) # slope $game_temp.slope_value = (1.0 - z0) / ($game_temp.pivot - h0) $game_temp.slope_value_map = (262144 * $game_temp.slope_value).to_i $game_temp.corrective_value = 1.0 - $game_temp.pivot * $game_temp.slope_value $game_temp.corrective_value_map = (262144 * $game_temp.corrective_value / @coeff_resolution).to_i last_line = - $game_temp.pivot_map - $game_system.neoM7_horizon old_limit = $game_temp.neoM7_height_limit $game_temp.neoM7_height_limit = (($game_temp.distance_h - $game_temp.distance_p) * last_line * $game_temp.cos_alpha) / ((($game_temp.distance_h) << 12) - last_line * $game_temp.sin_alpha) + $game_temp.pivot_map if $game_system.neoM7_white_horizon @current_function_name = @function_name + ($game_temp.neoM7_height_limit > 0 ? "H" : "") end $game_temp.neoM7_height_limit = [$game_temp.neoM7_height_limit.to_i, 0].max $game_temp.height_limit_sprites = $game_temp.neoM7_height_limit * @coeff_resolution @even = ((old_limit - $game_temp.neoM7_height_limit) % 2 == 0 ? @even : !@even) # delete lines beyond the new horizon self.sprite.bitmap.clean_limit(old_limit, $game_temp.neoM7_height_limit) if old_limit < $game_temp.neoM7_height_limit end #-------------------------------------------------------------------------- # * Increase (or decrease) the angle of slant #-------------------------------------------------------------------------- def increase_alpha(value) self.alpha = [[alpha + value, 89].min, 0].max refresh_alpha end #-------------------------------------------------------------------------- # * Increase (or decrease) the angle of rotation #-------------------------------------------------------------------------- def increase_theta(value) self.theta += value self.theta %= 360 theta_rad = (Math::PI * theta) / 180 $game_temp.cos_theta = (4096 * Math.cos(theta_rad)).to_i $game_temp.sin_theta = (4096 * Math.sin(theta_rad)).to_i $game_system.neoM7_theta = theta end #-------------------------------------------------------------------------- # * Increase (or decrease) the zoom level #-------------------------------------------------------------------------- def increase_zoom(value) value = value.to_f / 100 @zoom = [[@zoom * (2 ** value), 10000].min, 1].max $game_temp.zoom_sprites = @zoom.to_f / 100 $game_temp.zoom_map = (4096 * (1.0 / $game_temp.zoom_sprites)).to_i $game_system.neoM7_zoom = @zoom end #-------------------------------------------------------------------------- # * Increase the pivot's value #-------------------------------------------------------------------------- def increase_pivot(value) res = [[$game_temp.pivot + value, 480].min, 32].max $game_map.display_y -= ((res - $game_temp.pivot) << 2) $game_system.neoM7_center_y += ((res - $game_temp.pivot) << 2) $game_temp.pivot = res $game_temp.pivot_map = $game_temp.pivot / ($game_system.neoM7_resolution == 1 ? 1 : ($game_system.neoM7_resolution == 2 ? 1.33 : 2)) @offset_y_res = $game_temp.pivot - $game_temp.pivot_map refresh_alpha end #-------------------------------------------------------------------------- # * Set the angle of slant #-------------------------------------------------------------------------- def set_alpha(value) self.alpha = [[value, 89].min, 0].max refresh_alpha end #-------------------------------------------------------------------------- # * Set the angle of rotation #-------------------------------------------------------------------------- def set_theta(value) self.theta = value % 360 theta_rad = (Math::PI * theta) / 180 $game_temp.cos_theta = (4096 * Math.cos(theta_rad)).to_i $game_temp.sin_theta = (4096 * Math.sin(theta_rad)).to_i $game_system.neoM7_theta = theta end #-------------------------------------------------------------------------- # * Set the zoom level #-------------------------------------------------------------------------- def set_zoom(value) @zoom = [[value, 10000].min, 1].max $game_temp.zoom_sprites = @zoom.to_f / 100 $game_temp.zoom_map = (4096 * (1.0 / $game_temp.zoom_sprites)).to_i $game_system.neoM7_zoom = @zoom end #-------------------------------------------------------------------------- # * Set the pivot's value #-------------------------------------------------------------------------- def set_pivot(value) res = [[value, 480].min, 32].max $game_map.display_y -= ((res - $game_temp.pivot) << 2) $game_system.neoM7_center_y += ((res - $game_temp.pivot) << 2) $game_temp.pivot = res $game_temp.pivot_map = $game_temp.pivot / ($game_system.neoM7_resolution == 1 ? 1 : ($game_system.neoM7_resolution == 2 ? 1.33 : 2)) @offset_y_res = $game_temp.pivot - $game_temp.pivot_map refresh_alpha end #-------------------------------------------------------------------------- # * Slide from the current alpha into the target value #-------------------------------------------------------------------------- def to_alpha(value, speed) value = [[value, 89].min, 0].max while value > alpha increase_alpha([speed, value - alpha].min) spriteset.update Graphics.update end while value < alpha increase_alpha(-([speed, alpha - value].min)) spriteset.update Graphics.update end end #-------------------------------------------------------------------------- # * Slide from the current theta into the target value #-------------------------------------------------------------------------- def to_theta(value, speed, direction) value %= 360 while value != theta increase_theta(direction * ([(value - theta).abs, speed].min)) spriteset.update Graphics.update end end #-------------------------------------------------------------------------- # * Slide from the current zoom level into the target value #-------------------------------------------------------------------------- def to_zoom(value, speed) value = [[value, 10000].min, 1].max while value > @zoom increase_zoom(speed) if value < @zoom set_zoom(value) end spriteset.update Graphics.update end while value < @zoom increase_zoom(-speed) if value > @zoom set_zoom(value) end spriteset.update Graphics.update end end #-------------------------------------------------------------------------- # * Slide from the current pivot's value into the target value #-------------------------------------------------------------------------- def to_pivot(value, speed) value = [[value, 480].min, 32].max while value > $game_temp.pivot increase_pivot([speed, value - $game_temp.pivot].min) spriteset.update Graphics.update end while value < $game_temp.pivot increase_pivot(-([speed, $game_temp.pivot - value].min)) spriteset.update Graphics.update end end #-------------------------------------------------------------------------- # * Update the map sprite and the vertical sprites #-------------------------------------------------------------------------- def update # update map sprite @offset_x = $game_map.display_x / 4 + @offset_x_res @offset_y = $game_map.display_y / 4 + @offset_y_res current_function_name = @current_function_name if $game_system.neoM7_filter current_function_name += (@even ? "Even" : "Odd") @even = !@even end self.sprite.bitmap.neoM7(current_function_name, @map_tileset, @bitmap_data, @width, @height, @offset_x, @offset_y) self.sprite.zoom_x = @coeff_resolution self.sprite.zoom_y = @coeff_resolution # update vertical sprites for vertical_sprite in @vertical_sprites vertical_sprite.update end end #-------------------------------------------------------------------------- # * Update animation for animated tiles #-------------------------------------------------------------------------- def update_animated @index_animated += 1 @index_animated %= 4 @map_tileset = tilesets_list[@index_animated] # update vertical sprites for vertical_sprite in @vertical_sprites_animated vertical_sprite.update_animated(@index_animated) end end #-------------------------------------------------------------------------- # * Create a data bitmap representing the map, and its associated tilesets #-------------------------------------------------------------------------- def draw_map data = $game_map.data # Table where animated tiles are flagged data_animated = [] # Bitmap that will be filled with the 3-layers map data @bitmap_data = Bitmap.new(@width / 32, @height / 32) color = Color.new(0,0,0) rect = Rect.new(0, 0, 32, 32) # Create autotiles graphics RPG::Cache.clear @autotiles = [] for i in 0..6 autotile_name = $game_map.autotile_names[i] fichier = RPG::Cache.autotile(autotile_name) for l in 0..3 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) end end # Create a list of used terrain tiles (3 layers), and fill the data bitmap tiles_list = {} tiles_count = 0 for i in 0...$game_map.height for j in 0...$game_map.width value1 = ($terrain_tags_vertical_tiles.include?( $game_map.terrain_tags[data[j, i, 0]]) ? 0 : data[j, i, 0]) value2 = ($terrain_tags_vertical_tiles.include?( $game_map.terrain_tags[data[j, i, 1]]) ? 0 : data[j, i, 1]) value3 = ($terrain_tags_vertical_tiles.include?( $game_map.terrain_tags[data[j, i, 2]]) ? 0 : data[j, i, 2]) if !tiles_list.has_key?([value1, value2, value3]) tiles_count += 1 tiles_list[[value1, value2, value3]] = tiles_count end count = tiles_list[[value1, value2, value3]] color.set(count % 256, count / 256, 0) # up to 65536 different tiles for one map (should be sufficient) @bitmap_data.set_pixel(j, i, color) end end # Create a specific tileset (using the 3 layers) for the map tileset_height = (1 + (tiles_count / 8)) * 32 @map_tileset = Bitmap.new(256, tileset_height) @tilesets_list.push(@map_tileset) for k in 1..tiles_count list_values = tiles_list.index(k) value1 = list_values[0] value2 = list_values[1] value3 = list_values[2] if value1 != 0 if value2 == 0 if value3 == 0 if value1 > 383 bitmap = RPG::Cache.tile($game_map.tileset_name, value1, 0) else num = 4*((value1 / 48) - 1) bitmap = RPG::Cache.autotile_base(num, value1) data_animated.push(k) if @autotiles[num].animated end else bitmap = RPG::Cache_Tile.load(value1, value3) animated = false if value1 < 384 num = 4*((value1 / 48) - 1) animated = @autotiles[num].animated end if value3 < 384 num = 4*((value3 / 48) - 1) animated = @autotiles[num].animated end data_animated.push(k) if animated end else if value3 == 0 bitmap = RPG::Cache_Tile.load(value1, value2) animated = false if value1 < 384 num = 4*((value1 / 48) - 1) animated = @autotiles[num].animated end if value2 < 384 num = 4*((value2 / 48) - 1) animated = @autotiles[num].animated end data_animated.push(k) if animated else bitmap = RPG::Cache_Tile.load2(value1, value2, value3) animated = false if value1 < 384 num = 4*((value1 / 48) - 1) animated = @autotiles[num].animated end if value2 < 384 num = 4*((value2 / 48) - 1) animated = @autotiles[num].animated end if value3 < 384 num = 4*((value3 / 48) - 1) animated = @autotiles[num].animated end data_animated.push(k) if animated end end else if value2 == 0 if value3 != 0 if value3 > 383 bitmap = RPG::Cache.tile($game_map.tileset_name, value3, 0) else num = 4*((value3 / 48) - 1) bitmap = RPG::Cache.autotile_base(num, value3) data_animated.push(k) if @autotiles[num].animated end end else if value3 == 0 if value2 > 383 bitmap = RPG::Cache.tile($game_map.tileset_name, value2, 0) else num = 4*((value2 / 48) - 1) bitmap = RPG::Cache.autotile_base(num, value2) data_animated.push(k) if @autotiles[num].animated end else bitmap = RPG::Cache_Tile.load(value2, value3) animated = false if value2 < 384 num = 4*((value2 / 48) - 1) animated = @autotiles[num].animated end if value3 < 384 num = 4*((value3 / 48) - 1) animated = @autotiles[num].animated end data_animated.push(k) if animated end end end @map_tileset.blt(32 * ((k - 1) % 8), 32 * ((k - 1) / 8), bitmap, rect) end # save the data map and the tileset in the Cache RPG::Cache_Datamap.save(@id, @bitmap_data) RPG::Cache_Tileset.save(@id, @map_tileset) # create 3 other tilesets in case of animated tiles (4 patterns) if !$game_system.neoM7_animated tiles_list.clear return end @map_tileset_2 = @map_tileset.clone @map_tileset_3 = @map_tileset.clone @map_tileset_4 = @map_tileset.clone @tilesets_list.push(@map_tileset_2) @tilesets_list.push(@map_tileset_3) @tilesets_list.push(@map_tileset_4) for k in data_animated list_values = tiles_list.index(k) value1 = list_values[0] value2 = list_values[1] value3 = list_values[2] 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) 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) end else if 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) 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) end end else if value2 != 0 if value3 == 0 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) 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) end else if value3 != 0 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) end end end @map_tileset_2.blt(32 * ((k - 1) % 8), 32 * ((k - 1) / 8), bitmap_2, rect) @map_tileset_3.blt(32 * ((k - 1) % 8), 32 * ((k - 1) / 8), bitmap_3, rect) @map_tileset_4.blt(32 * ((k - 1) % 8), 32 * ((k - 1) / 8), bitmap_4, rect) end # save the three additional maps in the Cache RPG::Cache_Tileset.save(@id, @map_tileset_2, 1) RPG::Cache_Tileset.save(@id, @map_tileset_3, 2) RPG::Cache_Tileset.save(@id, @map_tileset_4, 3) tiles_list.clear end #-------------------------------------------------------------------------- # * no tileset for neoM7 maps #-------------------------------------------------------------------------- def tileset return nil end end
Inserite dopo il nome della mappa questi codici per attivare il Mode 7
[NM7] Attiva il Mode 7
[#XX] Sceglie l'angolo di rotazione (Asse Y) in verticale, al posto di XX mettete l'angolo.
[%XXX] Sceglie l'angolo di rotazione (Asse X) in orizzontale, al posto di XXX mettete l'angolo.
Ideale per creare mappe isometriche.
[A] Autotiles Animati
[H] Orizzonte bianco
[RX] Scegli Risoluzione al posto di X mettere 1, 2 o 3
[F] Attiva filtro (per migliorare le prestazioni)
[L] Loop mappa
Codici da evento
Per ora sono in inglese, non ho il tempo di tradurli.
Vanno inseriti in un evento tramite il comando Script
To set a new angle of slant (0~89) :
$scene.spriteset.tilemap.set_alpha(new angle)
To slide progressively into a new angle of slant :
$scene.spriteset.tilemap.to_alpha(new angle, speed)
To increase/decrease the slant :
$scene.spriteset.tilemap.increase_alpha(value)
- To set a new angle of rotation (0~379) :
$scene.spriteset.tilemap.set_theta(new angle)
To slide progressively into a new angle of rotation :
$scene.spriteset.tilemap.to_theta(angle, speed, dir)
To increase/decrease the angle of rotation :
$scene.spriteset.tilemap.increase_theta(value)
- To set a new zoom level :
$scene.spriteset.tilemap.set_zoom(new value)
To slide progressively into a new zoom level :
$scene.spriteset.tilemap.to_zoom(value, speed)
To increase/decrease the zoom level :
$scene.spriteset.tilemap.increase_zoom(value)
The pivot's value (32~480) represents the screenline's number considered as the axis for map trasformations.
By default its value is 256.
To set a new value :
$scene.spriteset.tilemap.set_pivot(new value)
To slide progressively into a new pivot's value :
$scene.spriteset.tilemap.to_pivot(value, speed)
To increase/decrease the pivot's value :
$scene.spriteset.tilemap.increase_pivot(value)
- Pivot's value and zoom level are saved from
one map to another. You have to reinitialize
them manually if you need it.
Bugs e Conflitti Noti
Funziona solo con Rpg Maker XP 1.02, la demo però si puo aprire anche con l'1.01, ma se modificate il progetto e lo salvate compaiono errori
Con Rpg maker VX non ho ancora provato, ma dovrebbe funzionare.
Modificato da Dilos, 26 April 2013 - 14:52 PM.
Applicato tag code.