Sujet n°10306
Posté par Guigui28240 le 28 Aoû - 21:33 (2011)
Titre : Neo Mode 7
bonjour a tous
J'ai decouvert il y a peu le script Neo Mode 7 et quand je l'ai testé et j'ai decouvert qu'il marchait avec PSP DS.
Pour ceux qui veulent:

NM7 Part 1
#============================================================================
# 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 = [3, 4] # 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 = 50
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
 

NM7 Part 2
#============================================================================
# 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

# Surf
if self_event != nil
if $game_map.terrain_tag(x, y) == 7 and self_event.terrain_tag != 7
return false
end
if $game_map.terrain_tag(x, y) != 7 and self_event.terrain_tag == 7
if self_event.type == Game_Player
# Retour au skin normal
$game_temp.common_event_id = POKEMON_S::Skill_Info.map_use(POKEMON_S::Skill_Info.id("SURF"))
end
return false
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 = true
$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
$game_system.neoM7_loop = map_data.name2.include?("[L]")
$game_system.neoM7_animated = map_data.name2
$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
time_before_move = 4.7
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
if Input.dir4 != 0
if @turn_count == nil
@turn_count = 0
end
@turn_count += 1.175 if @turn_count < time_before_move
else
@turn_count = 0
end
case Input.dir4
when 2
@turn_count == time_before_move ? move_down : turn_down
$look = 2
when 4
@turn_count == time_before_move ? move_left : turn_left
$look = 4
when 6
@turn_count == time_before_move ? move_right : turn_right
$look = 6
when 8
@turn_count == time_before_move ? move_up : turn_up
$look = 8
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 Input.trigger?(Input::C)
# 同位置および正面のイベント起動判定
check_event_trigger_here([0])
check_event_trigger_there([0,1,2])
# Implémentation Surf
if $game_map.passable?(front_tile[0],front_tile[1], 10 - $game_player.direction) and
terrain_tag != 7 and $game_map.terrain_tag(front_tile[0], front_tile[1]) == 7 and
not $game_system.map_interpreter.running?
$game_temp.common_event_id = POKEMON_S::Skill_Info.map_use(POKEMON_S::Skill_Info.id("SURF"))
end
if $game_map.passable?(front_tile[0],front_tile[1], 10 - $game_player.direction) and
terrain_tag != 6 and $game_map.terrain_tag(front_tile[0], front_tile[1]) == 6 and
not $game_system.map_interpreter.running?
$game_temp.common_event_id = POKEMON_S::Skill_Info.map_use(POKEMON_S::Skill_Info.id("SURF"))
end
end
end
end
end


NM7 Part 3
#============================================================================
# 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
pattern = cell_data
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
sprite.y += zoom_y * cell_data
sprite.z = z
sprite.ox = 96
sprite.oy = 96
sprite.zoom_x = zoom_x * cell_data / 100.0
sprite.zoom_y = zoom_y * cell_data / 100.0
sprite.angle = cell_data
sprite.mirror = (cell_data == 1)
sprite.opacity = cell_data * self.opacity / 255.0
sprite.blend_type = cell_data
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
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(-180, -130, 450, 350)
@viewport2 = Viewport.new(0, 0, 533, 572)
@viewport3 = Viewport.new(-180, -130, 450, 350)
@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)
@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))
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.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


NM7 Part 4
#============================================================================
# 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


NM7 Part 5
#============================================================================
# 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
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


voila c'est pour ceux qui veulent apres.
A bientôt

Posté par Epistol le 28 Aoû - 21:36 (2011)
J'essayerais demain, gare à toi si ça lag XD.

Posté par Guigui28240 le 28 Aoû - 21:50 (2011)
ah oui desolé voici l'anti-lag je suis tête en l'air ^^

