| 赞 | 3 |
| VIP | |
| 好人卡 | |
| 积分 | 21 |
| 经验 | |
| 最后登录 | 2025-8-7 |
| 在线时间 | 950 小时 |
- 梦石
- 0
- 星屑
- 2116
- 在线时间
- 950 小时
- 注册时间
- 2015-7-16
- 回帖
- 692

|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有账号?注册会员
×
theo 的反lag 搭配 mode 7 會出錯
開飛船時
反lag[pre lang="ruby"]#===============================================================================
# TheoAllen - Insane Anti Lag
# Version : 1.1
# Language : English
#-------------------------------------------------------------------------------
# With help from following people :
# - Tsukihime
# - KilloZapit
# - Galv
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Contact :
#-------------------------------------------------------------------------------
# *> http://www.rpgmakerid.com
# *> http://www.rpgmakervxace.net
# *> http://www.theolized.com
#===============================================================================
($imported ||= {})[:Theo_AntiLag] = true
#===============================================================================
# Change Logs:
# ------------------------------------------------------------------------------
# 2015.02.20 - Added page check enhancer to work with parallel process
# 2015.01.25 - Compatibility with Shaz's Mouse Script. def events_xy now should
# always return array,
# - Avoid error 'undefined method delete_sprite for nilClass'
# 2015.01.01 - Avoid unexpected error 'undefined method spriteset for scene'
# 2014.12.05 - Finished
#===============================================================================
=begin
------------------------------------------
*) Introduction :
------------------------------------------
As most of you already know, lag is common problem in RPG Maker games. You may
started to think it was because you have many events on map. And so, to avoid
lag, you split your map into part and limiting the event as well.
It's not entirely wrong because when you have a lot of events, program need
to checks all events. However, it wasn't done efficienly. This script
increase the efficiency on how default script works and prevent unecessary
update when it's not needed to gain speed.
However, I can not guarantee that it will have high compatibility since I
overwrite most of stuff. I will likely to make compatibility with my own
scripts. But I'm not sure about someone's script.
------------------------------------------
*) How to use :
------------------------------------------
Put this script below material but above main. And it's recommended to put
this above most of custom script.
Set the type of optimization that you like in config
You may disable some kind of optimization if you have compatibility issues
------------------------------------------
*) Terms of use :
------------------------------------------
Credit me, TheoAllen. You are free to edit this script by your own. As long
as you don't claim it's yours. For commercial purpose, don't forget to give me
a free copy of the game.
Additional people to put in credit credit list are listed in header above.
You should give them a free copy of your game as well if it's commercial ;)
=end
#==============================================================================
# Configurations :
#==============================================================================
module Theo
module AntiLag
#=============================================================================
# *) Normal optimization
#-----------------------------------------------------------------------------
# This kind of optimization is for normal usage. These optimization may works
# only if the total events on map is around 200 - 300.
#=============================================================================
#-----------------------------------------------------------------------------
Optimize_XY = true
#-----------------------------------------------------------------------------
# By default, event position checking is to check ALL the events on the map.
# If you want to check an event is in x,y position, it ask EVERY event if
# their position is match. By using this optimization, all events registered
# to the map table so that the engine won't check all events on map. Instead,
# it checks if there's event on a certain table.
#
# This kind of optimization is recommended to set it to true. However, it may
# not compatible with any pixel movement since they using box collider instead
# of using grid.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
Optimize_Event = true
#-----------------------------------------------------------------------------
# By default, if the engine want to check if there's event starting, they
# checked ALL the events on map. They did it in every frame. If you have 200
# events in map, they checked 60 x 200 events per second.
#
# By using this optimization, if event is triggered, it will be registered
# into a record. And then engine checked if there is event on the record
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
Optimize_Sprite = true
#-----------------------------------------------------------------------------
# By default, the engine still update every sprites which located off screen.
# This might waste the time since updating it is not necessary sometimes. By
# using this optimization, it ignores character sprite that already off screen
#-----------------------------------------------------------------------------
#=============================================================================
# *) Insane optimization
#-----------------------------------------------------------------------------
# This kind of optimization is to overcome the problem of using event beyond
# 230 on the map which normal optimization is failed to do. This optimization
# uses insane algorithm like table search and dispose any unecessary sprite on
# the fly.
#=============================================================================
#-----------------------------------------------------------------------------
Table_Limit_Search = 230
#-----------------------------------------------------------------------------
# Table search is a custom algorithm to grab events based on the map table.
# Instead of iterating all events and checked them if they're on the screen,
# it checked the visible map table instead. So, event that located far away
# from the player won't be updated. But any parallel process or autorun events
# or move route for an event will still updated.
#
# Table limit search means that if the total of events on map is above the
# limit, this script will switch event update algorithm to table search. So
# you will not worrying about having 999 or even 10.000 events on map.
#
# Table search required Optimize_XY to set to true.
#
# If you don't want to use table search algorithm, just put the parameter
# to nil.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
Table_Range_Search = 2
#-----------------------------------------------------------------------------
# This determine how far table search will perform check. Putting 3 means that
# it will update the event that located 3 tiles away from the screen.
#
# Keep in mind that the longer range search will affect the performance as
# well. It's recommended to put it between 2 - 4
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
Dispose_Sprite = true
#-----------------------------------------------------------------------------
# Sometimes, limiting the events which is being updated is not enough. Sprite
# objects is still being performace killer. Disposing sprite which is already
# off screen will greatly affect the performance. This kind of optimization
# is enabled only if the table search is used.
#
# Disposing sprite on the fly might be problematic sometimes. When something
# wrong happened, you can disable dispose sprite be setting this to false.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
PageCheck_Enchancer = true
#-----------------------------------------------------------------------------
# When a lot of events put together in one map, and each has 20 pages, and
# you have parallel process to change the variable or switches, you will see
# noticable lag.
#
# This kind of enhancer only refresh the visible events on the screen or when
# the event is on the visible range. So that it prevents to refresh all events
# This concept is a fool proof to the player since they will never know what
# is in their visible range
#
# However, this may ruin some system since this concept is still experimental.
#-----------------------------------------------------------------------------
end
end
#===============================================================================
# *) Final note :
#-------------------------------------------------------------------------------
# After all, these are just my attempt to speed up the game. Performance are
# still under influence by many factors. These include but may not limited to
#
# - Your CPU speed
# - Your laptop / PC temperature
# - How much power do you give for your CPU
# - Multi tasking
# - Someone's script
#
# I once used RM in old computer. When I switched to more advanced laptop, I
# saw that 60 FPS is really smooth.
#
# If your CPU seems overheat, turn off your laptop / PC for a while for cooling.
# My laptop was once overheat due to broken fan. When I played my own game I
# got 10 FPS. I made my own antilag and no one of them worked until I realized
# my laptop was overheat.
#
# Power saver mode in laptop may affect performance. Try to go high performance
# instead and let see if the lag gone. Once my friend played my game using power
# saver mode, and he got 15 FPS.
#
# If you have many programs running at same time, it may cause a little lag in
# RPG Maker games. Something like the screen won't be updated for a while.
#
# Some scripts can affect performance if it's not done right. This antilag
# script is tested using default script without additional scripts which
# directly affect something on map.
#
#-------------------------------------------------------------------------------
# *) Below this line is sacred place to visit. Unless you have enough skill,
# do not try to enter or any risk is yours.
#===============================================================================
#===============================================================================
# ** MapTable
#-------------------------------------------------------------------------------
# This class used to register the event into 2D table to increase performance
#===============================================================================
class MapTable
#-----------------------------------------------------------------------------
# * Initialize
#-----------------------------------------------------------------------------
def initialize
@table = []
($game_map.width + 1).times do |x|
@table[x] = []
($game_map.height + 1).times do |y|
@table[x][y] = []
end
end
end
#-----------------------------------------------------------------------------
# * Set value
#-----------------------------------------------------------------------------
def set(x,y,val)
@table[x][y] << val
end
#-----------------------------------------------------------------------------
# * Get array
#-----------------------------------------------------------------------------
def get(x,y)
@table[x][y]
end
end
#===============================================================================
# ** Array
#===============================================================================
class Array
# Just a fool proof
def values
return self
end
end
#===============================================================================
# ** Game_Map
#===============================================================================
class Game_Map
#-----------------------------------------------------------------------------
# * Public attributes
#-----------------------------------------------------------------------------
attr_accessor :event_redirect # Redirect events
attr_reader :forced_update_events # To keep force move route updated
attr_reader :keep_update_events # To keep parallel process updated
attr_reader :cached_events # To store event that need to be updated
attr_reader :starting_events # To store activated event
attr_reader :table # 2D Map table
#-----------------------------------------------------------------------------
# * Constant
#-----------------------------------------------------------------------------
EVENT_LIMIT = Theo::AntiLag::Table_Limit_Search
RANGE = Theo::AntiLag::Table_Range_Search
#-----------------------------------------------------------------------------
# * Alias method : Setup Events
#-----------------------------------------------------------------------------
alias theo_antilag_setup_events setup_events
def setup_events
@table = MapTable.new
@forced_update_events = []
@keep_update_events = []
@starting_events = []
@refreshed_events = []
theo_antilag_setup_events
select_on_screen_events
end
#-----------------------------------------------------------------------------
# * Overwrite method : Events
#-----------------------------------------------------------------------------
def events
@event_redirect ? @cached_events : @events
end
#///////////////////////////////////////////////////////////////////////////////
if Theo::AntiLag::Optimize_XY
#///////////////////////////////////////////////////////////////////////////////
#-----------------------------------------------------------------------------
# * Overwrite method : Event XY
#-----------------------------------------------------------------------------
def events_xy(x, y)
@table.get(x,y) || []
end
#-----------------------------------------------------------------------------
# * Overwrite method : Event XY nt
#-----------------------------------------------------------------------------
def events_xy_nt(x, y)
@table.get(x,y).select do |event|
event.pos_nt?(x, y)
end
end
#///////////////////////////////////////////////////////////////////////////////
end
#///////////////////////////////////////////////////////////////////////////////
if Theo::AntiLag::Optimize_Event
#///////////////////////////////////////////////////////////////////////////////
#-----------------------------------------------------------------------------
# * Overwrite method : Setup starting event
#-----------------------------------------------------------------------------
def setup_starting_map_event
event = @starting_events[0]
event.clear_starting_flag if event
@interpreter.setup(event.list, event.id) if event
event
end
#-----------------------------------------------------------------------------
# * Overwrite method : Any event starting?
#-----------------------------------------------------------------------------
def any_event_starting?
!@starting_events.empty?
end
#///////////////////////////////////////////////////////////////////////////////
end
#///////////////////////////////////////////////////////////////////////////////
#-----------------------------------------------------------------------------
# * Overwrite method : Refresh
#-----------------------------------------------------------------------------
def refresh
return table_refresh if table_update? && Theo::AntiLag::PageCheck_Enchancer
@events.each_value {|event| next if event.never_refresh; event.refresh }
@common_events.each {|event| event.refresh }
refresh_tile_events
@need_refresh = false
end
#-----------------------------------------------------------------------------
# * New method : Refresh event by table search
#-----------------------------------------------------------------------------
def table_refresh
@refreshed_events = []
@tile_events = []
@common_events.each {|event| event.refresh }
@need_refresh = false
end
#-----------------------------------------------------------------------------
# * Overwrite method : Update events
#-----------------------------------------------------------------------------
def update_events
last_events = (@cached_events.dup rescue @events.values)
select_on_screen_events
events = @cached_events | @keep_update_events | @forced_update_events
if Theo::AntiLag::Dispose_Sprite
offscreen_events = last_events - events
offscreen_events.each {|event| event.delete_sprite}
end
events.each {|event| event.update}
@common_events.each {|event| event.update}
end
#-----------------------------------------------------------------------------
# * New method : Select on screen events
#-----------------------------------------------------------------------------
def select_on_screen_events
unless table_update?
@cached_events = @events.values
return
end
#---------------------------------------------------------------------------
# * Table search algorithm
#---------------------------------------------------------------------------
new_dpx = display_x.to_i
new_dpy = display_y.to_i
dpx = loop_horizontal? ? new_dpx - RANGE : [new_dpx - RANGE, 0].max
dpy = loop_vertical? ? new_dpy - RANGE : [new_dpy - RANGE, 0].max
sw = (Graphics.width >> 5) + RANGE * 2
sh = (Graphics.height >> 5) + RANGE * 2
@cached_events = []
sw.times do |x|
sh.times do |y|
xpos = loop_horizontal? ? (x + dpx) % width : x + dpx
ypos = loop_vertical? ? (y + dpy) % height : y + dpy
next if xpos >= width || ypos >= height
ary = @table.get(xpos, ypos)
ary.each do |ev|
unless @refreshed_events.include?(ev.id)
ev.refresh
@tile_events << ev if ev.tile?
@refreshed_events << ev.id
end
end if Theo::AntiLag::PageCheck_Enchancer
@cached_events += ary
end
end
@cached_events.uniq!
end
#-----------------------------------------------------------------------------
# * Check if table search need to be performed or not
#-----------------------------------------------------------------------------
def table_update?
EVENT_LIMIT && @events.size > EVENT_LIMIT && Theo::AntiLag::Optimize_XY
end
end
#===============================================================================
# ** Game_Temp
#===============================================================================
class Game_Temp
attr_reader :event_sprites
#-----------------------------------------------------------------------------
# * Alias method : Initialize
#-----------------------------------------------------------------------------
alias theo_antilag_init initialize
def initialize
theo_antilag_init
@event_sprites = {}
end
end
#===============================================================================
# ** Game_CharacterBase
#===============================================================================
class Game_CharacterBase
#-----------------------------------------------------------------------------
# * Empty method : Sprite
#-----------------------------------------------------------------------------
def sprite
return nil
end
#-----------------------------------------------------------------------------
# * Empty method : Sprite =
#-----------------------------------------------------------------------------
def sprite=(spr)
end
end
#===============================================================================
# ** Game_Event
#===============================================================================
class Game_Event
#-----------------------------------------------------------------------------
# * Never refesh flag
#-----------------------------------------------------------------------------
attr_reader :never_refresh
#-----------------------------------------------------------------------------
# * Alias method : Initialize
#-----------------------------------------------------------------------------
alias theo_antilag_init initialize
def initialize(map_id, event)
theo_antilag_init(map_id, event)
$game_map.table.set(x,y,self)
@last_x = @x
@last_y = @y
end
#-----------------------------------------------------------------------------
# * Alias method : Update
#-----------------------------------------------------------------------------
alias theo_antilag_update update
def update
if (sprite && sprite.disposed?) || sprite.nil?
spriteset = SceneManager.scene.spriteset
return unless spriteset
spriteset.add_sprite(self)
end
theo_antilag_update
if Theo::AntiLag::Optimize_XY && (@last_x != @x || @last_y != @y)
$game_map.table.get(@last_x, @last_y).delete(self)
$game_map.table.set(@x,@y,self)
@last_x = @x
@last_y = @y
end
end
#-----------------------------------------------------------------------------
# * Alias method : Start
#-----------------------------------------------------------------------------
alias theo_antilag_start start
def start
theo_antilag_start
return unless Theo::AntiLag::Optimize_Event
$game_map.starting_events << self if @starting
end
#-----------------------------------------------------------------------------
# * Alias method : Clear starting flag
#-----------------------------------------------------------------------------
alias theo_antilag_clear_start clear_starting_flag
def clear_starting_flag
theo_antilag_clear_start
return unless Theo::AntiLag::Optimize_Event
$game_map.starting_events.delete(self)
end
#-----------------------------------------------------------------------------
# * Alias method : Setup page setting
#-----------------------------------------------------------------------------
alias theo_antilag_setup_page_settings setup_page_settings
def setup_page_settings
theo_antilag_setup_page_settings
if @event.pages.size == 1 && no_condition?(@event.pages[0].condition)
@never_refresh = true
end
if @trigger == 3 || @interpreter
$game_map.keep_update_events << self
$game_map.keep_update_events.uniq!
else
$game_map.keep_update_events.delete(self)
end
end
#-----------------------------------------------------------------------------
# * Check if the events has no page condition
#-----------------------------------------------------------------------------
def no_condition?(page)
!page.switch1_valid && !page.switch2_valid && !page.variable_valid &&
!page.self_switch_valid && !page.item_valid && !page.actor_valid
end
#-----------------------------------------------------------------------------
# * Delete sprite
#-----------------------------------------------------------------------------
def delete_sprite
sprset = SceneManager.scene.spriteset
return unless sprset
SceneManager.scene.spriteset.delete_sprite(sprite)
end
#-----------------------------------------------------------------------------
# * Overwrite method : Force move route
#-----------------------------------------------------------------------------
def force_move_route(move_route)
super
$game_map.forced_update_events << self
$game_map.forced_update_events.uniq!
end
#-----------------------------------------------------------------------------
# * Overwrite method : Restore move route
#-----------------------------------------------------------------------------
def restore_move_route
super
$game_map.forced_update_events.delete(self)
end
#-----------------------------------------------------------------------------
# * Overwrite method : Sprite
#-----------------------------------------------------------------------------
def sprite
$game_temp.event_sprites[@id]
end
#-----------------------------------------------------------------------------
# * Overwrite method : Sprite =
#-----------------------------------------------------------------------------
def sprite=(spr)
$game_temp.event_sprites[@id] = spr
end
end
#===============================================================================
# ** Sprite Character
#===============================================================================
class Sprite_Character
#-----------------------------------------------------------------------------
# * Alias method : Initialize
#-----------------------------------------------------------------------------
alias theo_antilag_init initialize
def initialize(viewport, character = nil)
character.sprite = self if character
theo_antilag_init(viewport, character)
end
#-----------------------------------------------------------------------------
# * Alias method : Update
#-----------------------------------------------------------------------------
alias theo_antilag_update update
def update
@sx = @character.screen_x
@sy = @character.screen_y
if Theo::AntiLag::Optimize_Sprite && !need_update?
self.visible = false
return
end
theo_antilag_update
end
#-----------------------------------------------------------------------------
# * New method : Determine if on screen
#-----------------------------------------------------------------------------
def need_update?
return true if graphic_changed?
return true if @character.animation_id > 0
return true if @balloon_sprite
return true if @character.balloon_id != 0
w = Graphics.width
h = Graphics.height
cw = @cw || 32
ch = @ch || 32
@sx.between?(-cw,w+cw) && @sy.between?(0,h+ch)
end
#-----------------------------------------------------------------------------
# * Overwrite update position.
# To limit screen_x and screen_y to be called many times
#-----------------------------------------------------------------------------
def update_position
move_animation(@sx - x, @sy - y)
self.x = @sx
self.y = @sy
self.z = @character.screen_z
end
#-----------------------------------------------------------------------------
# * Overwrite animation origin
# Since X and Y axis of sprite is not updated when off screen
#-----------------------------------------------------------------------------
def set_animation_origin
if @animation.position == 3
if viewport == nil
@ani_ox = Graphics.width / 2
@ani_oy = Graphics.height / 2
else
@ani_ox = viewport.rect.width / 2
@ani_oy = viewport.rect.height / 2
end
else
@ani_ox = @sx - ox + width / 2
@ani_oy = @sy - oy + height / 2
if @animation.position == 0
@ani_oy -= height / 2
elsif @animation.position == 2
@ani_oy += height / 2
end
end
end
end
#===============================================================================
# ** Spriteset_Map
#===============================================================================
class Spriteset_Map
#-----------------------------------------------------------------------------
# * Alias method : create character
#-----------------------------------------------------------------------------
alias theo_antilag_create_characters create_characters
def create_characters
$game_map.event_redirect = Theo::AntiLag::Dispose_Sprite
theo_antilag_create_characters
$game_map.event_redirect = false
end
#-----------------------------------------------------------------------------
# * New method : delete sprite
#-----------------------------------------------------------------------------
def delete_sprite(spr)
return unless spr
return if spr.disposed?
@character_sprites.delete(spr)
spr.dispose
end
#-----------------------------------------------------------------------------
# * New method : add sprite
#-----------------------------------------------------------------------------
def add_sprite(char)
spr = Sprite_Character.new(@viewport1, char)
@character_sprites.push(spr)
end
end
#===============================================================================
# ** Scene_Base
#===============================================================================
class Scene_Base
attr_reader :spriteset
end[/pre]
mod7
[pre lang="ruby"]#====================================================================
# Mode 7 Ace
# v.1.9
# Auteur : MGC
#
# Il s'agit d'un script de mode 7 basique pour RMVX Ace.
#
# - Permet une inclinaison de la carte de 0° à 89°
# - Toute la carte est inclinée, sans relief. Seuls les évènements
# paraissent dressés verticalement.
# - L'effet de colorisation à l'horizon est personnalisable.
# - Les tiles animés sont supportés, ainsi que le bouclage de la carte.
# - possibilité de zoomer (de 1:8 à 8:1) quand le mode 7 est activé.
#
# IMPORTANT : SI VOUS RENCONTREZ DU LAG, VEUILLEZ VOUS ASSURER D'AVOIR
# DECOCHER "REDUCE SCREEN FLICKERING" (F1).
#
# Nécessite :
# - le fichier MGC_Mode7_Ace_1_9.dll à la racine du projet
# - les 3 fichiers graphiques suivants, déposés dans Pictures/ :
# - autotiles_data.png
# - autotiles_data_small.png
# - autotiles_data_xsmall.png
#
# Configuration :
# - MODE7_MAPS_ID : Contient la liste des id des cartes pour lesquelles
# le mode 7 est appliqué dès l'entrée sur ces cartes
# - MODE7_DEFAULT_ZOOM : valeur de zoom par défaut qui s'applique dès le
# passage en mode 7. Compris entre 0.125 et 8.0.
# - MODE7_DEFAULT_ANGLE : valeur d'angle d'inclinaison par défaut qui
# s'applique dès le passage en mode 7. Compris entre 0 et 89.
# - MODE7_VIEW_LIMIT : nombre de tiles supplémentaires à afficher (en plus
# des 13 pour la vue normale de la carte en 544 * 416) avant l'horizon.
# - MODE7_FADING_DISTANCE : nombre de tiles avant l'horizon subissant un
# dégradé de ton et/ou d'opacité.
# - MODE7_FADING_TONE : composantes de couleur R, G, B vers lesquelles tend
# le dégradé de ton à l'horizon. Chaque composantes peut varier
# entre -255 et 255.
# - MODE7_FADING_OPACITY : opacité vers laquelle tend le dégradé d'opacité ton
# à l'horizon. Compris entre 255 (pas de dégradé d'opacité) et 0.
# - MODE7_SCAN_STEP : méthode de rafraîchissement de l'écran :
# - 1 : l'écran est entièrement redessiné en 1 frame. Déconseillé
# car extrêmement gourmand en ressources.
# - 2 : l'écran est redessiné en 2 frames (une ligne de l'écran sur
# deux est dessinée pour chaque frame).
# - 3 : l'écran est redessiné en 3 frames (une ligne de l'écran sur
# trois est dessinée pour chaque frame). Conseillé s'il y a
# trop de lag.
# - MODE7_TERRAIN_TAGS : liste de valeurs de terrain tags pour lesquelles les
# tiles doivent être dessinés verticalement en mode 7. Si le paramètre
# MODE7_VERTICAL_TILES_TYPE n'a pas sa valeur égale à 0, utiliser
# plusieurs valeurs permet de séparer des regroupements de tiles
# contigus.
# - MODE7_VERTICAL_TILES_TYPE :
# - 0 : aucun regroupement des tiles verticaux même si des tiles voisins
# ont le même terrain tag. Pour un tile avec un terrain tag
# configuré pour être dessiné verticalement, un sprite de
# dimensions 32*32 est créé. A priori aucun intérêt sans la
# rotation, car aura le même effet que la valeur 2 mais avec
# plus de sprites à l'écran, donc plus de ralentissements.
# - 1 : regroupement des tiles verticaux contigus sur la même colonne
# ayant le même terrain tag. Un sprite est créé par regroupement,
# le tile le plus bas du regroupement servant de base au sprite.
# A priori aucun intérêt sans la rotation, car aura le même effet
# que la valeur 3 mais avec plus de sprites à afficher.
# - 2 : regroupement des tiles verticaux contigus sur la même ligne
# ayant le même terrain tag. Un sprite est créé par regroupement,
# l'origine horizontale étant fixée au milieu du regroupement.
# - 3 : regroupement des tiles verticaux contigus ayant le même
# terrain tag, quelle que soit la ligne ou la colonne. Un sprite
# est créé par regroupement, le tile le plus bas du regroupement
# servant de base au sprite et l'origine horizontale étant fixée
# au milieu du regroupement. Valeur par défaut.
# - MODE7_ALWAYS_DRAW_TILES_ON_MAP :
# - 0 : les tiles verticaux ne sont pas dessinés couchés sur la carte.
# Valeur par défaut.
# - 1 : les tiles verticaux sont également dessinés couchés sur la carte.
# - MODE7_PARALLAXED_MAPS_ID : Contient la liste des id des cartes en mode 7
# pour lesquelles le panorama est utilisé en tant que couche inférieure.
# Vous pouvez utiliser un second panorama pour le fond, il faut ajouter
# dans les notes de la carte le texte suivant : [m7a_pano:nom_du_fichier]
#
# Utilisation :
# Commandes utilisables comme commandes d'évènement avec Script... :
# - MGC.start_mode7 : lance le mode 7 pour la carte
# - MGC.to_mode7_angle(nouvel angle, durée de transition)
# - MGC.to_mode7_zoom(nouvelle valeur de zoom, durée de transition)
# - MGC.end_mode7 : quitte le mode 7
# - MGC.set_mode7_scan(nouvelle valeur) : modifie le paramètre MODE7_SCAN_STEP
#
# Vous pouvez ajouter des commandes dans le nom des cartes pour forcer le
# paramétrage du mode 7 de la carte. Les paramètres dans le nom de la
# carte sont prioritaires par rapport à ceux dans la partie CONFIGURATION
# - [M7] : active le mode 7 pour la carte
# - [Ax], où x est un entier entre 0 et 89 : angle de la carte
# - [Zx], où x est un décimal entre 0.125 et 8.0 : zoom de la carte
# - [FDx], où x est un entier positif : nombre de tiles avant l'horizon
# subissant un dégradé de ton et/ou d'opacité
# - [FTx,y,z], où x, y et z sont des entiers entre -255 et 255 :
# composantes de couleur R, G, B vers lesquelles tend le dégradé
# de ton à l'horizon
# - [FOx], où x est un entier entre 0 et 255 : opacité vers laquelle
# tend le dégradé d'opacité ton à l'horizon
# - [P] : le panorama est utilisé en tant que couche inférieure de la carte
# Exemple :
# My Worldmap [M7][A55][Z0.5][FD20][FT128,64,-32][FO128]
#====================================================================
module MGC
#--------------------------------------------------------------------------
# * CONFIGURATION
#--------------------------------------------------------------------------
MODE7_MAPS_ID = []
MODE7_DEFAULT_ZOOM = 1.0
MODE7_DEFAULT_ANGLE = 0
MODE7_VIEW_LIMIT = 26
MODE7_FADING_DISTANCE = 13
MODE7_FADING_TONE = Tone.new(64, 64, 128)
MODE7_FADING_OPACITY = 0
MODE7_SCAN_STEP = 2
MODE7_TERRAIN_TAGS = [1, 2] # [1.7]
MODE7_VERTICAL_TILES_TYPE = 3 # [1.7]
MODE7_ALWAYS_DRAW_TILES_ON_MAP = 0 # [1.7]
MODE7_PARALLAXED_MAPS_ID = [] # [1.9]
#--------------------------------------------------------------------------
# * Initialisation
#--------------------------------------------------------------------------
@mode7_zoom = 1.0
@mode7_active = false
#--------------------------------------------------------------------------
# * Lancement du mode 7
#--------------------------------------------------------------------------
def self.start_mode7
@end_mode7 = false
@spriteset.start_mode7
end
#--------------------------------------------------------------------------
# * Fin du mode 7
#--------------------------------------------------------------------------
def self.end_mode7
@end_mode7 = true
self.to_mode7_zoom(1.0, 1)
end
#--------------------------------------------------------------------------
# * Setter pour l'attribut spriteset
#--------------------------------------------------------------------------
def self.spriteset=(spriteset)
@spriteset = spriteset
end
#--------------------------------------------------------------------------
# * Initialisation des données du mode 7
#--------------------------------------------------------------------------
def self.initialize_mode7(reset = false) # [1.9]
if reset
self.mode7_angle = $game_map.get_default_mode7_angle
@mode7_zoom = $game_map.get_default_mode7_zoom
else
self.mode7_angle = $game_system.mode7_angle ? $game_system.mode7_angle :
$game_map.get_default_mode7_angle
@mode7_zoom = $game_system.mode7_zoom ? $game_system.mode7_zoom :
$game_map.get_default_mode7_zoom
end
@mode7_angle_duration = 0
@mode7_zoom_incr = Math.log(@mode7_zoom) / Math.log(2)
@mode7_zoom_duration = 0
pivot = (Graphics.height >> 1) + 12
@mode7_data = [pivot, pivot.to_f / Graphics.height, 1.0, 1.0, 0,
Graphics.height, 0, 0, 0, 0]
end
#--------------------------------------------------------------------------
# * Change Map
#--------------------------------------------------------------------------
def self.start_change_map
self.mode7_angle = $game_map.get_default_mode7_angle
@mode7_angle_duration = 0
@mode7_zoom = $game_map.get_default_mode7_zoom
@mode7_zoom_incr = Math.log(@mode7_zoom) / Math.log(2)
@mode7_zoom_duration = 0
@change_map = true
end
#--------------------------------------------------------------------------
# * Is Changing Map ?
#--------------------------------------------------------------------------
def self.is_changing_map?
return @change_map
end
#--------------------------------------------------------------------------
# * End Change Map
#--------------------------------------------------------------------------
def self.end_change_map
@change_map = false
end
#--------------------------------------------------------------------------
# * Getter pour l'attribut mode7_data
#--------------------------------------------------------------------------
def self.mode7_data
return @mode7_data
end
#--------------------------------------------------------------------------
# * Getter pour l'attribut mode7_zoom
#--------------------------------------------------------------------------
def self.mode7_zoom
return @mode7_zoom
end
#--------------------------------------------------------------------------
# * Getter pour l'attribut mode7_angle
#--------------------------------------------------------------------------
def self.mode7_angle
return @mode7_angle
end
#--------------------------------------------------------------------------
# * Getter pour l'attribut mode7_active
#--------------------------------------------------------------------------
def self.mode7_active
return @mode7_active
end
#--------------------------------------------------------------------------
# * Setter pour l'attribut mode7_active
#--------------------------------------------------------------------------
def self.mode7_active=(flag)
$game_system.mode7_active = flag
@mode7_active = flag
end
#--------------------------------------------------------------------------
# * Setter pour l'attribut mode7_zoom
#--------------------------------------------------------------------------
def self.mode7_zoom=(zoom_value)
unless mode7_zoom == zoom_value
if zoom_value < 0.125 || zoom_value > 8.0 then return end
@mode7_zoom = zoom_value
$game_system.mode7_zoom = @mode7_zoom
$game_player.center($game_player.x, $game_player.y)
end
end
#--------------------------------------------------------------------------
# * Incrémentation de la valeur du zoom du mode 7
#--------------------------------------------------------------------------
def self.incr_mode7_zoom(val = 0.02)
@mode7_zoom_incr += val
new_zoom = 2 ** @mode7_zoom_incr
self.mode7_zoom = new_zoom
end
#--------------------------------------------------------------------------
# * Pour aller progressivement vers une nouvelle valeur de zoom du mode 7
#--------------------------------------------------------------------------
def self.to_mode7_zoom(new_zoom, duration)
unless mode7_zoom == new_zoom
if new_zoom < 0.125 || new_zoom > 8.0 then return end
@mode7_zoom_duration = duration
target_zoom_incr = Math.log(new_zoom) / Math.log(2)
@mode7_zoom_step = (target_zoom_incr - @mode7_zoom_incr) / duration
@target_mode7_zoom = new_zoom
end
end
#--------------------------------------------------------------------------
# * Setter pour l'attribut mode7_angle
#--------------------------------------------------------------------------
def self.mode7_angle=(new_angle)
unless new_angle == @mode7_angle
@mode7_angle = [[new_angle, 0].max, 89].min
@mode7_angle_real = @mode7_angle
$game_system.mode7_angle = @mode7_angle
end
end
#--------------------------------------------------------------------------
# * Autre setter pour l'attribut mode7_angle, ne réinitialisant pas @mode7_angle_real
#--------------------------------------------------------------------------
def self.set_mode7_angle(new_angle)
unless new_angle == @mode7_angle
@mode7_angle = [[new_angle, 0].max, 89].min
$game_system.mode7_angle = @mode7_angle
end
end
#--------------------------------------------------------------------------
# * Incrémentation de la valeur de l'angle du mode 7
#--------------------------------------------------------------------------
def self.incr_mode7_angle
@mode7_angle_real += @mode7_angle_step
self.set_mode7_angle(@mode7_angle_real.to_i)
end
#--------------------------------------------------------------------------
# * Pour aller progressivement vers une nouvelle valeur de l'angle du mode 7
#--------------------------------------------------------------------------
def self.to_mode7_angle(new_angle, duration)
unless @mode7_angle == new_angle
new_angle = [[new_angle, 0].max, 89].min
@mode7_angle_duration = duration
@mode7_angle_step = (new_angle - @mode7_angle).to_f / duration
@target_mode7_angle = new_angle
end
end
#--------------------------------------------------------------------------
# * Mise à jour du mode 7
#--------------------------------------------------------------------------
def self.update_mode7
if @mode7_active
if @mode7_zoom_duration > 0
@mode7_zoom_duration -= 1
if @mode7_zoom_duration == 0
self.mode7_zoom = @target_mode7_zoom
else
self.incr_mode7_zoom(@mode7_zoom_step)
end
elsif @mode7_angle_duration > 0
@mode7_angle_duration -= 1
if @mode7_angle_duration == 0
self.mode7_angle = @target_mode7_angle
else
self.incr_mode7_angle
end
elsif @end_mode7
@spriteset.end_mode7
@end_mode7 = false
end
end
end
#--------------------------------------------------------------------------
# * Vérifie si un effet est en cours
#--------------------------------------------------------------------------
def self.effect?
return @mode7_active && (@mode7_zoom_duration > 0 ||
@mode7_angle_duration > 0 || @end_mode7)
end
#--------------------------------------------------------------------------
# * Modifie la valeur de la méthode de rafraîchissement de l'écran
#--------------------------------------------------------------------------
def self.set_mode7_scan(new_value)
new_value = [[new_value, 1].max, 3].min
unless MODE7_SCAN_STEP == new_value
self.const_set(:MODE7_SCAN_STEP, new_value)
end
end
#==============================================================================
# ** MGC::Mode7_Map
#==============================================================================
class Mode7_Map
#--------------------------------------------------------------------------
# * Attributs
#--------------------------------------------------------------------------
attr_reader :viewport, :visible, :ox, :oy, :opacity, :blend_type, :color,
:tone, :wave_amp, :wave_length, :wave_speed, :wave_phase, :zoom, :map_data,
:flags
attr_accessor :bitmaps, :flash_data
attr_reader :alpha, :parameters
attr_reader :param_tiles # [1.7]
attr_reader :map_id # [1.9]
#--------------------------------------------------------------------------
# * Constantes
#--------------------------------------------------------------------------
RENDER = Win32API.new("MGC_Mode7_Ace_Rot_1_9", "renderMode7", "l", "l")
#--------------------------------------------------------------------------
# * Initialisation
#--------------------------------------------------------------------------
def initialize(viewport)
@viewport = viewport
self.bitmaps = [0, 0, 0, 0, 0, 0, 0, 0, 0]
@map_data = 0
@flags = 0
self.flash_data = nil
@cx = Graphics.width >> 1
@cy = Graphics.height >> 1
@sprite_render = Sprite.new(viewport)
@render = Bitmap.new(Graphics.width, Graphics.height)
@sprite_render.bitmap = @render
@sprite_render.x = 0
@sprite_render.y = 0
@sprite_render.z = 0
@zoom = 1.0
@view_limit = MODE7_VIEW_LIMIT << 5
m7_data = Table.new(6, Graphics.height) # [1.7]
@parameters = [@render, 0, map_data, bitmaps,
Cache.picture('autotiles_data'), Cache.picture('autotiles_data_small'),
Cache.picture('autotiles_data_xsmall'), 0, 0, 0, 0, 0, 0, 0, 4096,
100, $game_map.loop_horizontal?, $game_map.loop_vertical?, MODE7_SCAN_STEP,
0, m7_data, 2048, 0, MGC.mode7_data[5], MGC.mode7_data[0], 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0]
@parameters << $game_map.tileset.flags # 36 [1.7]
@parameters << MGC::MODE7_ALWAYS_DRAW_TILES_ON_MAP # 37 [1.7]
@parameters << MGC::MODE7_TERRAIN_TAGS # 38 [1.7]
@parameters << 0 # 39 [1.9]
refresh_fading
MGC.mode7_data[9] = m7_data
self.alpha = 0
self.visible = true
self.zoom = 1.0
self.ox = 0
self.oy = 0
self.opacity = 255
self.blend_type = 0
self.color = Color.new
self.tone = Tone.new
self.wave_amp = 0
self.wave_length = 180
self.wave_speed = 360
self.wave_phase = 0.0
@initialization = true
@param_tiles = [Bitmap.new(32, 32), bitmaps,
Cache.picture('autotiles_data'),
Cache.picture('autotiles_data_small'),
Cache.picture('autotiles_data_xsmall'), 0, [0, 0, 0]] # [1.7]
@map_id = $game_map.map_id # [1.9]
end
#--------------------------------------------------------------------------
# * Refresh Fading
#--------------------------------------------------------------------------
def refresh_fading
fading_dist = $game_map.get_default_fading_distance << 5
fading_begin = Graphics.height + @view_limit - fading_dist
@parameters[30] = fading_begin
@parameters[31] = fading_dist
@parameters[32] = $game_map.get_default_fading_tone.red.to_i
@parameters[33] = $game_map.get_default_fading_tone.green.to_i
@parameters[34] = $game_map.get_default_fading_tone.blue.to_i
@parameters[35] = $game_map.get_default_fading_opacity
end
#--------------------------------------------------------------------------
# * Refresh all the parameters dependent on the angle of slant
#--------------------------------------------------------------------------
def refresh_alpha
# angle of slant
alpha_rad = (Math::PI * alpha) / 180
cos_alpha_real = Math.cos(alpha_rad)
sin_alpha_real = Math.sin(alpha_rad)
cos_alpha = (2048 * cos_alpha_real).to_i
sin_alpha = (2048 * sin_alpha_real).to_i
distance_h = MGC.mode7_data[5]
pivot = MGC.mode7_data[0]
# h0, z0 : intermediate values used to calculate the slope
h0 = (-distance_h * pivot * cos_alpha) / ((distance_h << 11) +
pivot * sin_alpha) + pivot
z0 = (distance_h << 11).to_f / ((distance_h << 11) + pivot * sin_alpha)
# slope
slope_value = (1.0 - z0) / (pivot - h0)
slope_value_map = (131072 * slope_value).to_i
corrective_value = 1.0 - pivot * slope_value
corrective_value_map = (131072 * corrective_value).to_i
last_line = ((-pivot - @view_limit) * zoom).to_i
height_limit = (distance_h * last_line * cos_alpha) /
((distance_h << 11) - last_line * sin_alpha) + pivot
height_limit = [height_limit.to_i, 0].max
parameters[21] = cos_alpha
parameters[22] = sin_alpha
parameters[25] = slope_value_map
parameters[26] = corrective_value_map
parameters[27] = height_limit
parameters[29] = MODE7_SCAN_STEP
@need_refresh = true
MGC.mode7_data[3] = cos_alpha_real
MGC.mode7_data[4] = sin_alpha_real
MGC.mode7_data[6] = slope_value
MGC.mode7_data[7] = corrective_value
MGC.mode7_data[8] = height_limit
end
#--------------------------------------------------------------------------
# * Setter pour l'attribut map_data
#--------------------------------------------------------------------------
def map_data=(new_map_data)
@map_data = new_map_data
parameters[2] = @map_data
end
#--------------------------------------------------------------------------
# * Charge le panorama en mode 7 [1.9]
#--------------------------------------------------------------------------
def parallax=(new_parallax)
if new_parallax
parameters[39] = new_parallax
else
parameters[39] = 0
end
end
#--------------------------------------------------------------------------
# * Setter pour l'attribut flags
#--------------------------------------------------------------------------
def flags=(new_flags)
@flags = new_flags
parameters[7] = @flags
end
#--------------------------------------------------------------------------
# * Setter pour l'attribut zoom
#--------------------------------------------------------------------------
def zoom=(new_zoom)
unless zoom == new_zoom
@zoom = new_zoom
parameters[14] = (4096.0 / new_zoom).to_i
MGC.mode7_data[2] = new_zoom
vox = @ox
@ox = nil
self.ox = vox
voy = @oy
@oy = nil
self.oy = voy
@need_refresh = true
parameters[29] = MODE7_SCAN_STEP
@need_refresh = true
last_line = ((-parameters[24] - @view_limit) * zoom).to_i
height_limit = (parameters[23] * last_line * parameters[21]) /
((parameters[23] << 11) - last_line * parameters[22]) + parameters[24]
parameters[27] = [height_limit.to_i, 0].max
MGC.mode7_data[8] = parameters[27]
end
end
#--------------------------------------------------------------------------
# * Setter pour l'attribut alpha
#--------------------------------------------------------------------------
def alpha=(new_alpha)
unless new_alpha == alpha
@alpha = new_alpha
refresh_alpha
end
end
#--------------------------------------------------------------------------
# * Setter pour l'attribut shadow_opacity
#--------------------------------------------------------------------------
def shadow_opacity=(value)
@parameters[15] = [[value, 0].max, 255].min
end
#--------------------------------------------------------------------------
# * Setter pour l'attribut visible
#--------------------------------------------------------------------------
def visible=(flag)
@visible = flag
@sprite_render.visible = flag
end
#--------------------------------------------------------------------------
# * Setter pour l'attribut ox
#--------------------------------------------------------------------------
def ox=(new_ox)
new_ox = new_ox.to_i
unless new_ox == @ox
@ox = new_ox
@need_refresh = true
parameters[8] = @ox
parameters[29] = MODE7_SCAN_STEP
end
end
#--------------------------------------------------------------------------
# * Setter pour l'attribut oy
#--------------------------------------------------------------------------
def oy=(new_oy)
new_oy = new_oy.to_i
unless new_oy == @oy
@oy = new_oy
@need_refresh = true
parameters[9] = @oy
parameters[29] = MODE7_SCAN_STEP
end
end
#--------------------------------------------------------------------------
# * Setter pour l'attribut opacity
#--------------------------------------------------------------------------
def opacity=(new_opacity)
@opacity = new_opacity
@sprite_render.opacity = new_opacity
end
#--------------------------------------------------------------------------
# * Setter pour l'attribut blend_type
#--------------------------------------------------------------------------
def blend_type=(new_blend_type)
@blend_type = new_blend_type
@sprite_render.blend_type = new_blend_type
end
#--------------------------------------------------------------------------
# * Setter pour l'attribut color
#--------------------------------------------------------------------------
def color=(new_color)
@color = new_color
@sprite_render.color = new_color
end
#--------------------------------------------------------------------------
# * Setter pour l'attribut tone
#--------------------------------------------------------------------------
def tone=(new_tone)
@tone = new_tone
@sprite_render.tone = new_tone
end
#--------------------------------------------------------------------------
# * Setter pour l'attribut wave_amp
#--------------------------------------------------------------------------
def wave_amp=(new_wave_amp)
@wave_amp = new_wave_amp
@sprite_render.wave_amp = new_wave_amp
end
#--------------------------------------------------------------------------
# * Setter pour l'attribut wave_length
#--------------------------------------------------------------------------
def wave_length=(new_wave_length)
@wave_length = new_wave_length
@sprite_render.wave_length = new_wave_length
end
#--------------------------------------------------------------------------
# * Setter pour l'attribut wave_speed
#--------------------------------------------------------------------------
def wave_speed=(new_wave_speed)
@wave_speed = new_wave_speed
@sprite_render.wave_speed = new_wave_speed
end
#--------------------------------------------------------------------------
# * Setter pour l'attribut wave_phase
#--------------------------------------------------------------------------
def wave_phase=(new_wave_phase)
@wave_phase = new_wave_phase
@sprite_render.wave_phase = new_wave_phase
end
#--------------------------------------------------------------------------
# * Libération de l'instance
#--------------------------------------------------------------------------
def dispose
@render.dispose
@sprite_render.dispose
clear_vertical_tiles # [1.7]
@param_tiles[0].dispose
end
#--------------------------------------------------------------------------
# * Suppression des tiles verticaux [1.7]
#--------------------------------------------------------------------------
def clear_vertical_tiles
if @vertical_tiles
@vertical_tiles.each {|sprite| sprite.dispose}
@vertical_tiles.clear
end
end
#--------------------------------------------------------------------------
# * Retourne true si l'instance a été libérée
#--------------------------------------------------------------------------
def disposed?
return @render.disposed?
end
#--------------------------------------------------------------------------
# * Mise à jour, appelée normalement à chaque frame
#--------------------------------------------------------------------------
def update
if @visible
if MGC.is_changing_map?
refresh_fading
MGC.end_change_map
end
if parameters[18] != MODE7_SCAN_STEP
parameters[18] = MODE7_SCAN_STEP
parameters[19] = 0
parameters[29] = 0
@need_refresh = true
end
self.alpha = MGC.mode7_angle
self.zoom = MGC.mode7_zoom
if Graphics.frame_count & 31 == 0
parameters[10] += 1
parameters[10] %= 3
parameters[29] = MODE7_SCAN_STEP
unless @need_refresh
@need_refresh_anim = true
end
end
if parameters[29] > 0 && !@need_refresh && !@need_refresh_anim
@need_refresh = true
end
begin
if @need_refresh
parameters[19] += 1
if parameters[19] == parameters[18]
parameters[19] = 0
end
parameters[11] = 0
RENDER.call(parameters.__id__)
parameters[29] -= 1
if parameters[29] == 0
@need_refresh = false
end
elsif @need_refresh_anim
parameters[19] += 1
if parameters[19] == parameters[18]
parameters[19] = 0
end
parameters[11] = 1
RENDER.call(parameters.__id__)
parameters[29] -= 1
if parameters[29] == 0
@need_refresh_anim = false
end
end
if @initialization && parameters[29] == 0
@initialization = false
end
end while @initialization
@sprite_render.update
@vertical_tiles.each {|sprite| sprite.update} # [1.7]
end
end
#--------------------------------------------------------------------------
# * Flash des couches de la tilemap
#--------------------------------------------------------------------------
def flash(color, duration)
@sprite_render.flash(color, duration)
end
#--------------------------------------------------------------------------
# * Create vertical tiles [1.7]
#--------------------------------------------------------------------------
def create_vertical_tiles
unless @vertical_tiles
@vertical_tiles = []
end
clear_vertical_tiles
@vt_checked_tiles = Table.new($game_map.width, $game_map.height,
MGC::MODE7_TERRAIN_TAGS.size)
(0...$game_map.height).each {|iy|
(0...$game_map.width).each {|ix|
(0...3).each {|il|
terrain_tag = $game_map.terrain_tag_for_layer(ix, iy, il)
if terrain_tag > 0 && MGC::MODE7_TERRAIN_TAGS.include?(terrain_tag)
tag_index = MGC::MODE7_TERRAIN_TAGS.index(terrain_tag)
unless @vt_checked_tiles[ix, iy, tag_index] == 1
@vt_found_tiles = []
@vt_x_min = ix
@vt_x_max = ix
@vt_y_min = iy
@vt_y_max = iy
find_linked_tiles(ix, iy, terrain_tag, tag_index)
v_tile = MGC::Vertical_Tile.new(self, @viewport)
v_tile.x = 1 + @vt_x_max + @vt_x_min << 5 >> 1
v_tile.y = 1 + @vt_y_max << 5
v_tile.refresh_tile_data(@vt_found_tiles,
@vt_x_min, @vt_x_max, @vt_y_min, @vt_y_max)
@vertical_tiles << v_tile
break
end
end
}
}
}
@vt_checked_tiles = nil
end
#--------------------------------------------------------------------------
# * Find linked tiles [1.7]
# param x : Integer
# param y : Integer
# param terrain_tag : Integer
# param tag_index : Integer
#--------------------------------------------------------------------------
def find_linked_tiles(x, y, terrain_tag, tag_index)
unless @vt_checked_tiles[x, y, tag_index] == 1
@vt_checked_tiles[x, y, tag_index] = 1
found = false
(0...3).each {|il|
if $game_map.terrain_tag_for_layer(x, y, il) == terrain_tag
unless found
found_tile = [x, y, [false, false, false]]
@vt_found_tiles << found_tile
found = true
end
found_tile[2][il] = true
end
}
if found
if x > @vt_x_max
@vt_x_max = x
end
if x < @vt_x_min
@vt_x_min = x
end
if y > @vt_y_max
@vt_y_max = y
end
if y < @vt_y_min
@vt_y_min = y
end
if MGC::MODE7_VERTICAL_TILES_TYPE & 1 == 1
if y < $game_map.height - 1
find_linked_tiles(x, y + 1, terrain_tag, tag_index)
end
end
if MGC::MODE7_VERTICAL_TILES_TYPE & 2 == 2
if x < $game_map.width - 1
find_linked_tiles(x + 1, y, terrain_tag, tag_index)
end
end
if MGC::MODE7_VERTICAL_TILES_TYPE == 3
if x > 0
find_linked_tiles(x - 1, y, terrain_tag, tag_index)
end
if y > 0
find_linked_tiles(x, y - 1, terrain_tag, tag_index)
end
end
end
end
end
end
end
#==============================================================================
# ** Game_System
#==============================================================================
class Game_System
#--------------------------------------------------------------------------
# * Attributs
#--------------------------------------------------------------------------
attr_accessor :mode7_zoom, :mode7_angle, :mode7_active
end
#==============================================================================
# ** Game_Map
#==============================================================================
class Game_Map
attr_accessor :start_mode7, :end_mode7
#--------------------------------------------------------------------------
# * Aliased methods
#--------------------------------------------------------------------------
unless @already_aliased_mgc_m7a
alias setup_mgc_m7a setup
alias set_display_pos_mgc_m7a set_display_pos
alias scroll_down_mgc_m7a scroll_down
alias scroll_left_mgc_m7a scroll_left
alias scroll_right_mgc_m7a scroll_right
alias scroll_up_mgc_m7a scroll_up
@already_aliased_mgc_m7a = true
end
#--------------------------------------------------------------------------
# * Setup
#--------------------------------------------------------------------------
def setup(map_id)
setup_mgc_m7a(map_id)
@map = load_data(sprintf("Data/Map%03d.rvdata2", map_id)) # [1.9]
if is_mode7?
if MGC.mode7_active
MGC.start_change_map
end
self.start_mode7 = true
else
self.end_mode7 = true
end
end
#--------------------------------------------------------------------------
# * Check if the map is configured for mode 7
#--------------------------------------------------------------------------
def is_mode7?
return MGC::MODE7_MAPS_ID.include?(@map_id) ||
$data_mapinfos[@map_id].full_name[/\[M7\]/]
end
#--------------------------------------------------------------------------
# * Get default mode7 angle
#--------------------------------------------------------------------------
def get_default_mode7_angle
if $data_mapinfos[@map_id].full_name[/\[A(\d+)\]/]
return [[$1.to_i, 0].max, 89].min
else
return MGC::MODE7_DEFAULT_ANGLE
end
end
#--------------------------------------------------------------------------
# * Get default mode7 zoom
#--------------------------------------------------------------------------
def get_default_mode7_zoom
if $data_mapinfos[@map_id].full_name[/\[Z(\d+(?:\.\d+)*)\]/]
return [[$1.to_f, 0.125].max, 8.0].min
else
return MGC::MODE7_DEFAULT_ZOOM
end
end
#--------------------------------------------------------------------------
# * Get default fading distance
#--------------------------------------------------------------------------
def get_default_fading_distance
if $data_mapinfos[@map_id].full_name[/\[FD(\d{1,3})\]/]
return [$1.to_i, 0].max
else
return MGC::MODE7_FADING_DISTANCE
end
end
#--------------------------------------------------------------------------
# * Get default fading opacity
#--------------------------------------------------------------------------
def get_default_fading_opacity
if $data_mapinfos[@map_id].full_name[/\[FO(\d{1,3})\]/]
return [[$1.to_i, 0].max, 255].min
else
return MGC::MODE7_FADING_OPACITY
end
end
#--------------------------------------------------------------------------
# * Get default fading tone
#--------------------------------------------------------------------------
def get_default_fading_tone
if $data_mapinfos[@map_id].full_name[/\[FT(\-?\d{1,3}),(\-?\d{1,3}),(\-?\d{1,3})\]/]
red = [[$1.to_i, -255].max, 255].min
green = [[$2.to_i, -255].max, 255].min
blue = [[$3.to_i, -255].max, 255].min
return Tone.new(red, green, blue)
else
return MGC::MODE7_FADING_TONE
end
end
#--------------------------------------------------------------------------
# * Check if the map is parallaxed [1.9]
#--------------------------------------------------------------------------
def is_parallaxed?
return MGC::MODE7_PARALLAXED_MAPS_ID.include?(@map_id) ||
$data_mapinfos[@map_id].full_name[/\[P\]/]
end
#--------------------------------------------------------------------------
# * Check if the parallaxed map has a panorama in mode 7 [1.9]
#--------------------------------------------------------------------------
def has_additionnal_panorama?
return @map.note[/\[m7a_pano:\w+\]/]
end
#--------------------------------------------------------------------------
# * Return the panorama in mode 7 if the map is parallaxed [1.9]
#--------------------------------------------------------------------------
def set_additional_panorama
if @map.note[/\[m7a_pano:(\w+)\]/]
@parallax_name = $1
end
end
#--------------------------------------------------------------------------
# * Set Display Position
#--------------------------------------------------------------------------
def set_display_pos(x, y)
if MGC.mode7_active
if loop_horizontal?
@display_x = (x + width) % width
else
if MGC.mode7_zoom < 1.0 && width * MGC.mode7_zoom < screen_tile_x
@display_x = (width - screen_tile_x) / 2
else
x_min = screen_tile_x * (1.0 / MGC.mode7_zoom - 1.0) / 2
x_max = width + screen_tile_x * ((1.0 - 1.0 / MGC.mode7_zoom) / 2 - 1)
x = [x_min, [x, x_max].min].max
@display_x = x
end
end
if loop_vertical?
@display_y = (y + height) % height
else
if MGC.mode7_zoom < 1.0 && height * MGC.mode7_zoom < screen_tile_y
@display_y = (height - screen_tile_y) * MGC.mode7_data[1]
else
y_min = screen_tile_y * (1.0 / MGC.mode7_zoom - 1.0) * MGC.mode7_data[1]
y_max = height + screen_tile_y *
((1.0 - 1.0 / MGC.mode7_zoom) * (1 - MGC.mode7_data[1]) - 1)
y = [y_min, [y, y_max].min].max
@display_y = y
end
end
@parallax_x = x
@parallax_y = y
else
set_display_pos_mgc_m7a(x, y)
end
end
#--------------------------------------------------------------------------
# * Scroll Down
#--------------------------------------------------------------------------
def scroll_down(distance)
if MGC.mode7_active
if loop_vertical?
@display_y += distance
@display_y %= @map.height
@parallax_y += distance if @parallax_loop_y
else
last_y = @display_y
if MGC.mode7_zoom < 1.0 && height * MGC.mode7_zoom < screen_tile_y
@display_y = (height - screen_tile_y) * MGC.mode7_data[1]
else
max = height + screen_tile_y *
((1.0 - 1.0 / MGC.mode7_zoom) * (1 - MGC.mode7_data[1]) - 1)
@display_y = [@display_y + distance, max].min
end
@parallax_y += @display_y - last_y
end
else
scroll_down_mgc_m7a(distance)
end
end
#--------------------------------------------------------------------------
# * Scroll Left
#--------------------------------------------------------------------------
def scroll_left(distance)
if MGC.mode7_active
if loop_horizontal?
@display_x += @map.width - distance
@display_x %= @map.width
@parallax_x -= distance if @parallax_loop_x
else
last_x = @display_x
if MGC.mode7_zoom < 1.0 && width * MGC.mode7_zoom < screen_tile_x
@display_x = (width - screen_tile_x) / 2
else
min = screen_tile_x * (1.0 / MGC.mode7_zoom - 1.0) / 2
@display_x = [@display_x - distance, min].max
end
@parallax_x += @display_x - last_x
end
else
scroll_left_mgc_m7a(distance)
end
end
#--------------------------------------------------------------------------
# * Scroll Right
#--------------------------------------------------------------------------
def scroll_right(distance)
if MGC.mode7_active
if loop_horizontal?
@display_x += distance
@display_x %= @map.width
@parallax_x += distance if @parallax_loop_x
else
last_x = @display_x
if MGC.mode7_zoom < 1.0 && width * MGC.mode7_zoom < screen_tile_x
@display_x = (width - screen_tile_x) / 2
else
max = width + screen_tile_x * ((1.0 - 1.0 / MGC.mode7_zoom) / 2 - 1)
@display_x = [@display_x + distance, max].min
end
@parallax_x += @display_x - last_x
end
else
scroll_right_mgc_m7a(distance)
end
end
#--------------------------------------------------------------------------
# * Scroll Up
#--------------------------------------------------------------------------
def scroll_up(distance)
if MGC.mode7_active
if loop_vertical?
@display_y += @map.height - distance
@display_y %= @map.height
@parallax_y -= distance if @parallax_loop_y
else
last_y = @display_y
if MGC.mode7_zoom < 1.0 && height * MGC.mode7_zoom < screen_tile_y
@display_y = (height - screen_tile_y) * MGC.mode7_data[1]
else
min = screen_tile_y * (1.0 / MGC.mode7_zoom - 1.0) * MGC.mode7_data[1]
@display_y = [@display_y - distance, min].max
end
@parallax_y += @display_y - last_y
end
else
scroll_up_mgc_m7a(distance)
end
end
#--------------------------------------------------------------------------
# * Get Terrain Tag for a layer [1.7]
#--------------------------------------------------------------------------
def terrain_tag_for_layer(x, y, layer)
return 0 unless valid?(x, y)
return tileset.flags[tile_id(x, y, layer)] >> 12
end
end
#==============================================================================
# ** Game_CharacterBase
#==============================================================================
class Game_CharacterBase
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :sprite
end
#==============================================================================
# ** Serialisation
#==============================================================================
[:Sprite, :Viewport, :Bitmap, :Font].each {|classname|
eval(
"class #{classname}
def marshal_dump
return []
end
def marshal_load(array)
end
end")
}
#==============================================================================
# ** Sprite
#==============================================================================
class Sprite
#--------------------------------------------------------------------------
# * Aliased methods
#--------------------------------------------------------------------------
unless @already_aliased_mgc_m7a
alias initialize_mgc_m7a initialize
alias zoom_x_mgc_m7a= zoom_x=
alias zoom_y_mgc_m7a= zoom_y=
alias zoom_x_mgc_m7a zoom_x
alias zoom_y_mgc_m7a zoom_y
@already_aliased_mgc_m7a = true
end
#--------------------------------------------------------------------------
# * Initialisation
#--------------------------------------------------------------------------
def initialize(*args)
initialize_mgc_m7a(*args)
@phase_mode7 = false
self.zoom_x = 1.0
self.zoom_y = 1.0
end
#--------------------------------------------------------------------------
# * Setter pour l'attribut zoom_x
#--------------------------------------------------------------------------
def zoom_x=(new_zoom_x)
unless @phase_mode7
@base_zoom_x = new_zoom_x
end
self.zoom_x_mgc_m7a = new_zoom_x
end
#--------------------------------------------------------------------------
# * Setter pour l'attribut zoom_y
#--------------------------------------------------------------------------
def zoom_y=(new_zoom_y)
unless @phase_mode7
@base_zoom_y = new_zoom_y
end
self.zoom_y_mgc_m7a = new_zoom_y
end
#--------------------------------------------------------------------------
# * Getter pour l'attribut zoom_x
#--------------------------------------------------------------------------
def zoom_x
return @base_zoom_x
end
#--------------------------------------------------------------------------
# * Getter pour l'attribut zoom_y
#--------------------------------------------------------------------------
def zoom_y
return @base_zoom_y
end
#--------------------------------------------------------------------------
# * Valeur réelle du zoom_x en prenant en compte le zoom de la carte
#--------------------------------------------------------------------------
def zoom_x_real
return zoom_x_mgc_m7a
end
#--------------------------------------------------------------------------
# * Valeur réelle du zoom_y en prenant en compte le zoom de la carte
#--------------------------------------------------------------------------
def zoom_y_real
return zoom_y_mgc_m7a
end
end
#==============================================================================
# ** Sprite_Base
#==============================================================================
class Sprite_Base
#--------------------------------------------------------------------------
# * Aliased methods
#--------------------------------------------------------------------------
unless @already_aliased_mgc_m7a
alias animation_set_sprites_mgc_m7a_aprite_base animation_set_sprites
@already_aliased_mgc_m7a = true
end
#--------------------------------------------------------------------------
# * Set Animation Sprite
# frame : Frame data (RPG::Animation::Frame)
#--------------------------------------------------------------------------
def animation_set_sprites(frame)
if MGC.mode7_active
cell_data = frame.cell_data
@ani_sprites.each_with_index do |sprite, i|
next unless sprite
pattern = cell_data[i, 0]
if !pattern || pattern < 0
sprite.visible = false
next
end
sprite.bitmap = pattern < 100 ? @ani_bitmap1 : @ani_bitmap2
sprite.visible = true
sprite.src_rect.set(pattern % 5 * 192,
pattern % 100 / 5 * 192, 192, 192)
if @ani_mirror
sprite.x = @ani_ox - cell_data[i, 1] * zoom_y_real
sprite.y = @ani_oy + cell_data[i, 2] * zoom_y_real
sprite.angle = (360 - cell_data[i, 4])
sprite.mirror = (cell_data[i, 5] == 0)
else
sprite.x = @ani_ox + cell_data[i, 1] * zoom_y_real
sprite.y = @ani_oy + cell_data[i, 2] * zoom_y_real
sprite.angle = cell_data[i, 4]
sprite.mirror = (cell_data[i, 5] == 1)
end
sprite.z = self.z + 300 + i
sprite.ox = 96
sprite.oy = 96
sprite.zoom_x = cell_data[i, 3] * zoom_y_real / 100.0
sprite.zoom_y = cell_data[i, 3] * zoom_y_real / 100.0
sprite.opacity = cell_data[i, 6] * self.opacity / 255.0
sprite.blend_type = cell_data[i, 7]
end
else
animation_set_sprites_mgc_m7a_aprite_base(frame)
end
end
end
#==============================================================================
# ** Sprite_Character
#==============================================================================
class Sprite_Character < Sprite_Base
#--------------------------------------------------------------------------
# * Aliased methods
#--------------------------------------------------------------------------
unless @already_aliased_mgc_m7a
alias initialize_mgc_m7a_aprite_character initialize
alias update_position_mgc_m7a_aprite_character update_position
alias update_other_mgc_m7a_aprite_character update_other
alias update_balloon_mgc_m7a_aprite_character update_balloon
@already_aliased_mgc_m7a = true
end
#--------------------------------------------------------------------------
# * Object Initialization
# character : Game_Character
#--------------------------------------------------------------------------
def initialize(viewport, character = nil)
initialize_mgc_m7a_aprite_character(viewport, character)
character.sprite = self
end
#--------------------------------------------------------------------------
# * Update Position
#--------------------------------------------------------------------------
def update_position
if MGC.mode7_active
old_x = x
old_y = y
update_mode7
@in_mode_7 = true # [1.5]
move_animation(x - old_x, y - old_y)
else
if @in_mode_7 # [1.5]
self.zoom_x = zoom_x
self.zoom_y = zoom_y
@in_mode_7 = false
end
update_position_mgc_m7a_aprite_character
end
end
#--------------------------------------------------------------------------
# * Update Other
#--------------------------------------------------------------------------
def update_other
update_other_mgc_m7a_aprite_character
if MGC.mode7_active && visible
if !@force_mode7_invisible &&
y >= MGC.mode7_data[8] &&
(y - height * zoom_y_real) < Graphics.height
then
self.visible = true
if y < Graphics.height
dat = MGC.mode7_data[9]
self.opacity += dat[5, y]
self.tone.set(dat[2, y], dat[3, y], dat[4, y])
end
else
self.visible = false
end
end
end
#--------------------------------------------------------------------------
# * Update Position In Mode7
#--------------------------------------------------------------------------
def update_mode7
if @character.tile_id == 0 && character.character_name == "" # [1.8]
@force_mode7_invisible = true
return
end
y_screen = character.screen_y +
(character.is_a?(Game_Vehicle) ? character.altitude : 0)
y_init = MGC.mode7_data[2] * (y_screen - MGC.mode7_data[0])
if y_init < - (MGC::MODE7_VIEW_LIMIT << 5) - MGC.mode7_data[0] ||
y_init > Graphics.height
then
@force_mode7_invisible = true
return
else
@force_mode7_invisible = false
end
x_init = MGC.mode7_data[2] * (character.screen_x - (Graphics.width >> 1))
self.y = (MGC.mode7_data[0] + (MGC.mode7_data[5] * y_init *
MGC.mode7_data[3]) / (MGC.mode7_data[5] - y_init * MGC.mode7_data[4])).to_i
zx = MGC.mode7_data[6] * y + MGC.mode7_data[7]
self.x = ((Graphics.width >> 1) + zx * x_init).to_i
@phase_mode7 = true
self.zoom_x = MGC.mode7_data[2] * zx
self.zoom_y = zoom_x_real
@phase_mode7 = false
self.z = @character.screen_z + (y << 8) # [1.7]
if character.is_a?(Game_Vehicle)
self.y -= character.altitude * zoom_y_real
end
end
#--------------------------------------------------------------------------
# * Update Balloon Icon
#--------------------------------------------------------------------------
def update_balloon
update_balloon_mgc_m7a_aprite_character
if MGC.mode7_active && @balloon_duration > 0
@balloon_sprite.y = y - height * zoom_y_real
@balloon_sprite.zoom_x = zoom_x_real
@balloon_sprite.zoom_y = zoom_y_real
end
end
end
#==============================================================================
# ** Spriteset_Map
#==============================================================================
class Spriteset_Map
#--------------------------------------------------------------------------
# * Aliased methods
#--------------------------------------------------------------------------
unless @already_aliased_mgc_m7a
alias initialize_mgc_m7a initialize
alias create_tilemap_mgc_m7a create_tilemap
alias update_mgc_m7a update
alias update_shadow_mgc_m7a update_shadow
alias update_parallax_mgc_m7a update_parallax
@already_aliased_mgc_m7a = true
end
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
MGC.spriteset = self
initialize_mgc_m7a
end
#--------------------------------------------------------------------------
# * Lance le mode 7
#--------------------------------------------------------------------------
def start_mode7
unless @tilemap_mode7 && @tilemap_mode7.map_id == $game_map.map_id # [1.9]
if @tilemap_mode7
@tilemap_mode7.dispose unless @tilemap_mode7.disposed?
MGC.initialize_mode7(true)
else
MGC.initialize_mode7
@tilemap_classic = @tilemap
end
@tilemap_mode7 = MGC::Mode7_Map.new(@viewport1)
@tilemap_mode7.map_data = $game_map.data
if $game_map.is_parallaxed? && $game_map.parallax_name &&
$game_map.parallax_name != '' # [1.9]
then
@tilemap_mode7.parallax = Cache.parallax($game_map.parallax_name)
$game_map.set_additional_panorama
end
@tilemap = @tilemap_mode7
load_tileset
end
@tilemap_mode7.create_vertical_tiles # [1.7]
@tilemap_mode7.visible = true
@tilemap_classic.visible = false
@tilemap = @tilemap_mode7
MGC.mode7_active = true
end
#--------------------------------------------------------------------------
# * Met fin au mode 7
#--------------------------------------------------------------------------
def end_mode7
if @tilemap_mode7
@tilemap_mode7.visible = false
@tilemap_classic.visible = true
@tilemap = @tilemap_classic
@tilemap_mode7.clear_vertical_tiles # [1.7]
@parallax.visible = true # [1.9]
end
MGC.mode7_active = false
end
#--------------------------------------------------------------------------
# * Create Tilemap
#--------------------------------------------------------------------------
def create_tilemap
create_tilemap_mgc_m7a
unless $game_system.mode7_active
MGC.mode7_active = false
end
if $game_map.is_mode7? || $game_system.mode7_active
start_mode7
end
end
#--------------------------------------------------------------------------
# * Update
#--------------------------------------------------------------------------
def update
MGC.update_mode7
if $game_map.start_mode7
start_mode7
$game_map.start_mode7 = false
elsif $game_map.end_mode7
end_mode7
$game_map.end_mode7 = false
end
update_mgc_m7a
end
#--------------------------------------------------------------------------
# * Update Parallax [1.9]
#--------------------------------------------------------------------------
def update_parallax
update_parallax_mgc_m7a
if MGC.mode7_active && $game_map.is_parallaxed?
if $game_map.has_additionnal_panorama?
$game_map.set_additional_panorama
else
@parallax.visible = false
end
end
end
#--------------------------------------------------------------------------
# * Update Airship Shadow Sprite
#--------------------------------------------------------------------------
def update_shadow
if MGC.mode7_active
airship_sprite = $game_map.airship.sprite
@shadow_sprite.x = airship_sprite.x
@shadow_sprite.y = airship_sprite.y + $game_map.airship.altitude *
airship_sprite.zoom_y_real
@shadow_sprite.opacity = $game_map.airship.altitude * 8 *
airship_sprite.opacity
@shadow_sprite.zoom_x = airship_sprite.zoom_x_real
@shadow_sprite.zoom_y = airship_sprite.zoom_y_real
@shadow_sprite.update
else
update_shadow_mgc_m7a
end
end
end
#==============================================================================
# ** Scene_Map
#==============================================================================
class Scene_Map < Scene_Base
#--------------------------------------------------------------------------
# * Aliased methods
#--------------------------------------------------------------------------
unless @already_aliased_mgc_m7a
alias update_call_menu_mgc_m7a update_call_menu
@already_aliased_mgc_m7a = true
end
#--------------------------------------------------------------------------
# * Determine if Menu is Called due to Cancel Button
#--------------------------------------------------------------------------
def update_call_menu
unless MGC.effect?
update_call_menu_mgc_m7a
end
end
end
#============================================================================
# ** RPG::MapInfo
#============================================================================
class RPG::MapInfo
# defines the map name as the name without anything within brackets,
# including brackets
def name
return @name.gsub(/\[.*\]/) {''}
end
#--------------------------------------------------------------------------
# the original name with the codes
def full_name
return @name
end
end
module MGC
#--------------------------------------------------------------------------
# * Constantes [1.7]
#--------------------------------------------------------------------------
RENDER_TILE = Win32API.new("MGC_Mode7_Ace_1_9", "renderTile", "l", "l")
#==============================================================================
# ** MGC::Vertical_Tile [1.7]
#==============================================================================
class Vertical_Tile
#--------------------------------------------------------------------------
# * Attributs
#--------------------------------------------------------------------------
attr_accessor :x, :y, :screen_x, :screen_y, :zoom
attr_accessor :tile_width, :tile_height, :width, :height
#--------------------------------------------------------------------------
# * Initialisation
# param parent : MGC::Mode7_Map
# param viewport : Viewport
#--------------------------------------------------------------------------
def initialize(parent, viewport)
@parent = parent
@viewport = viewport
@visible = false
@sprite = nil
end
#--------------------------------------------------------------------------
# * Refresh tile data
# param tiles : Array<Array[Integer, Integer, Array[3]<Boolean>]>
# param x_min : Integer
# param x_max : Integer
# param y_min : Integer
# param y_max : Integer
#--------------------------------------------------------------------------
def refresh_tile_data(tiles, x_min, x_max, y_min, y_max)
self.tile_width = 1 + x_max - x_min
self.width = tile_width << 5
self.tile_height = 1 + y_max - y_min
self.height = tile_height << 5
@tiles_data = Array.new(tile_width * tile_height)
tiles.each {|tile|
x_tile = tile[0] - x_min
y_tile = tile[1] - y_min
@tiles_data[x_tile + y_tile * tile_width] = tile
}
end
#--------------------------------------------------------------------------
# * Dispose
#--------------------------------------------------------------------------
def dispose
if @sprite
@sprite.bitmap.dispose
@sprite.dispose
@sprite = nil
end
end
#--------------------------------------------------------------------------
# * Update
#--------------------------------------------------------------------------
def update
update_mode7
update_visibility
end
#--------------------------------------------------------------------------
# * Update Position In Mode7
#--------------------------------------------------------------------------
def update_mode7
x_scr = 32 * $game_map.adjust_x(x.to_f / 32)
y_scr = 32 * $game_map.adjust_y(y.to_f / 32)
y_init = MGC.mode7_data[2] * (y_scr - MGC.mode7_data[0])
if y_init < - (MGC::MODE7_VIEW_LIMIT << 5) - MGC.mode7_data[0] ||
y_init > Graphics.height
then
@force_invisible = true
return
else
@force_invisible = false
end
x_init = MGC.mode7_data[2] * (x_scr - (Graphics.width >> 1))
self.screen_y = (MGC.mode7_data[0] + (MGC.mode7_data[5] * y_init *
MGC.mode7_data[3]) / (MGC.mode7_data[5] - y_init * MGC.mode7_data[4])).to_i
zx = MGC.mode7_data[6] * screen_y + MGC.mode7_data[7]
self.screen_x = ((Graphics.width >> 1) + zx * x_init).to_i
self.zoom = MGC.mode7_data[2] * zx
end
#--------------------------------------------------------------------------
# * Update Visibility
#--------------------------------------------------------------------------
def update_visibility
if @visible
if !@force_invisible &&
screen_y >= MGC.mode7_data[8] &&
(screen_y - height * zoom) < Graphics.height &&
(screen_x + width * zoom / 2) >= 0 &&
(screen_x - width * zoom / 2) < Graphics.width
then
if screen_y < Graphics.height
dat = MGC.mode7_data[9]
@sprite.opacity = 255 + dat[5, screen_y]
@sprite.tone.set(dat[2, screen_y], dat[3, screen_y], dat[4, screen_y])
end
@sprite.x = screen_x
@sprite.y = screen_y
@sprite.z = screen_y << 8
@sprite.zoom_x = zoom
@sprite.zoom_y = zoom
else
@visible = false
@sprite.bitmap.dispose
@sprite.dispose
@sprite = nil
end
else
if !@force_invisible &&
screen_y >= MGC.mode7_data[8] &&
(screen_y - height * zoom) < Graphics.height &&
(screen_x + width * zoom / 2) >= 0 &&
(screen_x - width * zoom / 2) < Graphics.width
then
@visible = true
@sprite = Sprite.new(@viewport)
@sprite.ox = tile_width * 32 / 2
@sprite.oy = tile_height * 32
@sprite.x = screen_x
@sprite.y = screen_y
@sprite.z = screen_y << 8
@sprite.zoom_x = zoom
@sprite.zoom_y = zoom
@sprite.bitmap = Bitmap.new(32 * tile_width, 32 * tile_height)
(0...tile_height).each {|iy|
(0...tile_width).each {|ix|
tile_data = @tiles_data[ix + iy * tile_width]
if tile_data
(0...3).each {|il|
if tile_data[2][il]
@parent.param_tiles[6][il] =
$game_map.tile_id(tile_data[0], tile_data[1], il)
else
@parent.param_tiles[6][il] = 0
end
}
@parent.param_tiles[0].clear
MGC::RENDER_TILE.call(@parent.param_tiles.__id__)
@sprite.bitmap.blt(ix << 5, iy << 5, @parent.param_tiles[0],
@parent.param_tiles[0].rect)
end
}
}
if screen_y < Graphics.height
dat = MGC.mode7_data[9]
@sprite.opacity = 255 + dat[5, screen_y]
@sprite.tone.set(dat[2, screen_y], dat[3, screen_y], dat[4, screen_y])
end
end
end
end
end
end[/pre] |
|