Jump to content
New account registrations are disabed. This website is now an archive. Read more here.
  • 0

Question

19 answers to this question

Recommended Posts

  • 0

Try posting the script maybe then someone might be able to help.

 

The script has instructions, but they aren't that clear to me.

#==============================================================================

# Mode 7

# Written by: MGCaladtogel

# Version: unknown

# English version date: 21.5.2007

#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=

# - instruction rewritten by Blizzard for easier understanding.

# - slightly optimized by Blizzard

#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=

#

# Introduction:

#

# This script can display maps in a type of 3D with depth. It has a low lag

# factor.

#

#

# Instructions:

#

# In the editor in the lower left corner is the map list of the maps you

# are using in your game. You have several options: If you want to make a

# map use Mode 7 you need to ADD one or more of these text commands to the

# map's name. Those commands should not appear in the map's name if using

# a location display script. The options you have are the following:

#

# [M7] : to activate Mode7

# [#XX] : XX is the slant angle (in degree). Default value is 0 (normal maps)

# [Y] : Y-map looping

# [X] : X-map looping. This option needs resources (lower fps).

# [A] : animated autotiles (with 4 patterns). This option increases

# significantly the loading time, so it may crash for large maps

# (SystemStackError)

# [C] : to center the map on the hero (even for small maps)

# [P] : to have a fixed panorama

# [H] : to have a white horizon

# [OV] : Overworld Sprite Resize (a Mewsterus's script feature)

#

# Alternatively you can define prepared settings that will be triggered with

# every map that has that specific text included in its name. See the

# "MODE7_SETTINGS" below to prepare your settings.

#

#

# Control commands:

#

# You can change the settings on the map in-game and use a couple of

# additional commands. If you want to use one of those commands, use a "Call

# Script" event command and type one of the following commands into the text

# input window:

#

# 1. $scene.spriteset.tilemap.mode7_set(ANGLE)

# 2. $scene.spriteset.tilemap.mode7_set_p(ANGLE)

# 3. $scene.spriteset.tilemap.mode7_redraw

# 4. $game_system.map_opacity = VALUE

# 5. $game_system.map_gradual_opacity = VALUE

# 6. $game_system.map_tone = Color.new(RED, GREEN, BLUE)

# 7. $game_system.map_gradual_tone = Tone.new(RED, GREEN, BLUE, GREY)

# 8. $game_system.horizon = VALUE

# 9. $game_system.reset

#

# 1. Redraws the map with a new angle which is specified by ANGLE

# 2. Redraws the map progressively with a new angle which is specified by

# ANGLE

# 3. Redraws the map (can be useful with the following commands)

# 4. Defines the opacity for Mode7 maps (it needs to redraw)

# 5. Defines a gradual opacity for Mode7 maps (it needs to redraw)

# (it bugs with horizontal looping)

# 6. Defines the tone for Mode7 maps (it needs to redraw)

# 7. Defines a gradual tone for Mode7 maps (it needs to redraw)

# 8. Defines the view's distance (default : 960) (it needs to redraw)

# 9. Re-initialize the previous options

#

#

# Additional commands:

#

# 1) If you wish to obtain flat events, add a comment in the event's code

# and type in the word "Flat" without the double quotes).

# 2) You can handle the height of vertical events by adding a comment to the

# event's code with the text "Height X" (without the double quotes).

# Replace X with the height value. Example: If you use Height 1.5, then

# the event will appear floating above its position in a height of 1.5 map

# squares (48 pixels).

#

#==============================================================================

 

# hash for predefined settings

MODE7_SETTINGS = {}

# access for map names

$data_maps = load_data("Data/MapInfos.rxdata")

 

#---------------------#

# START Configuration #

#---------------------#

 

# The map is drawn from all the tiles of the three layers. You can define tiles

# which are not being drawn flat, but vertical which creates the impression

# that the objects would be standing upright.

# To define such tiles, add one or more terrain tags to this array and separate

# them with commas. In your tileset database gives those specific tiles one of

# those terrain tags and the tile will be drawn vertically.

VERTICAL_TILE_TERRAIN_TAGS = [1, 2]

 

# You can create packages of settings which are automatically triggered if a

# map name includes the text corresponding to the setting. Use following

# template to create such settings:

#

# MODE7_SETTINGS['CORRESPONDING_TEXT'] = ['SETTING_1', 'SETTING_2', ...]

#

# CORRESPONDING_TEXT - text in map name

# SETTING - one of the settings from the instructions WITHOUT the

# [ and ] brackets (i.e. instead of [H], use just H)

#

# You can add as many settings as you want. There are two predefined settings

# to make you understand easier how it works.

 

MODE7_SETTINGS['World Map'] = ['#60', 'X', 'Y', 'H', 'P']

MODE7_SETTINGS['Smallslant'] = ['#20', 'A', 'S']

 

#---------------------#

# END Configuration #

#---------------------#

 

#============================================================================

# ■ Game_System

#----------------------------------------------------------------------------

# Add attributes to this class

#============================================================================

 

class Game_System

attr_accessor :mode7 # false : normal map / true : mode 7

attr_accessor :loop_x # true : horizontal-looping map

attr_accessor :loop_y # true : vertical-looping map

attr_accessor :always_scroll # true : to center the camera around the hero

attr_accessor :map_tone # mode7 map's tone (Color)

attr_accessor :map_opacity # mode7 map's opacity (0..255)

attr_accessor :animated # true : animated autotiles for mode7 maps

attr_accessor :white_horizon # true : white line horizon for mode7 maps

attr_accessor :angle # mode7 map's slant angle (in degree)

attr_accessor :horizon # horizon's distance

attr_accessor :fixed_panorama # true : to fix the panorama (no scrolling any more)

attr_accessor :ov # true : Overworld Sprite Resize (smaller hero's sprite)

attr_accessor :ov_zoom # resize's value with ov

attr_accessor :map_gradual_opacity # mode7 map's gradual opacity (0..255)

attr_accessor :map_gradual_tone # mode7 map's gradual tone (Color)

#--------------------------------------------------------------------------

# * Object Initialization

#--------------------------------------------------------------------------

alias initialize_mode7_game_system initialize

def initialize

initialize_mode7_game_system

init_mode7

end

#--------------------------------------------------------------------------

# * Mode 7 Initialization

#--------------------------------------------------------------------------

def init_mode7

self.mode7 = true

self.loop_x = false

self.loop_y = false

self.always_scroll = false

self.animated = false

self.white_horizon = false

self.angle = 0

self.fixed_panorama = false

self.ov = false

self.ov_zoom = 0.6

reset

end

#--------------------------------------------------------------------------

# * Reset the values for opacity, tone and horizon's distance

#--------------------------------------------------------------------------

def reset

self.map_opacity = 255

self.map_tone = Color.new(0,0,0,0)

self.horizon = 960 # default value, equivalent to 30 tiles

self.map_gradual_opacity = 0

self.map_gradual_tone = Tone.new(0,0,0,0)

end

end

 

#============================================================================

# ■ Tilemap_mode7

#----------------------------------------------------------------------------

# This new Tilemap class handles the drawing of a mode7 map

#============================================================================

 

class Tilemap_mode7

attr_accessor :maps_list # contains map's graphics

attr_accessor :map_ground # original map's graphic to handle flat events

attr_accessor :tone_values # tone values for each line (Hash)

attr_accessor :opacity_values # opacity values for each line (Hash)

#--------------------------------------------------------------------------

# * Object Initialization

# viewport : viewport

#--------------------------------------------------------------------------

def initialize(viewport)

@id = $game_map.map_id # map's ID : to load or save the map in Cache

@maps_list = [] # contains map's drawings (Bitmap)

@disp_y = $game_map.display_y # @disp_y : tilemap's display_y

@disp_x = $game_map.display_x # @disp_x : tilemap's display_x

@height = 32 * $game_map.height # @height : map's height (in pixel)

@width = 32 * $game_map.width # @width : map's width (in pixel)

$game_temp.height = @height

# map's drawings are loaded if already in Cache

if RPG::Cache_Carte.in_cache(@id)

@map = RPG::Cache_Carte.load(@id)

@maps_list.push(@map)

@map_ground = RPG::Cache_Carte.load(@id, 4) # to handle flat events

if $game_system.animated

@map_2 = RPG::Cache_Carte.load(@id, 1)

@map_3 = RPG::Cache_Carte.load(@id, 2)

@map_4 = RPG::Cache_Carte.load(@id, 3)

@maps_list.push(@map_2)

@maps_list.push(@map_3)

@maps_list.push(@map_4)

end

else # draw the map and save it in the Cache

draw_map

end

# create vertical elements from tiles

data_V = Data_Vertical_Sprites.new(viewport)

# @sprites_V : list of vertical sprites (Sprite_V)

@sprites_V = data_V.list_sprites_V

# @sprites_V_animated : list of animated vertical sprites (Sprite_V)

@sprites_V_animated = data_V.list_sprites_V_animated

@angle = $game_system.angle # map's slant angle (in degree)

@distance_h = 480 # distance between the map's center and the vanishing point

@pivot = 256 # screenline's number of the slant's pivot

@index_animated = 0 # 0..3 : index of animated tiles pattern

@viewport = viewport

@tone_values = {} # list of the tone values for each line

@opacity_values = {} # list of the opacity values for each line

init_sprites(@angle) # initialize screenlines sprites

end

#--------------------------------------------------------------------------

# * Dispose

#--------------------------------------------------------------------------