Anti-lag:
#===============================================================================
# ** AntiLag Script
#-------------------------------------------------------------------------------
# f0tz!baerchen
# 0.71
# 06.01.2007
#-------------------------------------------------------------------------------
# Credits:
# Chaosg1 (for testing ;) )
# NearFantastica (for the Event AntiLag I used and improved)
# Thomas6497 pour une petite modification de vitesse x)
#-------------------------------------------------------------------------------
# Features:
# - Event AntiLag: Event (and their Sprites) which are not on the screen are
# not updated except they run on "Autostart" or "Parallel Process" or they
# have an empty comment in the first line
# - High Priority: Game can be run on high priority
# - Smooth Antilag: the Event AntiLag does only work fine if the events are
# distributed over the whole map, but when there are many events at the same
# place it lags again. If the script notices that the CPU utilization
# gets higher than $antilag.max_cpu_utilization it will slow down the game and
# reduce the framerate as long as needed.
#-------------------------------------------------------------------------------
# Settings:
# can be changed anytime during the game. They are found at the end of the
# script.
#===============================================================================
#===============================================================================
# Class for Antilag Settings
#===============================================================================
class Antilag_Settings

attr_accessor :event
attr_accessor :max_cpu_utilization
attr_accessor :cpu_tolerance
#-----------------------------------------------------------------------------
# initializes default settings
#-----------------------------------------------------------------------------
def initialize
@event = true
@high_priority = true
@max_cpu_utilization = 100
@cpu_tolerance = 40
@SetPriorityClass = Win32API.new('kernel32', 'SetPriorityClass',
['p', 'i'], 'i')
@GetProcessTimes = Win32API.new('kernel32', 'GetProcessTimes',
['i','p','p','p','p'], 'i')
end
#-----------------------------------------------------------------------------
# turns high priority on/off
#-----------------------------------------------------------------------------
def high_priority=(value)
@high_priority = value

if @high_priority
@SetPriorityClass.call(-1, 0x00000080) # High Priority
else
@SetPriorityClass.call(-1, 0x00000020) # Normal Priority
end
end
#-----------------------------------------------------------------------------
# returns the current CPU Utilization
#-----------------------------------------------------------------------------
def get_cpu_utilization
# uses API Call to get the Kernel and User Time
creation_time = '0' * 10
exit_time = '0' * 10
kernel_time = '0' * 10
user_time = '0' * 10
@GetProcessTimes.call(-1, creation_time, exit_time, kernel_time, user_time)
# converts times into integer (in 100ns)
kernel_time = kernel_time.unpack('l2')
user_time = user_time.unpack('l2')
kernel_time = kernel_time[0] + kernel_time[1]
user_time = user_time[0] + user_time[1]
# takes differences to calculate cpu utilization
if @old_time != nil
timer_difference = Time.new - @old_timer
time_difference = kernel_time + user_time - @old_time
result = time_difference / timer_difference / 100000
else
result = $antilag.max_cpu_utilization
end
# saves values (to calculate the differences, s.a.)
@old_timer = Time.new
@old_time = kernel_time + user_time
return result
end
end
$antilag = Antilag_Settings.new
#===============================================================================
# Scene_Map class
#===============================================================================
class Scene_Map
#-----------------------------------------------------------------------------
# update method, smooth antilag has been added
#-----------------------------------------------------------------------------
alias f0tzis_anti_lag_scene_map_update update
def update
f0tzis_anti_lag_scene_map_update
if Graphics.frame_count % 20 == 0 and $antilag.max_cpu_utilization <= 100
# calculates difference between max utilization and current utilization
abs = $antilag.max_cpu_utilization - $antilag.get_cpu_utilization
# changes Frame Rate if difference is bigger than the tolerance
if abs.abs >= $antilag.max_cpu_utilization * $antilag.cpu_tolerance/100.0
Graphics.frame_rate = [[10, Graphics.frame_rate + abs / 2].max, 40].min
end
end
end
end
#==============================================================================
# Game_Event Class
#===============================================================================
class Game_Event
#-----------------------------------------------------------------------------
# for AntiLag, decides, if an event is on the screen or not.
#-----------------------------------------------------------------------------
def in_range?

# returns true if $event_antilag is false or the event is an
# Autostart/Parallel Process event or it has an empty
# comment in the first line
if not $antilag.event or (@trigger == 3 or @trigger == 4 or
(@list != nil and @list[0].code == 108 and @list[0].parameters == ['']))
return true
end

screne_x = $game_map.display_x
screne_x -= 256
screne_y = $game_map.display_y
screne_y -= 256
screne_width = $game_map.display_x
screne_width += 2816
screne_height = $game_map.display_y
screne_height += 2176

return false if @real_x <= screne_x
return false if @real_x >= screne_width
return false if @real_y <= screne_y
return false if @real_y >= screne_height
return true

