=begin
LOOK MODE 7 Traduzido por Kevin-BK
adicione os seguintes comandos para o nome do mapa
[M7] - Use m7 neste mapa. Se for omitido, tilemap padrão será usado
[# XX] - XX = Valor entre 89 e 0. Define o ângulo de inclinação
[X] - X = 1 ou 0 se X = 1, ocultar paredes verticais se a parte traseira teria
ser visível
if [# XX] ou [-X] são omitidos, a última configuração será usada
by Shining Advances
=end
class Game_System
alias initialize_m7 initialize
attr_reader :factor
attr_reader :correct
attr_reader :scroll_y
attr_reader :distance
attr_reader :angle
attr_reader :height
attr_reader :columns
attr_reader :filter
attr_accessor :hidewalls
attr_accessor :hide
attr_accessor :new_angle
attr_accessor :need_refresh
def initialize
initialize_m7
@scroll_y = 10 # distância da câmera para o jogador
@height = 1 # a altura do chão sprites
# aumentar este valor aumenta o desempenho ligeiramente
# No entanto os valores> 2 vai deixar o solo unneatly olhar à distância
@columns = 16 # a quantidade de sprites para uma parede vertical
# definido para 8 ou 16
# 8 vai aumentar o desempenho muito, mas ao custo da qualidade
@filter = 2*32 # pula o filtro a cada frame 3 ~ vertical dentro
# O intervalo dado. configuração @ filter a zero irá desativar o filtro
@hidewalls = 0
# 1 -> esconde paredes verticais se o verso seria visível
# 0 -> mostrar a paredes verticais
@distance = 480 #O Foco
# Os valores mais elevados vai deixar as paredes verticais ser mais paralelas
@hide = 90 # se a distância de uma parede e é o jogador y-coord está entre
# 1 e se esconder @, a parede vai se tornar transparente
self.angle = 45 # dar um palpite que ângulo se entende. _.
# cada um desses valores pode ser alterado com um script de chamada:
# $ game_system .* * = valor do atributo
# exemplo:
# $ game_system.height = 2
@new_angle = false#internal use. do not change
@need_refresh = false
end
#central projection formulas based on MGCaladtogel's Neo Mode07 Script
def screen2m7_y(y)
#calcs old screen_y to new screen_y
return @scroll_y + (@cd * y) / (@distance - y * @sinus)
end
def screen2map_y(y)
#calcs new screen_y to map_y (y*32)
return @distance * (@scroll_y - y) /
(@dif - y * @sinus) + @scroll_y
end
def screen2zoom(y)
return (y * @factor + @correct)
end
def angle=(n)
@angle = n
@cosinus = Math.cos(Math::PI * (@angle / 180.0))
@sinus = Math.sin(Math::PI * (@angle / 180.0))
@cd = @cosinus * @distance
@ys = @scroll_y * @sinus
@dif = @ys - @cd
z0 = @distance / (@distance + @scroll_y * @sinus)
h0 = (-@distance * @scroll_y * @cosinus) /
(@distance + @scroll_y * @sinus) + @scroll_y
@factor = (1.0 - z0) / (@scroll_y - h0)
@correct = 1.0 - @scroll_y * @factor
@new_angle = true
end
def distance=(n)
@distance = n
self.angle = @angle
end
def height=(n)
@height = n
@need_refresh = true
end
def columns=(n)
@columns = n
@need_refresh = true
end
end
$data_maps = load_data("Data/MapInfos.rxdata")
class M7Tilemap
attr_reader :autotiles
attr_accessor :tileset
attr_accessor :priorities
def initialize(vp)
@viewport = vp
@horizontal = {} #hash that stores horizontal wall sprites
@vertical = {} #hash that stores vertical wall sprites
@tileset = nil
@map_data = nil
@priorities = nil
@bitmap = Bitmap.new(1,1) #bitmap that represents the map
@sprites = [] #array that stores the ground sprites
@autotiles = []
refresh
end
def refresh
#set tilemapsettings to globalsettings
@height = $game_system.height
@columns = $game_system.columns
@scroll_y = $game_system.scroll_y
@filter = $game_system.filter
#set ox and oy to unnormal values to force refresh of sprite coordinates
#see methods ox= oy=
@ox = -1
@oy = -1
#dispose old sprites
w = nil
@sprites.each{ |w|
w.dispose}
@sprites = []
#create new sprites
for i in 0...(@scroll_y / @height)
@sprites[i] = Sprite.new(@viewport)
@sprites[i].y = i * @height
end
#skip every 2. sprite beyond @scroll_y to increase performance
#it looks still the same because zoom > 1
for i in (@scroll_y / @height)...(((480-@scroll_y) / 2 + @scroll_y) /
@height)
@sprites[i] = Sprite.new(@viewport)
@sprites[i].y = i * @height * 2 - @scroll_y
end
@sprites.each {|w|
w.zoom_x = $game_system.screen2zoom(w.y+1)
if w.zoom_x > 1 #zoom < 1 could make a sprite with 1 pixel height disappear
w.zoom_y = w.zoom_x
end
w.x = 320
}
unless @map_data.nil?
#if there is no map_data (that means refresh is called for the first time)
#-> create bitmap and sprites
refresh_bitmap
end
end
def terrain=(n)
@terrain = n
end
def tileset=(bitmap)
@tileset = bitmap
end
def ox=(n)
return if @ox == n #if ox didn't change, there is no need to render
@ox = n
dif = (@oy + @scroll_y) #calc difference once to increase performance
ox = n + 320 #calc ox of the screen center once to increase performance
#define local variables before loops to increase performance
w = nil #sprites
i = nil #index, key and y coord
a = nil #ary of sprites
z = nil #zoom
erase = nil
@sprites.each{ |w|
w.ox = ox} #scroll ground sprites to ox
@horizontal.each{ |i, a|
#calc zoom for all horizontal sprites on this y-achsis
new_y = $game_system.screen2m7_y(i - dif)
z = $game_system.screen2zoom(new_y)#a[0].y)
#do this sprites need to be set on transparent?
erase = (a[0].y - 256).between?(1,$game_system.hide)
a.each{ |w|
w.x = 320 + z * (w.map_x - ox) #calc x coord
if erase and 28 >= (ox - w.map_x).abs
#if player is behind wall, make it transparent
w.opacity = 100
else
w.opacity = 255
end
}
}
@vertical.each{ |i, a|
#calc y-coord of sprites in ary a
new_y = $game_system.screen2m7_y(i - dif)
#calc z-coord of sprites in ary a
z = $game_system.screen2zoom(new_y)
#these sprites can be skipped if they are in filter range
erase = (a[0].map_y % 6 != 0)
a.each{ |w|
#if sprites are in filter range, skip them
if erase and (w.map_x - ox).abs < @filter
w.jump = true #mark sprite as skipped
w.visible = false #make them invisible
next
end
w.jump = false #mark sprite as not skipped
if w.visible
#can sprite be skipped due to hidewalls setting?
if w.visible = (ox*w.side >= w.map_x*w.side)
w.x = 320 + z * (w.map_x - ox)
end
elsif w.visible = (ox*w.side >= w.map_x*w.side)
#if sprites were invisible, they were skipped and have to be
#fully new rendered -> set y-achsis too
w.y = new_y
w.x = 320 + z * (w.map_x - ox)
w.zoom_y = z
end
}
}
end
def oy=(n)
return if @oy == n
@oy = n
ox320 = @ox + 320
dif = (n + @scroll_y)
w = nil #sprites
i = nil #index, key and y coord
a = nil #ary of sprites
z = nil #zoom
new_y = nil
erase = nil
@sprites.each{ |w|
#which row of the ground bitmap does the sprite represent?
w.src_rect.y = $game_system.screen2map_y(w.y+1).round + @oy
}
@horizontal.each{ |i, a|
#same as in ox=
new_y = $game_system.screen2m7_y(i - dif)
z = $game_system.screen2zoom(new_y)
erase = (a[0].y - 256).between?(1,$game_system.hide)
a.each{ |w|
w.y = new_y
w.x = 320 + (z * (w.map_x - ox320))
w.zoom_x = (w.zoom_y = z + 0.04)
if erase and 28 >= (ox320 - w.map_x).abs
w.opacity = 100
else
w.opacity = 255
end
}
}
@vertical.each{ |i, a|
new_y = $game_system.screen2m7_y(i - dif)
z = $game_system.screen2zoom(new_y)
a.each { |w|
if w.visible
w.y = new_y
w.x = 320 + z * (w.map_x - ox320)
w.zoom_y = z
end
}
}
end
def map_data=(data)
@map_data = data
refresh_bitmap
end
def refresh_bitmap
@terrain = $game_map.terrain_tags if @terrain.nil?
#dispose old wall sprites
@horizontal.each{ |i, c|
c.each{ |w|
w.dispose}}
@vertical.each{ |i, c|
c.each{ |w|
w.dispose}}
@horizontal.clear
@vertical.clear
@bitmap.dispose
@bitmap = Bitmap.new(@map_data.xsize*32,@map_data.ysize*32)
rect = Rect.new(0,0,32,32)
source = Rect.new(0,0,32,32)
i = 0
x = 0
y = 0
z = 0
data = nil
wall = nil
#create new ground bitmap/texture
for x in
[Tens de ter uma conta e sessão iniciada para poderes visualizar este link] for y in
[Tens de ter uma conta e sessão iniciada para poderes visualizar este link] rect.x = x*32
rect.y = y*32
source.x = ((@map_data[x,y,0] - 384) %
* 32
source.y = ((@map_data[x,y,0] - 384) /
* 32
@bitmap.stretch_blt(rect,@tileset,source)
#look for vertical and horizontal walls
for z in 0..2
data = @map_data[x,y,z]
if @terrain[data] == 2 #if vertical wall
if @terrain[@map_data[[x+1,@map_data.xsize-1].min,y,z].to_i] != 2
#if next tile is ground -> need to display vertical wall
#these are walls on the left side of the room
for i in 0...@columns
#split vertical wall into @columns sprites
wall = SWall.new(@viewport,@columns)
wall.map_x = x * 32 + 32
wall.map_y = y * 32 + (@columns-i) * 32 / @columns
wall.bitmap = @tileset
wall.z = wall.map_y
wall.side = 1 * $game_system.hidewalls
wall.set_src(@terrain, data, i)
wall.ox = 32 / @columns / 2 - 1
#save walls with same y-coord into same array to
#calc screen y coord for all these sprites at once
#-> increases performance
if @vertical.key?(wall.map_y)
@vertical[wall.map_y].push(wall)
else
@vertical[wall.map_y] = [wall]
end
end
end
if @terrain[@map_data[[x-1,0].max,y,z].to_i] != 2
#for comments see above
#these are walls on the right side of the room
for i in 0...@columns
wall = SWall.new(@viewport,@columns)
wall.map_x = x * 32
wall.map_y = y * 32 + (@columns-i) * 32 / @columns
wall.bitmap = @tileset
wall.mirror = true
wall.set_src(@terrain, data, i)
wall.z = wall.map_y
wall.side = -1 * $game_system.hidewalls
wall.ox = 32 / @columns / 2
if @vertical.key?(wall.map_y)
@vertical[wall.map_y].push(wall)
else
@vertical[wall.map_y] = [wall]
end
end
end
end
if @terrain[data] == 1 and #if horizontal wall
(y+1 == @map_data.ysize or
@map_data[x,y+1,z] != data +
#and next tile is no wall
wall = Wall.new(@viewport,1,@map_data)
wall.map_x = x * 32 + 16
wall.map_y = y * 32 + 32 + 1
wall.real_y = y
wall.bitmap = @tileset
wall.set_src(@terrain, data)
wall.ox = 15
wall.z = wall.map_y
if @horizontal.key?(wall.map_y)
@horizontal[wall.map_y].push(wall)
else
@horizontal[wall.map_y] = [wall]
end
end
end
end
end
#set scr_rect and ground bitmap/texture of the ground sprites
for i in
[Tens de ter uma conta e sessão iniciada para poderes visualizar este link] @sprites[i].bitmap = @bitmap
@sprites[i].src_rect.set(0,i,@bitmap.width,@height)
if i >= @scroll_y / @height
@sprites[i].src_rect.height *= 2
end
end
end
def update
if $game_system.need_refresh
$game_system.new_angle = false
$game_system.need_refresh = false
refresh
return
end
if $game_system.new_angle
#applies new zoom to ground sprites
@sprites.each {|w|
w.zoom_x = $game_system.screen2zoom(w.y+1)
if w.zoom_x > 1
w.zoom_y = w.zoom_x
end
w.x = 320
}
#changes ox/oy to force new rendering of walls
x = @ox
y = @oy
@ox += 1
@oy += 1
self.ox = x
self.oy = y
$game_system.new_angle = false
end
end
def dispose
@horizontal.each{ |i, c|
c.each{ |w|
w.dispose}}
@vertical.each{ |i, c|
c.each{ |w|
w.dispose}}
@sprites.each{ |w|
w.dispose}
@bitmap.dispose
end
end
class Wall < Sprite
attr_accessor :map_x
attr_accessor :map_y
attr_accessor :real_y
attr_accessor :side
attr_accessor :jump
attr_accessor :height
def initialize(vp,spalten,data=nil)
super(vp)
@data = data
@spalten = spalten
@jump = false
@real_y = 0
@map_x = 0
@map_y = 0
@side = 0
self.x = 320
self.z = 100
@blick = true
end
def set_src(terrain,tile,i=0)
height = 1
#calc height of the wall
while terrain[tile - height * 8].to_i == 1
height += 1
end
self.src_rect.set(
((tile %
* 32) + 32 / @spalten * i,
((tile - 384) / 8 - height + 1) * 32,
32 / @spalten,
32 * height)
self.oy = height * 32 - 1
@height = height
end
end
class SWall < Wall
def set_src(terrain,tile,i)
super
self.src_rect.height -= 32
self.oy -= 32
end
end
class Game_Map
attr_reader :m7
alias scroll_down_m7 scroll_down
alias scroll_left_m7 scroll_left
alias scroll_right_m7 scroll_right
alias scroll_up_m7 scroll_up
alias setup_m7 setup
#don NOT stop scrolling anymore when end of map is reached
def scroll_down(distance)
if $game_map.m7
@display_y += distance
else
scroll_down_m7(distance)
end
end
def scroll_left(distance)
if $game_map.m7
@display_x -= distance
else
scroll_left_m7(distance)
end
end
def scroll_right(distance)
if $game_map.m7
@display_x += distance
else
scroll_right_m7(distance)
end
end
def scroll_up(distance)
if $game_map.m7
@display_y -= distance
else
scroll_up_m7(distance)
end
end
def name
return $data_maps[@map_id].name
end
def setup(id)
setup_m7(id)
@m7 = false
for part in self.name.split("[")
case part
when /#(.*)\]/
$game_system.angle = $1.to_i
when "m7]"
@m7 = true
when /-(.*)\]/
$game_system.hidewalls = $1.to_i
end
end
end
end
class Game_Character
alias screen_z_m7 screen_z
def screen_z(height = 0)
if $game_map.m7
if @always_on_top
return $game_map.height * 32 + 10
end
return @real_y / 4 + 33
else
screen_z_m7(height)
end
end
end
class Game_Player
alias center_m7 center
def center(x, y)
if $game_map.m7
$game_map.display_x = x * 128 - CENTER_X
$game_map.display_y = y * 128 - CENTER_Y
else
center_m7(x, y)
end
end
end
class Sprite_Character
#set event screen coords
alias update_m7 update
def update
update_m7
return unless $game_map.m7
self.y = $game_system.screen2m7_y(self.y - $game_system.scroll_y)
self.zoom_x = self.zoom_y = $game_system.screen2zoom(self.y)
self.x = 320 + (self.zoom_x * (self.x - 320))
end
end
class Spriteset_Map
def initialize
# Make viewports
@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
# Make tilemap
if $game_map.m7
@tilemap = M7Tilemap.new(@viewport1)
@tilemap.terrain = $game_map.terrain_tags
else
@tilemap = Tilemap.new(@viewport1)
end
@tilemap.tileset = RPG::Cache.tileset($game_map.tileset_name)
for i in 0..6
autotile_name = $game_map.autotile_names[i]
@tilemap.autotiles[i] = RPG::Cache.autotile(autotile_name)
end
@tilemap.map_data = $game_map.data
@tilemap.priorities = $game_map.priorities
# Make panorama plane
@panorama = Plane.new(@viewport1)
@panorama.z = -1000
# Make fog plane
@fog = Plane.new(@viewport1)
@fog.z = 3000
# Make character sprites
@character_sprites = []
for i in $game_map.events.keys.sort
sprite = Sprite_Character.new(@viewport1, $game_map.events[i])
@character_sprites.push(sprite)
end
@character_sprites.push(Sprite_Character.new(@viewport1, $game_player))
# Make weather
@weather = RPG::Weather.new(@viewport1)
# Make picture sprites
@picture_sprites = []
for i in 1..50
@picture_sprites.push(Sprite_Picture.new(@viewport2,
$game_screen.pictures[i]))
end
# Make timer sprite
@timer_sprite = Sprite_Timer.new
# Frame update
update
end
end