def dispose

# dispose of @sprites (scanlines), @sprites_V (vertical_sprites), and

# @sprites_loop_x (additional scanlines for horizontal looping)

(@sprites + @sprites_V + @sprites_loop_x).each {|sprite| sprite.dispose}

[@sprites, @sprites_V, @sprites_loop_x, @sprites_V_animated,

@maps_list].each {|obj| obj.clear}

$game_system.angle = @angle

end

#--------------------------------------------------------------------------

# * Increase slant's angle

#--------------------------------------------------------------------------

def increase_angle

return if @angle == 88

@angle += 2

@angle = 88 if @angle > 88

@sprites.clear

@sprites_loop_x.clear

init_sprites(@angle) # reinitialize screenlines sprites

end

#--------------------------------------------------------------------------

# * Decrease slant's angle

#--------------------------------------------------------------------------

def decrease_angle

return if @angle == 0

@angle -= 2

@angle = 0 if @angle < 0

@sprites.clear

@sprites_loop_x.clear

init_sprites(@angle) # reinitialize screenlines sprites

end

#--------------------------------------------------------------------------

# * Slide from the current angle into the target value

# value : target angle's value (in degree)

#--------------------------------------------------------------------------

def mode7_set_p(value)

while value > @angle

increase_angle

update

Graphics.update

end

while value < @angle

decrease_angle

update

Graphics.update

end

end

#--------------------------------------------------------------------------

# * Redraw the map instantaneously with the new slant angle's value

# value : target angle's value (in degree)

#--------------------------------------------------------------------------

def mode7_set(value)

if value < 0

@angle = 0

elsif value > 89

@angle = 89

else

@angle = value

end

@sprites.clear

@sprites_loop_x.clear

init_sprites(@angle) # reinitialize screenlines sprites

update

Graphics.update

end

#--------------------------------------------------------------------------

# * Reinitialize screenlines sprites

#--------------------------------------------------------------------------

def mode7_redraw

@sprites.clear

@sprites_loop_x.clear

init_sprites(@angle) # reinitialize scanlines

update

Graphics.update

end

#--------------------------------------------------------------------------

# * Create sprites equivalent to scanlines

# value : target angle's value (in degree)

#--------------------------------------------------------------------------

def init_sprites(angle)

@horizon = $game_system.horizon

angle_rad = (Math::PI * angle) / 180 # angle in radian

@sprites = [] # list of the scanlines sprites (Sprite)

@sprites_loop_x = [] # list of the additionnal sprites (for X-looping)

cos_angle = Math.cos(angle_rad)

sin_angle = Math.sin(angle_rad)

# save values in $game_temp

$game_temp.distance_h = @distance_h

$game_temp.pivot = @pivot

$game_temp.cos_angle = cos_angle

$game_temp.sin_angle = sin_angle

# h0, z0 : intermediate values

h0 = (- @distance_h * @pivot * cos_angle).to_f /

(@distance_h + @pivot * sin_angle) + @pivot

z0 = @distance_h.to_f / (@distance_h + @pivot * sin_angle)

$game_temp.slope_value = (1.0 - z0) / (@pivot - h0)

$game_temp.corrective_value = 1.0 - @pivot * $game_temp.slope_value

last_line = - @pivot - @horizon # last_line : the highest line that is drawn

height_limit = (@distance_h * last_line * cos_angle).to_f /

(@distance_h - last_line * sin_angle) + @pivot # the line corresponding to

# the last_line in the warped reference = horizon's line

$game_temp.height_limit = height_limit

# constant to handle gradual opacity

k2lim = ((@distance_h * last_line).to_f /

(@distance_h * cos_angle + last_line * sin_angle)).to_i

# one sprite is created for each screenline

(0..479).each {|j|

next if j < height_limit # if the line is further than the horizon's line,

# no sprite is created

i = j - @pivot # y-reference is the pivot's line

sprite = Sprite.new(@viewport)

sprite.x = 320 # x-reference is the vertical line in the middle of the screen

sprite.y = j

sprite.z = - 99999 # map must not mask vertical elements

sprite.y_origin_bitmap = (@distance_h * i).to_f /

(@distance_h * cos_angle + i * sin_angle) + @pivot

sprite.y_origin_bitmap_i = (sprite.y_origin_bitmap + 0.5).to_i

sprite.y_origin_bitmap_i %= @height if $game_system.loop_y

sprite.zoom_x = $game_temp.slope_value * j + $game_temp.corrective_value

sprite.length = 2 + (640.to_f / sprite.zoom_x).to_i

sprite.x_origin_bitmap_i = ((642 - sprite.length) / 2)

sprite.x_origin_bitmap_i %= @width if $game_system.loop_x

sprite.x_origin_bitmap = (sprite.x_origin_bitmap_i).to_f

sprite.ox = sprite.length / 2

sprite.bitmap = @map

# horizontal translation to center around the hero

if @disp_x != 0

sprite.x_origin_bitmap += @disp_x / 4

sprite.x_origin_bitmap_i = (sprite.x_origin_bitmap).to_i

sprite.x_origin_bitmap_i %= @width if $game_system.loop_x

end

# vertical translation to center around the hero

if @disp_y != 0

sprite.y_origin_bitmap += @disp_y / 4

sprite.y_origin_bitmap_i = (sprite.y_origin_bitmap + 0.5).to_i

sprite.y_origin_bitmap_i %= @height if $game_system.loop_y

end

# handle opacity and tone

k2 = ((@distance_h * i).to_f /

(@distance_h * cos_angle + i * sin_angle)).to_i

k2 = 0 if k2 > 0

k_red = (- k2.to_f/k2lim * $game_system.map_gradual_tone.red).to_i

k_green = (- k2.to_f/k2lim * $game_system.map_gradual_tone.green).to_i

k_blue = (- k2.to_f/k2lim * $game_system.map_gradual_tone.blue).to_i

k_gray = (- k2.to_f/k2lim * $game_system.map_gradual_tone.gray).to_i

k2 = (- k2.to_f/k2lim * $game_system.map_gradual_opacity).to_i

sprite.tone = Tone.new(k_red, k_green, k_blue, k_gray)

sprite.opacity = 255 - k2

sprite.opacity *= ($game_system.map_opacity).to_f / 255

sprite.color = $game_system.map_tone

# white horizon's line

k = 500 / (j - height_limit)

if $game_system.white_horizon

tone_red = sprite.tone.red + k

tone_green = sprite.tone.green + k

tone_blue = sprite.tone.blue + k

tone_gray = sprite.tone.gray + k

sprite.tone = Tone.new(tone_red, tone_green, tone_blue, tone_gray)

end

@tone_values[j] = sprite.tone

@opacity_values[j] = sprite.opacity

# set sprite's graphics

sprite.src_rect.set(sprite.x_origin_bitmap_i, sprite.y_origin_bitmap_i,

sprite.length, 1)

@sprites.push(sprite)

if $game_system.loop_x && j < @pivot

# additional sprite to handle horizontal looping

sprite2 = Sprite.new(@viewport)

sprite2.x = 320

sprite2.y = j

sprite2.z = - 99999

sprite2.y_origin_bitmap = sprite.y_origin_bitmap

sprite2.y_origin_bitmap_i = sprite.y_origin_bitmap_i

sprite2.zoom_x = sprite.zoom_x

sprite2.length = sprite.length

sprite2.x_origin_bitmap_i = sprite.x_origin_bitmap_i - @width

sprite2.x_origin_bitmap = sprite.x_origin_bitmap_i - @width

sprite2.ox = sprite.ox

sprite2.bitmap = @map

sprite2.opacity = sprite.opacity

sprite2.color = sprite.color

sprite2.tone = sprite.tone

sprite2.src_rect.set(sprite2.x_origin_bitmap_i, sprite2.y_origin_bitmap_i,

sprite2.length, 1)

@sprites_loop_x.push(sprite2)

end}

end

#--------------------------------------------------------------------------

# * Update the screenlines sprites and the vertical sprites

# compare tilemap's display with map's display

#--------------------------------------------------------------------------

def update

# update screenlines sprites

if @disp_y < $game_map.display_y

difference = $game_map.display_y - @disp_y

@disp_y += difference

(@sprites + @sprites_loop_x).each {|sprite|

sprite.y_origin_bitmap += difference.to_f / 4

sprite.y_origin_bitmap_i = (sprite.y_origin_bitmap+0.5).to_i

sprite.y_origin_bitmap_i %= @height if $game_system.loop_y

sprite.src_rect.set(sprite.x_origin_bitmap_i, sprite.y_origin_bitmap_i,

sprite.length, 1)}

end

if @disp_y > $game_map.display_y

difference = @disp_y - $game_map.display_y

@disp_y -= difference

(@sprites + @sprites_loop_x).each {|sprite|

sprite.y_origin_bitmap -= difference.to_f / 4

sprite.y_origin_bitmap_i = (sprite.y_origin_bitmap+0.5).to_i

sprite.y_origin_bitmap_i %= @height if $game_system.loop_y

sprite.src_rect.set(sprite.x_origin_bitmap_i, sprite.y_origin_bitmap_i,

sprite.length, 1)}

end

if @disp_x < $game_map.display_x

difference = $game_map.display_x - @disp_x

@disp_x += difference

@sprites.each {|sprite|

sprite.x_origin_bitmap += difference.to_f / 4

sprite.x_origin_bitmap_i = (sprite.x_origin_bitmap).to_i

sprite.x_origin_bitmap_i %= @width if $game_system.loop_x

sprite.src_rect.set(sprite.x_origin_bitmap_i, sprite.y_origin_bitmap_i,

sprite.length, 1)}