end
#-----------------------------------------------------------------------------
# update method
#-----------------------------------------------------------------------------
alias f0tzis_anti_lag_game_event_update update
def update
return if not self.in_range?
f0tzis_anti_lag_game_event_update
end

end
#===============================================================================
# Sprite_Character Class
#===============================================================================
class Sprite_Character < RPG::Sprite
#-----------------------------------------------------------------------------
# update method, parameters added for Loop_Map, rebuild for 8dirs
#-----------------------------------------------------------------------------
alias f0tzis_anti_lag_sprite_char_update update
def update
return if @character.is_a?(Game_Event) and not @character.in_range?
f0tzis_anti_lag_sprite_char_update
end

end
#===============================================================================
# Settings
#===============================================================================
$antilag.max_cpu_utilization = 70 # the maximum CPU utilization, the script
# try to stay under this value during changing
# changing the frame rate. The lower this
# value the higher will be the lag reduction
# (and the smoothness, too), a value > 100
# will disable this feature completely
$antilag.cpu_tolerance = 20 # this value tells the script how many % of
# the CPU utilization change should be ignored
# If you change it too a higher value you,
# your Frame Rate will be more constant but
# smaller lags will be ignored.
$antilag.high_priority = true # set this to true if you want the game to run
# on high priority
$antilag.event = true # set this to true to enable normal anti-lag
#===============================================================================
# Interpreter Class
#===============================================================================
class Interpreter
#-----------------------------------------------------------------------------
# * Script
#-----------------------------------------------------------------------------
def command_355
# Set first line to script
script = @list[@index].parameters[0] + "\n"
# Loop
loop do
# If next event command is second line of script or after
if @list[@index+1].code == 655
# Add second line or after to script
script += @list[@index+1].parameters[0] + "\n"
# If event command is not second line or after
else
# Abort loop
break
end
# Advance index
@index += 1
end
# Evaluation
result = eval(script)
#---------------------------------------------------------------------------
# If return value is false
# NEW: the last word of the code mustnt be false!
#---------------------------------------------------------------------------
if result == false and script[script.length-6..script.length-2] != 'false'
# End
return false
end
# Continue
return true
end
end

Posté par Brendan75 le 28 Aoû - 21:51 (2011)
Merci de bien vouloir utiliser la balise Code.

Posté par Guigui28240 le 28 Aoû - 21:55 (2011)
désolé je suis nul je sais pas comment on fait XP

Posté par Nuri Yuri le 28 Aoû - 21:56 (2011)
Les scripts du NéoMode 7 ont été enlevé du forum pour une bonne raison ça serai gentil de ne par les remettre et de laisser les membres qui le veulent chercher.

Posté par Solfay le 28 Aoû - 21:58 (2011)
Je n'utiliserais pas ton script, mais merci pour l'anti-lag, en espérant qu'il marche bien 42 .

Posté par IamTheAdic le 28 Aoû - 21:58 (2011)
Arrêtez avec ce script incompatible avec PSP. Le NM7 c'est la merde. Votre projet - va lagguer - va avoir des bugs tout le temps.

Si je vous vois poster dans le ST des bugs à cause du NM7, je ne vous répondrais pas.

Posté par Guigui28240 le 28 Aoû - 21:58 (2011)
Je sais mais si sa se trouve y en a qui ne le trouvent pas donc je les aides 

Posté par IamTheAdic le 28 Aoû - 21:59 (2011)
ça ne les aide pas, ça pourri leur projet.

Posté par Nuri Yuri le 28 Aoû - 22:00 (2011)
Au pire le sujet pourrait être archivé demain soir pour ne pas avoir à faire face à ces problèmes.
@GuiGui : On s'en fou, ils se démerdent, après ils nous prennent pour un support technique de NM7 alors on peut s'en passer.

Posté par Guigui28240 le 28 Aoû - 22:02 (2011)
ok je suis d'accord donc je les laisse se débrouiller.

Posté par Nuri Yuri le 28 Aoû - 22:07 (2011)
C'est pour le bien de tous. Puis si ils veulent des scripts ils doivent savoir où chercher.

Posté par Guigui28240 le 28 Aoû - 22:31 (2011)
ok je comprend tres bien donc je le garde pour moi

Posté par Nuri Yuri le 28 Aoû - 22:32 (2011)
Je déplace maintenant alors.