@sprites_loop_x.each {|sprite|

sprite.x_origin_bitmap += difference.to_f / 4

sprite.x_origin_bitmap_i = (sprite.x_origin_bitmap).to_i

sprite.x_origin_bitmap_i %= @width

sprite.x_origin_bitmap_i -= @width

sprite.src_rect.set(sprite.x_origin_bitmap_i, sprite.y_origin_bitmap_i,

sprite.length, 1)}

end

if @disp_x > $game_map.display_x

difference = @disp_x - $game_map.display_x

@disp_x -= difference

@sprites.each {|sprite|

sprite.x_origin_bitmap -= difference.to_f / 4

sprite.x_origin_bitmap_i = (sprite.x_origin_bitmap).to_i

sprite.x_origin_bitmap_i %= @width if $game_system.loop_x

sprite.src_rect.set(sprite.x_origin_bitmap_i, sprite.y_origin_bitmap_i,

sprite.length, 1)}

@sprites_loop_x.each {|sprite|

sprite.x_origin_bitmap -= difference.to_f / 4

sprite.x_origin_bitmap_i = (sprite.x_origin_bitmap).to_i

sprite.x_origin_bitmap_i %= @width

sprite.x_origin_bitmap_i -= @width

sprite.src_rect.set(sprite.x_origin_bitmap_i, sprite.y_origin_bitmap_i,

sprite.length, 1)}

end

# update vertical sprites

@sprites_V.each {|sprite| sprite.update}

end

#--------------------------------------------------------------------------

# * Update animation for animated tiles

#--------------------------------------------------------------------------

def update_animated

@index_animated += 1

@index_animated %= 4

map = @maps_list[@index_animated]

# update screenlines sprites

(@sprites + @sprites_loop_x).each {|sprite|

sprite.bitmap = map

sprite.src_rect.set(sprite.x_origin_bitmap_i, sprite.y_origin_bitmap_i,

sprite.length, 1)}

# update vertical sprites

@sprites_V_animated.each {|sprite| sprite.update_animated(@index_animated)}

end

#--------------------------------------------------------------------------

# * Create bitmaps representing the map

#--------------------------------------------------------------------------

def draw_map

data = $game_map.data

# Table where animated tiles are flagged

data_animated = Table.new($game_map.width, $game_map.height)

# bigger maps to handle horizontal looping

offset = ($game_system.loop_x ? 640 : 0)

@map = Bitmap.new(@width + offset, @height)

@maps_list.push(@map)

rect = Rect.new(0, 0, 32, 32)

# create autotiles graphics

RPG::Cache.clear

@autotiles = []

(0..6).each {|i|

autotile_name = $game_map.autotile_names

fichier = RPG::Cache.autotile(autotile_name)

(0..3).each {|l|

data_autotile = Data_Autotiles.new(fichier,l)

data_autotile.number = 4*i + l

RPG::Cache.save_autotile(data_autotile, data_autotile.number)

@autotiles.push(data_autotile)}}

# scan map's data to draw it

(0...$game_map.height).each {|i| (0...$game_map.width).each {|j|

data_animated[j, i] = 0

# tile's ID for the first layer

value1 = data[j, i, 0].to_i

# prevent from drawing a vertical tile

value1 = (VERTICAL_TILE_TERRAIN_TAGS.include?($game_map.terrain_tags[value1]) ?

0 : value1)

# value1 != 0

if value1 != 0

# tile's ID for the second layer

value2 = data[j, i, 1].to_i

# prevent from drawing a vertical tile

value2 = (VERTICAL_TILE_TERRAIN_TAGS.include?($game_map.terrain_tags[value2]) ?

0 : value2)

# tile's ID for the third layer

value3 = data[j, i, 2].to_i

# prevent from drawing a vertical tile

value3 = (VERTICAL_TILE_TERRAIN_TAGS.include?($game_map.terrain_tags[value3]) ?

0 : value3)

# value1 != 0, value2 = 0

if value2 == 0

# value1 != 0, value2 = 0, value3 = 0

if value3 == 0

# value1 associated with a normal autotile

if value1 > 383

bitmap = RPG::Cache.tile($game_map.tileset_name, value1, 0)

@map.blt(32*j, 32*i, bitmap, rect)

if $game_system.loop_x && j.between?(0, 19)

@map.blt(32*(j+$game_map.width), 32*i, bitmap, rect)

end

# value1 associated with an autotile

else

num = 4*((value1 / 48) - 1)

bitmap = RPG::Cache.autotile_base(num, value1)

if @autotiles[num].animated

data_animated[j, i] = 1

end

@map.blt(32*j, 32*i, bitmap, rect)

if $game_system.loop_x && j.between?(0, 19)

@map.blt(32*(j+$game_map.width), 32*i, bitmap, rect)

end

end

# value1 != 0, value2 = 0, value3 != 0

else

bitmap = RPG::Cache_Tile.load(value1, value3)

# value1 associated with an autotile

if value1 < 384

num = 4*((value1 / 48) - 1)

data_animated[j, i] = 1 if @autotiles[num].animated

end

# value3 associated with an autotile

if value3 < 384

num = 4*((value3 / 48) - 1)

data_animated[j, i] = 1 if @autotiles[num].animated

end

@map.blt(32*j, 32*i, bitmap, rect)

if $game_system.loop_x && j.between?(0, 19)

@map.blt(32*(j+$game_map.width), 32*i, bitmap, rect)

end

end

# value1 != 0, value2 != 0, value3 = 0

elsif value3 == 0

bitmap = RPG::Cache_Tile.load(value1, value2)

# value1 associated with an autotile

if value1 < 384

num = 4*((value1 / 48) - 1)

data_animated[j, i] = 1 if @autotiles[num].animated

end

# value2 associated with an autotile

if value2 < 384

num = 4*((value2 / 48) - 1)

data_animated[j, i] = 1 if @autotiles[num].animated

end

@map.blt(32*j, 32*i, bitmap, rect)

if $game_system.loop_x && j.between?(0, 19)

@map.blt(32*(j+$game_map.width), 32*i, bitmap, rect)

end

# value1 != 0, value2 != 0, value3 != 0

else

bitmap = RPG::Cache_Tile.load2(value1, value2, value3)

# value1 associated with an autotile

if value1 < 384

num = 4*((value1 / 48) - 1)

data_animated[j, i] = 1 if @autotiles[num].animated

end

# value2 associated with an autotile

if value2 < 384

num = 4*((value2 / 48) - 1)

data_animated[j, i] = 1 if @autotiles[num].animated

end

# value3 associated with an autotile

if value3 < 384

num = 4*((value3 / 48) - 1)

data_animated[j, i] = 1 if @autotiles[num].animated

end

@map.blt(32*j, 32*i, bitmap, rect)

if $game_system.loop_x && j.between?(0, 19)

@map.blt(32*(j+$game_map.width), 32*i, bitmap, rect)

end

end

# value1 = 0

else

value2 = data[j, i, 1].to_i

value2 = (VERTICAL_TILE_TERRAIN_TAGS.include?($game_map.terrain_tags[value2]) ?

0 : value2)

value3 = data[j, i, 2].to_i

value3 = (VERTICAL_TILE_TERRAIN_TAGS.include?($game_map.terrain_tags[value3]) ?

0 : value3)

# value1 = 0, value2 = 0

if value2 == 0

# value1 = 0, value2 = 0, value3 != 0

if value3 != 0

# value3 associated with a normal tile

if value3 > 383

bitmap = RPG::Cache.tile($game_map.tileset_name, value3, 0)

@map.blt(32*j, 32*i, bitmap, rect)

if $game_system.loop_x && j.between?(0, 19)

@map.blt(32*(j+$game_map.width), 32*i, bitmap, rect)

end

# value3 associated with an autotile

else

num = 4*((value3 / 48) - 1)

bitmap = RPG::Cache.autotile_base(num, value3)

if @autotiles[num].animated

data_animated[j, i] = 1

end

@map.blt(32*j, 32*i, bitmap, rect)

if $game_system.loop_x && j.between?(0, 19)

@map.blt(32*(j+$game_map.width), 32*i, bitmap, rect)

end

end

end

# value1 = 0, value2 != 0, value3 = 0

elsif value3 == 0

# value2 associated with a normal tile

if value2 > 383

bitmap = RPG::Cache.tile($game_map.tileset_name, value2, 0)

@map.blt(32*j, 32*i, bitmap, rect)

if $game_system.loop_x && j.between?(0, 19)

@map.blt(32*(j+$game_map.width), 32*i, bitmap, rect)

end

# value2 associated with an autotile

else

num = 4*((value2 / 48) - 1)

bitmap = RPG::Cache.autotile_base(num, value2)

if @autotiles[num].animated

data_animated[j, i] = 1

end

@map.blt(32*j, 32*i, bitmap, rect)

if $game_system.loop_x && j.between?(0, 19)

@map.blt(32*(j+$game_map.width), 32*i, bitmap, rect)

end

end

# value1 = 0, value2 != 0, value3 != 0

else

bitmap = RPG::Cache_Tile.load(value2, value3)

# value2 associated with an autotile

if value2 < 384

num = 4*((value2 / 48) - 1)

data_animated[j, i] = 1 if @autotiles[num].animated

end

# value3 associated with an autotile

if value3 < 384

num = 4*((value3 / 48) - 1)

data_animated[j, i] = 1 if @autotiles[num].animated

end

@map.blt(32*j, 32*i, bitmap, rect)

if $game_system.loop_x && j.between?(0, 19)

@map.blt(32*(j+$game_map.width), 32*i, bitmap, rect)

end

end

end}}

# save the map's drawing in the Cache

RPG::Cache_Carte.save(@id, @map)

@map_ground = @map.clone

# save a copy of the map to handle flat events

RPG::Cache_Carte.save(@id, @map_ground, 4)

return if !$game_system.animated

# create 3 other maps in case of animated tiles

@map_2 = @map.clone

@map_3 = @map.clone

@map_4 = @map.clone

@maps_list.push(@map_2)

@maps_list.push(@map_3)

@maps_list.push(@map_4)

(0...$game_map.height).each {|i| (0...$game_map.width).each {|j|

next if data_animated[j, i].to_i == 0

# modify the tile if it is flagged as animated

value1 = data[j, i, 0].to_i

value2 = data[j, i, 1].to_i

value3 = data[j, i, 2].to_i

# prevent from drawing a vertical tile

value1 = (VERTICAL_TILE_TERRAIN_TAGS.include?($game_map.terrain_tags[value3]) ?

0 : value3)

value2 = (VERTICAL_TILE_TERRAIN_TAGS.include?($game_map.terrain_tags[value3]) ?

0 : value3)

value3 = (VERTICAL_TILE_TERRAIN_TAGS.include?($game_map.terrain_tags[value3]) ?

0 : value3)

if value1 != 0

if value2 == 0

if value3 == 0

num = 4*((value1 / 48) - 1)

bitmap_2 = RPG::Cache.autotile_base(num+1, value1)

bitmap_3 = RPG::Cache.autotile_base(num+2, value1)

bitmap_4 = RPG::Cache.autotile_base(num+3, value1)

@map_2.blt(32*j, 32*i, bitmap_2, rect)

@map_3.blt(32*j, 32*i, bitmap_3, rect)

@map_4.blt(32*j, 32*i, bitmap_4, rect)

if $game_system.loop_x && j.between?(0, 19)

@map_2.blt(32*(j+$game_map.width), 32*i, bitmap_2, rect)

@map_3.blt(32*(j+$game_map.width), 32*i, bitmap_3, rect)

@map_4.blt(32*(j+$game_map.width), 32*i, bitmap_4, rect)

end

else

bitmap_2 = RPG::Cache_Tile.load(value1, value3, 1)

bitmap_3 = RPG::Cache_Tile.load(value1, value3, 2)

bitmap_4 = RPG::Cache_Tile.load(value1, value3, 3)

@map_2.blt(32*j, 32*i, bitmap_2, rect)

@map_3.blt(32*j, 32*i, bitmap_3, rect)

@map_4.blt(32*j, 32*i, bitmap_4, rect)

if $game_system.loop_x && j.between?(0, 19)

@map_2.blt(32*(j+$game_map.width), 32*i, bitmap_2, rect)

@map_3.blt(32*(j+$game_map.width), 32*i, bitmap_3, rect)

@map_4.blt(32*(j+$game_map.width), 32*i, bitmap_4, rect)

end

end

elsif value3 == 0

bitmap_2 = RPG::Cache_Tile.load(value1, value2, 1)

bitmap_3 = RPG::Cache_Tile.load(value1, value2, 2)

bitmap_4 = RPG::Cache_Tile.load(value1, value2, 3)

@map_2.blt(32*j, 32*i, bitmap_2, rect)

@map_3.blt(32*j, 32*i, bitmap_3, rect)

@map_4.blt(32*j, 32*i, bitmap_4, rect)

if $game_system.loop_x && j.between?(0, 19)

@map_2.blt(32*(j+$game_map.width), 32*i, bitmap_2, rect)

@map_3.blt(32*(j+$game_map.width), 32*i, bitmap_3, rect)

@map_4.blt(32*(j+$game_map.width), 32*i, bitmap_4, rect)

end

else

bitmap_2 = RPG::Cache_Tile.load2(value1, value2, value3, 1)

bitmap_3 = RPG::Cache_Tile.load2(value1, value2, value3, 2)

bitmap_4 = RPG::Cache_Tile.load2(value1, value2, value3, 3)

@map_2.blt(32*j, 32*i, bitmap_2, rect)

@map_3.blt(32*j, 32*i, bitmap_3, rect)

@map_4.blt(32*j, 32*i, bitmap_4, rect)

if $game_system.loop_x && j.between?(0, 19)

@map_2.blt(32*(j+$game_map.width), 32*i, bitmap_2, rect)

@map_3.blt(32*(j+$game_map.width), 32*i, bitmap_3, rect)

@map_4.blt(32*(j+$game_map.width), 32*i, bitmap_4, rect)

end

end

elsif value2 != 0

if value3 == 0

num = 4*((value2 / 48) - 1)

bitmap_2 = RPG::Cache.autotile_base(num+1, value2)

bitmap_3 = RPG::Cache.autotile_base(num+2, value2)

bitmap_4 = RPG::Cache.autotile_base(num+3, value2)

@map_2.blt(32*j, 32*i, bitmap_2, rect)

@map_3.blt(32*j, 32*i, bitmap_3, rect)

@map_4.blt(32*j, 32*i, bitmap_4, rect)

if $game_system.loop_x && j.between?(0, 19)

@map_2.blt(32*(j+$game_map.width), 32*i, bitmap_2, rect)

@map_3.blt(32*(j+$game_map.width), 32*i, bitmap_3, rect)

@map_4.blt(32*(j+$game_map.width), 32*i, bitmap_4, rect)

end

else

bitmap_2 = RPG::Cache_Tile.load(value2, value3, 1)

bitmap_3 = RPG::Cache_Tile.load(value2, value3, 2)

bitmap_4 = RPG::Cache_Tile.load(value2, value3, 3)

@map_2.blt(32*j, 32*i, bitmap_2, rect)

@map_3.blt(32*j, 32*i, bitmap_3, rect)

@map_4.blt(32*j, 32*i, bitmap_4, rect)

if $game_system.loop_x && j.between?(0, 19)

@map_2.blt(32*(j+$game_map.width), 32*i, bitmap_2, rect)

@map_3.blt(32*(j+$game_map.width), 32*i, bitmap_3, rect)

@map_4.blt(32*(j+$game_map.width), 32*i, bitmap_4, rect)

end

end

elsif value3 != 0

num = 4*((value3 / 48) - 1)

bitmap_2 = RPG::Cache.autotile_base(num+1, value3)

bitmap_3 = RPG::Cache.autotile_base(num+2, value3)

bitmap_4 = RPG::Cache.autotile_base(num+3, value3)

@map_2.blt(32*j, 32*i, bitmap_2, rect)

@map_3.blt(32*j, 32*i, bitmap_3, rect)

@map_4.blt(32*j, 32*i, bitmap_4, rect)

if $game_system.loop_x && j.between?(0, 19)

@map_2.blt(32*(j+$game_map.width), 32*i, bitmap_2, rect)

@map_3.blt(32*(j+$game_map.width), 32*i, bitmap_3, rect)

@map_4.blt(32*(j+$game_map.width), 32*i, bitmap_4, rect)

end

end}}

# save the three additional maps in the Cache

RPG::Cache_Carte.save(@id, @map_2, 1)

RPG::Cache_Carte.save(@id, @map_3, 2)

RPG::Cache_Carte.save(@id, @map_4, 3)

end

end

 

#============================================================================

# ■ Game_Map

#----------------------------------------------------------------------------

# Methods modifications to handle map looping

#============================================================================

 

class Game_Map

#--------------------------------------------------------------------------

# * Scroll Down

# distance : scroll distance

#--------------------------------------------------------------------------

alias scroll_down_mode7_game_map scroll_down

def scroll_down(distance)

if !$game_system.mode7

scroll_down_mode7_game_map(distance)

return

end

@display_y = @display_y + distance

unless $game_system.loop_y || $game_system.always_scroll

height = (self.height - 15) * 128

@display_y = height if @display_y > height

end

end

#--------------------------------------------------------------------------

# * Scroll Left

# distance : scroll distance

#--------------------------------------------------------------------------

alias scroll_left_mode7_game_map scroll_left

def scroll_left(distance)

if !$game_system.mode7

scroll_left_mode7_game_map(distance)

return

end

@display_x = @display_x - distance

unless $game_system.loop_x || $game_system.always_scroll

@display_x = 0 if @display_x < 0

end

end

#--------------------------------------------------------------------------

# * Scroll Right

# distance : scroll distance

#--------------------------------------------------------------------------

alias scroll_right_mode7_game_map scroll_right

def scroll_right(distance)

if !$game_system.mode7

scroll_right_mode7_game_map(distance)

return

end

@display_x = @display_x + distance

unless $game_system.loop_x || $game_system.always_scroll

width = (self.width - 20) * 128

@display_x = width if @display_x > width

end

end

#--------------------------------------------------------------------------

# * Scroll Up

# distance : scroll distance

#--------------------------------------------------------------------------

alias scroll_up_mode7_game_map scroll_up

def scroll_up(distance)

if !$game_system.mode7

scroll_up_mode7_game_map(distance)

return

end

@display_y = @display_y - distance

unless $game_system.loop_y || $game_system.always_scroll

@display_y = 0 if @display_y < 0

end

end

#--------------------------------------------------------------------------

# * Determine Valid Coordinates

# x : x-coordinate

# y : y-coordinate

# Allow the hero to go out of the map when map looping

#--------------------------------------------------------------------------

alias valid_mode7_game_map? valid?

def valid?(x, y)

return (valid_mode7_game_map?(x, y)) if !$game_system.mode7

if $game_system.loop_x

return ($game_system.loop_y || y >= 0 && y < height)

elsif $game_system.loop_y

return (x >= 0 && x < width)

end

return (x >= 0 && x < width && y >= 0 && y < height)

end

#--------------------------------------------------------------------------

# * Determine if Passable

# x : x-coordinate

# y : y-coordinate

# d : direction (0,2,4,6,8,10)

# * 0,10 = determine if all directions are impassable

# self_event : Self (If event is determined passable)

#--------------------------------------------------------------------------

alias passable_mode7_game_map? passable?

def passable?(x, y, d, self_event = nil)

if !$game_system.mode7

passable_mode7_game_map?(x, y, d, self_event)

return(passable_mode7_game_map?(x, y, d, self_event))

end

return false unless valid?(x, y)

bit = (1 << (d / 2 - 1)) & 0x0f

events.each_value {|event|

if event.tile_id >= 0 && event != self_event &&

event.x == x && event.y == y && !event.through

if @passages[event.tile_id] & bit != 0

return false

elsif @passages[event.tile_id] & 0x0f == 0x0f

return false

elsif @priorities[event.tile_id] == 0

return true

end

end}

[2, 1, 0].each {|i|

tile_id = data[x % width, y % height, i] # handle map looping

if tile_id == nil

return false

elsif @passages[tile_id] & bit != 0

return false

elsif @passages[tile_id] & 0x0f == 0x0f

return false

elsif @priorities[tile_id] == 0

return true

end}

return true

end

end

 

#============================================================================

# ■ Game_Character

#----------------------------------------------------------------------------

# "update" method modifications to handle map looping

#============================================================================

 

class Game_Character

attr_accessor :x

attr_accessor :y

attr_accessor :real_x

attr_accessor :real_y

attr_reader :flat

attr_reader :height

#--------------------------------------------------------------------------

# * Object Initialization

#--------------------------------------------------------------------------

alias initialize_mode7_game_character initialize

def initialize

initialize_mode7_game_character

init_mode7

end

#--------------------------------------------------------------------------

# * Mode7 Initialization

#--------------------------------------------------------------------------

def init_mode7

@flat = false

@height = 0.0

end

#--------------------------------------------------------------------------

# * Update

#--------------------------------------------------------------------------

alias update_mode7_game_character update

def update

if !$game_system.mode7

update_mode7_game_character

return

end

# if x-coordinate is out of the map

if !(x.between?(0, $game_map.width - 1))

difference = 128 * x - real_x

if self.is_a?(Game_Player)

# increase or decrease map's number

self.map_number_x += difference / (difference.abs)

end

# x-coordinate is equal to its equivalent in the map

self.x %= $game_map.width

self.real_x = 128 * x - difference

end

# if y-coordinate is out of the map

if !(y.between?(0, $game_map.height - 1))

difference = 128 * y - real_y

if self.is_a?(Game_Player)

# increase or decrease map's number

self.map_number_y += difference / (difference.abs)

end

# y-coordinate is equal to its equivalent in the map

self.y %= $game_map.height

self.real_y = 128 * y - difference

end

update_mode7_game_character

end

end

 

#==============================================================================

# ■ Game_Event

#----------------------------------------------------------------------------

# Add methods to handle flat events and altitude for vertical event

#============================================================================

 

class Game_Event < Game_Character

#--------------------------------------------------------------------------

# * scan the event's commands list

# page : the scanned page (RPG::Event::Page)

#--------------------------------------------------------------------------

def check_commands(page)

@height = 0.0

command_list = page.list

(0..command_list.length - 2).each {|k|

command = command_list[k]

if (command.parameters[0].to_s).include?('Height')

@height = (command.parameters[0][7,command.parameters[0].length-1]).to_f

end

@flat = (command.parameters[0].to_s).include?('Flat')}

end

#--------------------------------------------------------------------------

# * scan the event's commands list of the current page when refreshed

#--------------------------------------------------------------------------

alias refresh_mode7_game_character refresh

def refresh

refresh_mode7_game_character

check_commands(@page) if @page != nil

end

end

 

#============================================================================

# ■ Game_Player

#----------------------------------------------------------------------------

# Add attributes to have a well-working panorama's scrolling

#============================================================================

 

class Game_Player < Game_Character

attr_accessor :map_number_x # map's number with X-looping

attr_accessor :map_number_y # map's number with Y-looping

#--------------------------------------------------------------------------

# * Object Initialization

#--------------------------------------------------------------------------

alias initialize_mode7_game_player initialize

def initialize

initialize_mode7_game_player

init_mode7

end

#--------------------------------------------------------------------------

# * Mode 7 Initialization

#--------------------------------------------------------------------------

def init_mode7

self.map_number_x = 0

self.map_number_y = 0

super

end

#--------------------------------------------------------------------------

# * Handle the option : center around the hero

#--------------------------------------------------------------------------

alias center_mode7_game_player center

def center(x, y)

if !$game_system.mode7 || !$game_system.always_scroll

center_mode7_game_player(x, y)

return

end

$game_map.display_x = x * 128 - CENTER_X

$game_map.display_y = y * 128 - CENTER_Y

end

end

 

#============================================================================

# ■ Sprite

#----------------------------------------------------------------------------

# Add attributes to work efficiently with scanlines sprites

#============================================================================

 

class Sprite

attr_accessor :y_origin_bitmap # bitmap's y-coordinate for the "src_rect.set"

#method (float)

attr_accessor :x_origin_bitmap # bitmap's x-coordinate for the "src_rect.set"

#method (float)

attr_accessor :y_origin_bitmap_i # bitmap's y-coordinate for the

#"src_rect.set" method (integer)

attr_accessor :x_origin_bitmap_i # bitmap's x-coordinate for the

#"src_rect.set" method (integer)

attr_accessor :length # sprite's width

end

 

#============================================================================

# ■ Sprite_Character

#----------------------------------------------------------------------------

# Calculate x-coordinate and y-coordinate for a mode7 map

#============================================================================

 

class Sprite_Character < RPG::Sprite

attr_reader :flat_indicator # true if the event is flat-drawn

#--------------------------------------------------------------------------

# * Object Initialization

#--------------------------------------------------------------------------

alias initialize_mode7_sprite_character initialize

def initialize(viewport, character = nil)

@flat_indicator = false

initialize_mode7_sprite_character(viewport, character)

end

#--------------------------------------------------------------------------

# * Update

#--------------------------------------------------------------------------

alias update_mode7_sprite_character update

def update

if !$game_system.mode7

update_mode7_sprite_character

return

end

if @flat_indicator

if (!@character.flat || @character.moving? ||

@tile_id != @character.tile_id ||

@character_name != @character.character_name ||

@character_hue != @character.character_hue)

@flat_indicator = @character.flat

# redraw the original ground

maps_list = $scene.spriteset.tilemap.maps_list

map_ground = $scene.spriteset.tilemap.map_ground

rect = Rect.new(@flat_x_map, @flat_y_map, @flat_width, @flat_height)

maps_list.each {|map|

map.blt(@flat_x_map, @flat_y_map, map_ground, rect)

if $game_system.loop_x && @flat_x_map.between?(0, 19 * 32)

map.blt(@flat_x_map + 32 * $game_map.width, @flat_y_map, map_ground,

rect)

end}

else

return

end

end

super

if @tile_id != @character.tile_id ||

@character_name != @character.character_name ||

@character_hue != @character.character_hue

@tile_id = @character.tile_id

@character_name = @character.character_name

@character_hue = @character.character_hue

if @tile_id >= 384

self.bitmap = RPG::Cache.tile($game_map.tileset_name,

@tile_id, @character.character_hue)

self.src_rect.set(0, 0, 32, 32)

self.ox = 16

self.oy = 32

else

self.bitmap = RPG::Cache.character(@character.character_name,

@character.character_hue)

@cw = bitmap.width / 4

@ch = bitmap.height / 4

self.ox = @cw / 2

self.oy = @ch

# pivot correction (intersection between the map and this sprite)

self.oy -= 4

end

end

self.visible = (!@character.transparent)

if @tile_id == 0

sx = @character.pattern * @cw

sy = (@character.direction - 2) / 2 * @ch

self.src_rect.set(sx, sy, @cw, @ch)

end

if @character.flat # event must be flat drawn

return if $scene.spriteset == nil

if @tile_id == 0

@flat_x_map = @character.real_x / 4 - (@cw - 32) / 2

@flat_y_map = @character.real_y / 4 - @ch + 32

@flat_x0 = sx

@flat_y0 = sy

@flat_width = @cw

@flat_height = @ch

else

@flat_x_map = @character.real_x / 4

@flat_y_map = @character.real_y / 4

@flat_x0 = 0

@flat_y0 = 0

@flat_width = 32

@flat_height = 32

end

# modify the maps graphics

maps_list = $scene.spriteset.tilemap.maps_list

rect = Rect.new(@flat_x0, @flat_y0, @flat_width, @flat_height)

maps_list.each {|map|

map.blt(@flat_x_map, @flat_y_map, bitmap, rect, @character.opacity)

if $game_system.loop_x && @flat_x_map.between?(0, 19 * 32)

map.blt(@flat_x_map + 32 * $game_map.width, @flat_y_map, bitmap, rect,

@character.opacity)

end}

@flat_indicator = true

self.opacity = 0

return

end

x_intermediate = @character.screen_x

y_intermediate = @character.screen_y

y_intermediate -= $game_temp.pivot + 4 if $game_system.mode7

# if vertical looping

if $game_system.loop_y

h = 32 * $game_map.height

y_intermediate = (y_intermediate + h / 2) % h - h / 2

end

# coordinates in a mode7 map

self.y = (($game_temp.distance_h * y_intermediate *

$game_temp.cos_angle).to_f / ($game_temp.distance_h - y_intermediate *

$game_temp.sin_angle) + $game_temp.pivot)

self.zoom_x = $game_temp.slope_value * y + $game_temp.corrective_value

self.zoom_y = zoom_x

self.x = 320 + zoom_x * (x_intermediate - 320)

# if horizontal looping

if $game_system.loop_x

offset = ($game_map.width >= 24 ? 64 * zoom_x : 0)

l = 32 * $game_map.width * zoom_x

self.x = (x + offset) % l - offset

end

# Overworld Sprite Resize

if @character.is_a?(Game_Player) && $game_system.ov

self.zoom_x *= $game_system.ov_zoom

self.zoom_y *= $game_system.ov_zoom

end

self.z = @character.screen_z(@ch)

# hide the sprite if it is beyond the horizon's line

self.opacity = (y < $game_temp.height_limit ? 0 : @character.opacity)

self.y -= 32 * @character.height * zoom_y # height correction

self.blend_type = @character.blend_type

self.bush_depth = @character.bush_depth

if @character.animation_id != 0

animation = $data_animations[@character.animation_id]

animation(animation, true)

@character.animation_id = 0

end

end

end

 

#============================================================================

# ■ Sprite_V (Vertical Sprites)

#----------------------------------------------------------------------------

# Sprites corresponding to the vertical elements formed by tiles

#============================================================================

 

class Sprite_V < Sprite

attr_accessor :x_map # sprite's x_coordinates (in squares) (Float)

attr_accessor :y_map # sprite's y_coordinates (in squares) (Float)

attr_accessor :square_y # sprite's y_coordinates (in squares) (Integer)

attr_accessor :priority # sprite's priority

attr_accessor :animated # True if animated

attr_accessor :list_bitmap # list of sprite's bitmaps (Bitmap)

#--------------------------------------------------------------------------

# * Update

#--------------------------------------------------------------------------

def update

square_y_corrected = square_y

y_intermediate = 32 * y_map - $game_temp.pivot - $game_map.display_y / 4

y_intermediate_reference = y_intermediate

# if vertical looping

if $game_system.loop_y

y_intermediate = (y_intermediate + $game_temp.height / 2) %

$game_temp.height - $game_temp.height / 2

if y_intermediate_reference < y_intermediate

square_y_corrected = square_y + $game_map.height

elsif y_intermediate_reference > y_intermediate

square_y_corrected = square_y - $game_map.height

end

end

self.y = ($game_temp.distance_h * y_intermediate *

$game_temp.cos_angle).to_f / ($game_temp.distance_h - y_intermediate *

$game_temp.sin_angle) + $game_temp.pivot

if y < $game_temp.height_limit

# hide the sprite if it is beyond the horizon's line

self.opacity = 0

return

end

self.opacity = 255

if $scene.spriteset != nil

opacity_values = $scene.spriteset.tilemap.opacity_values

tone_values = $scene.spriteset.tilemap.tone_values

if opacity_values.has_key?(y)

self.opacity = opacity_values[y]

self.tone = tone_values[y]

end

end

self.zoom_x = $game_temp.slope_value * y + $game_temp.corrective_value

self.zoom_y = zoom_x

x_intermediate = 32 * x_map - $game_map.display_x / 4

self.x = 320 + (zoom_x * (x_intermediate - 320))

# if horizontal looping

if $game_system.loop_x

offset = ($game_map.width >= 24 ? 64 * zoom_x : 0)

l = 32 * $game_map.width * self.zoom_x

self.x = (self.x + offset) % l - offset

end

self.z = (128 * square_y_corrected - $game_map.display_y + 3) / 4 +

32 + 32 * priority

end

#--------------------------------------------------------------------------

# * Update bitmap for animation

# index : 0..3 : animation's index

#--------------------------------------------------------------------------

def update_animated(index)

self.bitmap = @list_bitmap[index]

end

end

 

#============================================================================

# ■ Spriteset_Map

#----------------------------------------------------------------------------

# Modifications to call a mode7 map

#============================================================================

 

class Spriteset_Map

attr_accessor :tilemap # just to be able to access the tilemap

#--------------------------------------------------------------------------

# * Defines map's options from its name

# Refer to Game_System class

#--------------------------------------------------------------------------

def init_options

map_data = $data_maps[$game_map.map_id]

MODE7_SETTINGS.each_key {|keyword|

if map_data.name2.include?(keyword)

command_list = MODE7_SETTINGS[keyword]

$game_system.mode7 = true

$game_system.loop_x = command_list.include?("X")

$game_system.loop_y = command_list.include?("Y")

$game_system.always_scroll = command_list.include?("C")

$game_system.animated = command_list.include?("A")

$game_system.white_horizon = command_list.include?("H")

$game_system.fixed_panorama = command_list.include?("P")

$game_system.ov = command_list.include?("OV")

command_list.each {|command|

if command.include?("#")

$game_system.angle = (command.slice(1, 2)).to_i

if $game_system.angle < 0

$game_system.angle = 0

elsif $game_system.angle > 89

$game_system.angle = 89

end

break

end}

return

end}

$game_system.mode7 = map_data.name2.include?("[M7]")

$game_system.loop_x = map_data.name2.include?("[X]")

$game_system.loop_y = map_data.name2.include?("[Y]")

$game_system.always_scroll = map_data.name2.include?("[C]")

$game_system.animated = map_data.name2.include?("[A]")

$game_system.white_horizon = map_data.name2.include?("[H]")

$game_system.fixed_panorama = map_data.name2.include?("[P]")

$game_system.ov = map_data.name2.include?("[OV]")

if $game_system.mode7

map_data.name2 =~ /\[#[ ]*([00-99]+)\]/i

$game_system.angle = $1.to_i

if $game_system.angle < 0

$game_system.angle = 0

elsif $game_system.angle > 89

$game_system.angle = 89

end

end

end

#--------------------------------------------------------------------------

# * Initialize Object

# Rewritten to call a map with mode7

#--------------------------------------------------------------------------

alias initialize_mode7_spriteset_map initialize

def initialize

if !$game_system.mode7

initialize_mode7_spriteset_map

return

end

init_options

@viewport1 = Viewport.new(0, 0, 640, 480)

@viewport2 = Viewport.new(0, 0, 640, 480)

@viewport3 = Viewport.new(0, 0, 640, 480)

@viewport2.z = 200

@viewport3.z = 5000

# mode7 map

@tilemap = Tilemap_mode7.new(@viewport1)

@panorama = Plane.new(@viewport1)

# sprites drawn at the horizon's level have a negative z, and with a z value

# of -100000 the panorama is still below

@panorama.z = ($game_system.mode7 ? -100000 : -1000)

@fog = Plane.new(@viewport1)

@fog.z = 3000

@character_sprites = []

$game_map.events.keys.sort.each {|i|

sprite = Sprite_Character.new(@viewport1, $game_map.events)

@character_sprites.push(sprite)}

@character_sprites.push(Sprite_Character.new(@viewport1, $game_player))

@weather = RPG::Weather.new(@viewport1)

@picture_sprites = []

(1..50).each {|i|

@picture_sprites.push(Sprite_Picture.new(@viewport2,

$game_screen.pictures))}

@timer_sprite = Sprite_Timer.new

update

end

#--------------------------------------------------------------------------

# * Dispose

#--------------------------------------------------------------------------

alias dispose_mode7_spriteset_map dispose

def dispose

if !$game_system.mode7

dispose_mode7_spriteset_map

return

end

@tilemap.dispose

@panorama.dispose

@fog.dispose

@character_sprites.each {|sprite| sprite.dispose}

@weather.dispose

@picture_sprites.each {|sprite| sprite.dispose}

@timer_sprite.dispose

@viewport1.dispose

@viewport2.dispose

@viewport3.dispose

end

#--------------------------------------------------------------------------

# * Update

#--------------------------------------------------------------------------

alias update_mode7_spriteset_map update

def update

if !$game_system.mode7

update_mode7_spriteset_map

return

end

if @panorama_name != $game_map.panorama_name ||

@panorama_hue != $game_map.panorama_hue

@panorama_name = $game_map.panorama_name

@panorama_hue = $game_map.panorama_hue

if @panorama.bitmap != nil

@panorama.bitmap.dispose

@panorama.bitmap = nil

end

if @panorama_name != ""

@panorama.bitmap = RPG::Cache.panorama(@panorama_name, @panorama_hue)

end

Graphics.frame_reset

end

if @fog_name != $game_map.fog_name || @fog_hue != $game_map.fog_hue

@fog_name = $game_map.fog_name

@fog_hue = $game_map.fog_hue

if @fog.bitmap != nil

@fog.bitmap.dispose

@fog.bitmap = nil

end

@fog.bitmap = RPG::Cache.fog(@fog_name, @fog_hue) if @fog_name != ''

Graphics.frame_reset

end

# update animated tiles each 20 frames

if Graphics.frame_count % 20 == 0 && $game_system.animated

@tilemap.update_animated

end

@tilemap.update

# if the panorama is fixed

if $game_system.fixed_panorama

@panorama.ox = 0

@panorama.oy = 0

# if it is a mode7 map

else

# to have a fluent panorama scrolling

@panorama.ox = (128 * $game_map.width * $game_player.map_number_x +

$game_player.real_x) / 8

@panorama.oy = - (128 * $game_map.height * $game_player.map_number_y +

$game_player.real_y) / 32

end

@fog.zoom_x = $game_map.fog_zoom / 100.0

@fog.zoom_y = $game_map.fog_zoom / 100.0

@fog.opacity = $game_map.fog_opacity

@fog.blend_type = $game_map.fog_blend_type

@fog.ox = $game_map.display_x / 4 + $game_map.fog_ox

@fog.oy = $game_map.display_y / 4 + $game_map.fog_oy

@fog.tone = $game_map.fog_tone

@character_sprites.each {|sprite| sprite.update}

@weather.type = $game_screen.weather_type

@weather.max = $game_screen.weather_max

@weather.ox = $game_map.display_x / 4

@weather.oy = $game_map.display_y / 4

@weather.update

@picture_sprites.each {|sprite| sprite.update}

@timer_sprite.update

@viewport1.tone = $game_screen.tone

@viewport1.ox = $game_screen.shake

@viewport3.color = $game_screen.flash_color

@viewport1.update

@viewport3.update

end

end

 

#============================================================================

# ■ Scene_Map

#============================================================================

class Scene_Map

attr_accessor :spriteset # just need to access the spriteset

end

 

#============================================================================

# ■ Data_Autotiles

#----------------------------------------------------------------------------

# Creates the set of tiles from an autotile's file

#============================================================================

 

class Data_Autotiles < Bitmap

# data list to form tiles from an atotiles file

Data_creation = [[27,28,33,34],[5,28,33,34],[27,6,33,34],[5,6,33,34],

[27,28,33,12],[5,28,33,12],[27,6,33,12],[5,6,33,12],[27,28,11,34],

[5,28,11,34],[27,6,11,34],[5,6,11,34],[27,28,11,12],[5,28,11,12],

[27,6,11,12],[5,6,11,12],[25,26,31,32],[25,6,31,32],[25,26,31,12],

[25,6,31,12],[15,16,21,22],[15,16,21,12],[15,16,11,22],[15,16,11,12],

[29,30,35,36],[29,30,11,36],[5,30,35,36],[5,30,11,36],[39,40,45,46],

[5,40,45,46],[39,6,45,46],[5,6,45,46],[25,30,31,36],[15,16,45,46],

[13,14,19,20],[13,14,19,12],[17,18,23,24],[17,18,11,24],[41,42,47,48],

[5,42,47,48],[37,38,43,44],[37,6,43,44],[13,18,19,24],[13,14,43,44],

[37,42,43,48],[17,18,47,48],[13,18,43,48],[13,18,43,48]]

attr_accessor :number # autotile's number to identify it

attr_accessor :animated # TRUE if the autotile is animated

#--------------------------------------------------------------------------

# * Initialize Object

# file : autotiles file's bitmap (Bitmap)

# l : 0..3 : pattern's number for animated autotiles

#--------------------------------------------------------------------------

def initialize(file, l)

super(8*32, 6*32)

create(file, l)

end

#--------------------------------------------------------------------------

# * Create the tiles set

# file : autotiles file's bitmap (Bitmap)

# l : 0..3 : pattern's number for animated autotiles

#--------------------------------------------------------------------------

def create(file, l)

l = (file.width > 96 ? l : 0)

self.animated = (file.width > 96)

(0..5).each {|i| (0..7).each {|j| Data_creation[8 * i + j].each {|number|

number -= 1

m = 16 * (number % 6)

n = 16 * (number / 6)

blt(32 * j + m % 32, 32 * i + n % 32, file,

Rect.new(m + 96 * l, n, 16, 16))}}}

end

end

 

#============================================================================

# ■ Data_Vertical_Sprites

#----------------------------------------------------------------------------

# Create a list of vertical sprites for the three layers of a map

# "V" for "Vertical" in the script

# "num" for "number"

#============================================================================

 

class Data_Vertical_Sprites

attr_accessor :list_sprites_V # list of vertical sprites

attr_accessor :list_sprites_V_animated # list of animated vertical sprites

#--------------------------------------------------------------------------

# * A little method to compare terrain_tags

# value : tile's ID

# num : reference terrain_tag's value

#--------------------------------------------------------------------------

def suitable?(value, num)

return ($game_map.terrain_tags[value] == num)

end

#--------------------------------------------------------------------------

# * This algorithm scans each layer and create a sprites formed by tiles

# in contact

# viewport : Viewport

#--------------------------------------------------------------------------

def initialize(viewport)

@viewport = viewport

# lists initialization

self.list_sprites_V = []

self.list_sprites_V_animated = []

# @num_tiles : list of tiles coordinates that form a vertical sprite

@num_tiles = []

# create copy of map's data

@dataV = ($game_map.data).clone

# scan each layer, row and column

(0..2).each {|h| (0..$game_map.height).each {|i| (0..$game_map.width).each {|j|

value = @dataV[j, i, h].to_i

# if tile's terrain tag is declared to give vertical sprites

if VERTICAL_TILE_TERRAIN_TAGS.include?($game_map.terrain_tags[value])

@reference_terrain_tag = $game_map.terrain_tags[value]

@num_tiles.push([j, i])

# the following algorithm is so complex that I really don't know how

# it works exactly

list_end = 0

length = 0

while j + length + 1 < $game_map.width &&

suitable?(@dataV[j +length+ 1, i, h].to_i, @reference_terrain_tag)

@num_tiles.push([j + length+ 1,i])

length += 1

end

list_start = j

list_end = length + j

indicator = true

row = 0

j2 = j

while indicator

row += 1

break if (i + row) == $game_map.height

list_start2 = j2

length2 = 0

indicator = false

if length >= 2

((j2 + 1)..(j2 + length -1)).each {|k|

if suitable?(@dataV[k, i + row, h].to_i,

@reference_terrain_tag)

if !indicator

list_start2 = k

else

length2 = k - list_start2

end

indicator = true

@num_tiles.push([k, i + row])

elsif !indicator

length2 -= 1

end}

end

if suitable?(@dataV[j2 + length, i + row, h].to_i,

@reference_terrain_tag)

length2 = j2 + length - list_start2

indicator = true

@num_tiles.push([j2 + length, i + row])

length3 = 1

while j2 + length + length3 < $game_map.width &&

suitable?(@dataV[j2 + length + length3, i + row, h].to_i,

@reference_terrain_tag)

@num_tiles.push([j2 + length + length3, i + row])

length3 += 1

length2 += 1

if j2 + length + length3 > list_end

list_end = j2 + length + length3

end

end

end

if suitable?(@dataV[j2, i + row, h].to_i, @reference_terrain_tag)

list_start3 = list_start2 - j2

length2 = length2 + list_start3

list_start2 = j2

indicator = true

@num_tiles.push([j2, i + row])

length3 = 1

while j2 - length3 >= 0 &&

suitable?(@dataV[j2 - length3, i + row, h].to_i,

@reference_terrain_tag)

@num_tiles.push([j2 - length3, i + row])

length3 += 1

length2 += 1

list_start2 -= 1

list_start = list_start2 if list_start2 < list_start

end

end

length = length2

j2 = list_start2

end

row -= 1

# create a bitmap and a sprite from the tiles listed in @num_tiles

create_bitmap(i, list_start, row, list_end - list_start, h)

# clear the used tiles

clear_data(h)

# reinitialize the list of tiles

@num_tiles = []

end}}}

end

#--------------------------------------------------------------------------

# * Clear the used data to prevent from reusing them

# layer : current scanned layer

#--------------------------------------------------------------------------

def clear_data(layer)

@num_tiles.each {|num| @dataV[num[0], num[1], layer] = 0}

end

#--------------------------------------------------------------------------

# * Create a Bitmap from the listed tiles in @num_tiles and its associated

# sprite (Sprite_V)

# row : start row's value

# column : start column's value

# height : sprite's height (in tiles)

# width : sprite's width (in tiles)

# layer : current scanned layer

#--------------------------------------------------------------------------

def create_bitmap(row, column, height, width, layer)

bmp = Bitmap.new(32*(1+width), 32*(1+height))

rect = Rect.new(0, 0, 32, 32)

@num_tiles.sort! {|a, b| -(a[1] - b[1])}

sprite = Sprite_V.new(@viewport)

# initialize sprite's attributes

sprite.animated = false

sprite.list_bitmap = []

# draw the bitmap

@num_tiles.each {|tile_coordinates|

value = @dataV[tile_coordinates[0], tile_coordinates[1], layer].to_i

# if tile is a normal tile

if value > 383

bitmap = RPG::Cache.tile($game_map.tileset_name, value, 0)

else # tile is an autotile

file = (value / 48) - 1

num_file = 4 * file

if !sprite.animated

autotile_name = $game_map.autotile_names[file]

fichier = RPG::Cache.autotile(autotile_name)

sprite.animated = (fichier.width > 96 ? true : false)

end

bitmap = RPG::Cache.autotile_base(num_file, value)

end

bmp.blt(32 * (tile_coordinates[0] - column),

32 * (tile_coordinates[1] - row), bitmap, rect)}

sprite.list_bitmap.push(bmp)

# create 3 additionnal bitmaps for animated sprites

if sprite.animated

(1..3).each {|j|

bmp = Bitmap.new(32 * (1 + width), 32 * (1 + height))

@num_tiles.each {|tile_coordinates|

value = @dataV[tile_coordinates[0], tile_coordinates[1], layer].to_i

if value > 383

bitmap = RPG::Cache.tile($game_map.tileset_name, value, 0)

else

num_file = 4 * ((value / 48) - 1)

bitmap = RPG::Cache.autotile_base(num_file + j, value)

end

bmp.blt(32 * (tile_coordinates[0] - column),

32 * (tile_coordinates[1] - row), bitmap, rect)}

sprite.list_bitmap.push(bmp)}

end

value = @dataV[@num_tiles[0][0], @num_tiles[0][1], layer].to_i

# set sprite's priority

sprite.priority = $game_map.priorities[value]

# set sprite's coordinates (in squares (32 * 32 pixels))

sprite.x_map = (column.to_f) + bmp.width / 64

sprite.x_map += 0.5 if width % 2 == 0

sprite.y_map = (row + height).to_f + 0.5

sprite.square_y = sprite.y_map.to_i # Integer

# set the y_pivot (intersection between the map and the sprite)

sprite.oy = bmp.height - 16

sprite.ox = bmp.width / 2

sprite.bitmap = sprite.list_bitmap[0]

self.list_sprites_V.push(sprite)

self.list_sprites_V_animated.push(sprite) if sprite.animated

end

end

 

#============================================================================

# ■ RPG::Cache_Tile

#----------------------------------------------------------------------------

# The tiles resulting in a superimposing of several tiles are kept in memory

# for a faster call

# valueX : tile's ID

#============================================================================

 

module RPG::Cache_Tile

@cache = {}

#--------------------------------------------------------------------------

# * Superimposing of two tiles, offset = pattern's number for animated

# autotiles

#--------------------------------------------------------------------------

def self.load(value1, value2, offset=0)

if !@cache.include?([value1, value2, offset])

bitmap = Bitmap.new(32, 32)

rect = Rect.new(0, 0, 32, 32)

if value1 > 383 # normal tile

bitmap.blt(0, 0, RPG::Cache.tile($game_map.tileset_name, value1, 0),

rect)

else # autotile

num = 4*((value1 / 48) - 1) + offset

bitmap.blt(0, 0, RPG::Cache.autotile_base(num, value1), rect)

end

if value2 > 383 # normal tile

bitmap.blt(0, 0, RPG::Cache.tile($game_map.tileset_name, value2, 0),

rect)

else # autotile

num = 4*((value2 / 48) - 1) + offset

bitmap.blt(0, 0, RPG::Cache.autotile_base(num, value2), rect)

end

###@cache[[value1, value2, offset]] = bitmap

return bitmap

end

@cache[[value1, value2, offset]]

end

#--------------------------------------------------------------------------

# * Superimposing of three tiles

#--------------------------------------------------------------------------

def self.load2(value1, value2, value3, offset = 0)

if !@cache.include?([value1, value2, value3, offset])

bitmap = Bitmap.new(32, 32)

rect = Rect.new(0, 0, 32, 32)

if value1 > 383 # normal tile

bitmap.blt(0, 0, RPG::Cache.tile($game_map.tileset_name, value1, 0),

rect)

else # autotile

num = 4*((value1 / 48) - 1) + offset

bitmap.blt(0, 0, RPG::Cache.autotile_base(num, value1), rect)

end

if value2 > 383 # normal tile

bitmap.blt(0, 0, RPG::Cache.tile($game_map.tileset_name, value2, 0),

rect)

else # autotile

num = 4*((value2 / 48) - 1) + offset

bitmap.blt(0, 0, RPG::Cache.autotile_base(num, value2), rect)

end

if value3 > 383 # normal tile

bitmap.blt(0, 0, RPG::Cache.tile($game_map.tileset_name, value3, 0),

rect)

else # autotile

num = 4*((value3 / 48) - 1) + offset

bitmap.blt(0, 0, RPG::Cache.autotile_base(num, value3), rect)

end

###@cache[[value1, value2, value3, offset]] = bitmap

return bitmap

end

@cache[[value1, value2, value3, offset]]

end

#--------------------------------------------------------------------------

# * Clear the Cache

#--------------------------------------------------------------------------

def self.clear

@cache = {}

GC.start

end

end

 

#============================================================================

# ■ RPG::Cache_Carte

#----------------------------------------------------------------------------

# Maps drawn with mode7 are kept in memory to have a faster call the next

# times they need to be drawn

#============================================================================

 

module RPG::Cache_Carte

@cache = {}

#--------------------------------------------------------------------------

# * Check if the map is in the Cache

# map_id : map's ID

#--------------------------------------------------------------------------

def self.in_cache(map_id)

return @cache.include?(map_id)

end

#--------------------------------------------------------------------------

# * Return the map's drawing (Bitmap)

# map_id : map's ID

# num : pattern's number for animated autotiles

#--------------------------------------------------------------------------

def self.load(map_id, num = 0)

return @cache[map_id][num]

end

#--------------------------------------------------------------------------

# * Save the map's drawing in the Cache

# map_id : map's ID

# bitmap : map's drawing (Bitmap)

# num : pattern's number for animated autotiles

#--------------------------------------------------------------------------

def self.save(map_id, bitmap, num = 0)

@cache[map_id] = [] if !self.in_cache(map_id)

@cache[map_id][num] = bitmap

end

#--------------------------------------------------------------------------

# * Clear the Cache

#--------------------------------------------------------------------------

def self.clear

@cache = {}

GC.start

end

end

 

#============================================================================

# ■ RPG::Cache

#----------------------------------------------------------------------------

# The tiles from autotiles files are kept in memory for a faster call

#============================================================================

 

module RPG::Cache

#--------------------------------------------------------------------------

# * Check if the map is in the Cache

# num : autotiles file's ID

# value : tile's ID

#--------------------------------------------------------------------------

def self.autotile_base(num, value)

key = [num, value]

if !@cache.include?(key) || @cache[key].disposed?

@cache[key] = Bitmap.new(32, 32)

num_tile = value % 48

sx = 32 * (num_tile % 8)

sy = 32 * (num_tile / 8)

rect = Rect.new(sx, sy, 32, 32)

@cache[key].blt(0, 0, self.load_autotile(num), rect)

end

@cache[key]

end

#--------------------------------------------------------------------------

# * Save the tile's drawing in the Cache

# bitmap : tile's drawing (Bitmap)

# key : tile's ID

#--------------------------------------------------------------------------

def self.save_autotile(bitmap, key)

@cache[key] = bitmap

end

#--------------------------------------------------------------------------

# * Return the tile's drawing (Bitmap)

# key : tile's ID

#--------------------------------------------------------------------------

def self.load_autotile(key)

@cache[key]

end

end

 

#============================================================================

# ■ RPG::MapInfo

#============================================================================

 

class RPG::MapInfo

# defines the map's name as the name without anything within brackets,

# including brackets

def name

return @name.gsub(/\[.*\]/) {""}

end

#--------------------------------------------------------------------------

# the original name with the codes

def name2

return @name

end

end

 

#============================================================================

# ■ Game_Temp

#----------------------------------------------------------------------------

# Add attributes to this class / Avoid using too many global variables

#============================================================================

 

class Game_Temp

attr_accessor :pivot # screenline's number of the slant's pivot

attr_accessor :cos_angle # cosinus of the slant's angle

attr_accessor :sin_angle # sinus of the slant's angle

attr_accessor :height_limit # horizon's line

attr_accessor :distance_h # distance between the map's center and the vanishing point

attr_accessor :slope_value # intermediate value

attr_accessor :corrective_value # intermediate value

attr_accessor :height # map's height (in pixel)

#--------------------------------------------------------------------------

# * Object Initialization

#--------------------------------------------------------------------------

alias initialize_mode7_game_temp initialize

def initialize

initialize_mode7_game_temp

self.pivot = 0

self.cos_angle = 0.0

self.sin_angle = 0.0

self.height_limit = 0

self.distance_h = 0

self.slope_value = 0.0

self.corrective_value = 0.0

self.height = 0

end

end

 

Any other thoughts? If it is limited to just one template it should be writable to add more.

Share this post


Link to post
Share on other sites
  • 0

If the 'object' you speak of is from a tileset, you need to change the terrain flag to a 1 or 2. (or at least thats what you do with the version I have) I believe they have a slightly different effect, but have yet to find out what it is.

Share this post


Link to post
Share on other sites
  • 0

If the 'object' you speak of is from a tileset, you need to change the terrain flag to a 1 or 2. (or at least thats what you do with the version I have) I believe they have a slightly different effect, but have yet to find out what it is.

 

Let me try that out. I think that might do it.

Share this post


Link to post
Share on other sites
  • 0

You are welcome. The version I have is only very slightly different. Same scripter and version, oddly.

 

Just remember, instead of double posting, please use the 'edit' button down in the lower right corner of your post.

Edited by Midnite Reaper

Share this post


Link to post
Share on other sites
  • 0

What happens when u try to walk on the stairs/mountains ?

 

mode 7 is one of the hardest scrips 2 work with i tried it but i lost motivation for it.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...