#==============================================================================
# ■ Game_System
#------------------------------------------------------------------------------
# システム周りのデータを扱うクラスです。乗り物や BGM などの管理も行います。
# このクラスのインスタンスは $game_system で参照されます。
#==============================================================================
class Game_System
#--------------------------------------------------------------------------
# ● 公開インスタンス変数
#--------------------------------------------------------------------------
attr_accessor :layer # レイヤー
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
alias game_system_initialize initialize
def initialize
game_system_initialize
@layer = -1
end
end
#==============================================================================
# ■ Game_Temp
#------------------------------------------------------------------------------
# セーブデータに含まれない、一時的なデータを扱うクラスです。このクラスのイン
# スタンスは $game_temp で参照されます。
#==============================================================================
class Game_Temp
#--------------------------------------------------------------------------
# ● 公開インスタンス変数
#--------------------------------------------------------------------------
attr_accessor :map_name #再読み込み回避
attr_accessor :link_array #再読み込み回避
attr_accessor :check #再読み込み回避
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
alias game_temp_initialize initialize
def initialize
game_temp_initialize
@map_name = [] #再読み込み回避
@link_array = [] #再読み込み回避
@check = false #再読み込み回避
end
end
#==============================================================================
# ■ Game_Map
#------------------------------------------------------------------------------
# マップを扱うクラスです。スクロールや通行可能判定などの機能を持っています。
# このクラスのインスタンスは $game_map で参照されます。
#==============================================================================
class Game_Map
#--------------------------------------------------------------------------
# ● 定数
#--------------------------------------------------------------------------
MAX_EVENT = 1000 # 1レイヤ当たりのイベント数
MAX_LAYER = 5 # レイヤの最大数
LAYER_UP = 1022 # レイヤを上げるチップID
LAYER_DW = 1023 # レイヤを下げるチップID
#--------------------------------------------------------------------------
# ● 公開インスタンス変数
#--------------------------------------------------------------------------
attr_accessor :name
attr_accessor :para_layer
attr_accessor :spe_layer
attr_reader :spe_picture_name
attr_reader :spe_picture_layer
#--------------------------------------------------------------------------
# ● セットアップ
# map_id : マップ ID
# enable : 所属レイヤーの変更
#--------------------------------------------------------------------------
def setup(map_id,enable=false)
#########################################################################
#レイヤー
range = 0..MAX_LAYER-1
if $game_temp.check == false
id_array = []
$data_mapinfos.each do | i,data |
$game_temp.map_name[i] = data.name
id_array.push(i)
end
id_array.each do | id |
buf = []
name = $game_temp.map_name[id].gsub(/\<(\w+)\>/,"")
name = name.gsub(/\[(\w+)\]/,"")
id_array.each do | id2 |
temp_name = $game_temp.map_name[id2]
if temp_name.match(name) && temp_name.match(/\<lay(\d+)\>/)
buf[$1.to_i] = id2
end
end
buf[0] = id if buf[0] == nil
$game_temp.link_array[id] = buf
end
$game_temp.check = true
end
@map_id = map_id
@name = $data_mapinfos[@map_id].name
@map_lay = [] #各レイヤーのマップデータ
@layer_no = 0
$game_player.active_layer=0
@pl_layer = 0
@name.gsub(/\<lay(\d+)\>/i) { @pl_layer = enable || $game_system.layer == -1 ? $1.to_i : $game_system.layer }
$game_player.active_layer = @pl_layer #プレイヤーのレイヤーを決定
$game_player.link_layer_followers #フォロワーのレイヤーをリンク
@layer_num = $game_temp.link_array[@map_id].size
@map_id = $game_temp.link_array[@map_id][0]
#リンクするマップをレイヤーとして読み込む
@spe_picture_name = ""
@para_layer = 0
$game_temp.link_array[@map_id].each do | id |
@map_lay.push(load_data(sprintf("Data/Map%03d.rvdata2",id)))
link_name = $game_temp.map_name[id]
link_id = $game_temp.link_array[@map_id].index(id)
link_name.gsub(/<para>/) { @para_layer = link_id }
link_name.gsub(/\[(\w+)\]/){ set_spe_picture(link_id,$1) }
end
set_layer_no(0)
@map_lay.each { |map| map.display_name = @map_lay[0].display_name }
@display_x = [0,0,0,0,0]
@display_y = [0,0,0,0,0]
@speed_x = [0,0,0,0,0]
@speed_y = [0,0,0,0,0]
#########################################################################
@tileset_id = @map.tileset_id
# @display_x = 0
# @display_y = 0
referesh_vehicles
setup_events
setup_scroll
setup_parallax
setup_battleback
@need_refresh = false
end
#--------------------------------------------------------------------------
# ● フレーム更新
# main : インタプリタ更新フラグ
#--------------------------------------------------------------------------
def update(main = false)
refresh if @need_refresh
update_interpreter if main
update_scroll
update_move_layer
update_events
update_vehicles
update_parallax
@screen.update
end
#--------------------------------------------------------------------------
# ● イベントのセットアップ
#--------------------------------------------------------------------------
def setup_events
@events = {}
@map_lay.each_with_index do | map,index |
map.events.each do |i, event|
event.id += MAX_EVENT*index
@events[i+MAX_EVENT*index] = Game_Event.new(@map_id, event)
# @events[i+MAX_EVENT*index].active_layer = index
end
end
@common_events = parallel_common_events.collect do |common_event|
Game_CommonEvent.new(common_event.id)
end
refresh_tile_events
end
#--------------------------------------------------------------------------
# ● 乗っているタイルIDを取得する
#--------------------------------------------------------------------------
def get_chip_id(x=$game_player.x,y=$game_player.y,layer=0)
[2, 1, 0].each do |i|
tile_id = @map_lay[layer].data[x, y, i]
return tile_id if tile_id != 0 # タイル ID 取得できたら終了
end
return nil
end
#--------------------------------------------------------------------------
# ● 取得するレイヤーNoの設定
#--------------------------------------------------------------------------
def set_layer_no(no)
@layer_no = no
@layer_no %= @layer_num
@layer_no = 0 if @layer_no < 0
@map = @map_lay[@layer_no]
end
#--------------------------------------------------------------------------
# ● レイヤー数の取得
#--------------------------------------------------------------------------
def get_layer_num
return @layer_num
end
#--------------------------------------------------------------------------
# ● リージョン ID の取得
#--------------------------------------------------------------------------
def region_id(x, y)
valid?(x, y) ? @map_lay[$game_player.active_layer].data[x, y, 3] >> 8 : 0
end
#--------------------------------------------------------------------------
# ● エンカウントリストの取得
#--------------------------------------------------------------------------
def encounter_list
@map_lay[$game_player.active_layer].encounter_list
end
#--------------------------------------------------------------------------
# ● エンカウント歩数の取得
#--------------------------------------------------------------------------
def encounter_step
@map_lay[$game_player.active_layer].encounter_step
end
#--------------------------------------------------------------------------
# ● マップデータの取得
#--------------------------------------------------------------------------
def data
return @map_lay[@layer_no].data
end
#--------------------------------------------------------------------------
# ● 通行可能判定
# x : X 座標
# y : Y 座標
# flag : 調べる通行禁止ビット (通常 0x01、乗り物の場合のみ変更)
#--------------------------------------------------------------------------
def passable?(x, y, d, active_layer=0)
check_passage(x, y, (1 << (d / 2 - 1)) & 0x0f, active_layer)
end
#--------------------------------------------------------------------------
# ● 小型船の通行可能判定
#--------------------------------------------------------------------------
def boat_passable?(x, y, active_layer=0)
check_passage(x, y, 0x0200, active_layer)
end
#--------------------------------------------------------------------------
# ● 大型船の通行可能判定
#--------------------------------------------------------------------------
def ship_passable?(x, y, active_layer=0)
check_passage(x, y, 0x0400, active_layer)
end
#--------------------------------------------------------------------------
# ● 通行チェック
# bit : 調べる通行禁止ビット
#--------------------------------------------------------------------------
def check_passage(x, y, bit, active_layer)
#上レイヤーの接続チップは"上"のみチェック
up = false
set_layer_no(active_layer+1)
up = true if LAYER_UP == tile_id(x,y,2)
#下レイヤーの接続チップは"下"のみチェック
dw = false
unless up
set_layer_no(active_layer-1)
dw = true if LAYER_DW == tile_id(x,y,2)
end
set_layer_no(active_layer) if up == false && dw == false
if bit == 0x0200 || bit == 0x0400
if LAYER_DW == tile_id(x,y,2) || LAYER_UP == tile_id(x,y,2)
return true
end
end
all_tiles(x, y).each do |tile_id|
flag = tileset.flags[tile_id]
next if flag & 0x10 != 0 # [☆] : 通行に影響しない
if flag & bit == 0 # [○] : 通行可
set_layer_no(active_layer)
return true
end
if flag & bit == bit # [×] : 通行不可
set_layer_no(active_layer)
return false
end
end
set_layer_no(active_layer)
return false # 通行不可
end
#--------------------------------------------------------------------------
# ● 横方向にループするか?
#--------------------------------------------------------------------------
def loop_horizontal?
return (@map_lay[0].scroll_type == 2 or @map_lay[0].scroll_type == 3)
end
#--------------------------------------------------------------------------
# ● 縦方向にループするか?
#--------------------------------------------------------------------------
def loop_vertical?
return (@map_lay[0].scroll_type == 1 or @map_lay[0].scroll_type == 3)
end
#--------------------------------------------------------------------------
# ● ダッシュ禁止か否かの取得
#--------------------------------------------------------------------------
def disable_dash?
return @map_lay[0].disable_dashing
end
#--------------------------------------------------------------------------
# ● 遠景のセットアップ
#--------------------------------------------------------------------------
alias setup_parallax_game_map setup_parallax
def setup_parallax
old_map = @map
@map = @map_lay[@para_layer]
setup_parallax_game_map
@map = old_map
end
#--------------------------------------------------------------------------
# ● BGM / BGS 自動切り替え
#--------------------------------------------------------------------------
alias autoplay_game_map autoplay
def autoplay
old_map = @map
@map = @map_lay[0]
autoplay_game_map
@map = old_map
end
#--------------------------------------------------------------------------
# ● 茂み判定
# x : X 座標
# y : Y 座標
#--------------------------------------------------------------------------
def bush?(x, y, layer=0)
@map = @map_lay[layer]
valid?(x, y) && layered_tiles_flag?(x, y, 0x40)
end
#--------------------------------------------------------------------------
# ● カウンター判定
# x : X 座標
# y : Y 座標
#--------------------------------------------------------------------------
def counter?(x, y, layer=0)
@map = @map_lay[layer]
valid?(x, y) && layered_tiles_flag?(x, y, 0x80)
end
#--------------------------------------------------------------------------
# ● レイヤースクロール
#--------------------------------------------------------------------------
def set_move_layer(lay,speed_x,speed_y)
@speed_x[lay] = speed_x
@speed_y[lay] = speed_y
end
#--------------------------------------------------------------------------
# ● レイヤースクロール
#--------------------------------------------------------------------------
def update_move_layer
return if scrolling?
@speed_x.each_with_index do | x,i |
if x > 0
scroll_left(2 ** x.abs / 256.0,i)
elsif x < 0
scroll_right(2 ** x.abs / 256.0,i)
end
end
@speed_y.each_with_index do | y,i |
if y > 0
scroll_up(2 ** y.abs / 256.0,i)
elsif y < 0
scroll_down(2 ** y.abs / 256.0,i)
end
end
end
#--------------------------------------------------------------------------
# ● 表示位置の設定
# x : 新しい表示 X 座標 (*256)
# y : 新しい表示 Y 座標 (*256)
#--------------------------------------------------------------------------
def set_display_pos(x, y)
x = [0, [x, width - screen_tile_x].min].max unless loop_horizontal?
y = [0, [y, height - screen_tile_y].min].max unless loop_vertical?
range = 0..4
range.each do | i |
@display_x[i] = (x + width) % width
@display_y[i] = (y + height) % height
end
@parallax_x = x
@parallax_y = y
end
#--------------------------------------------------------------------------
# ● 表示座標を差し引いた X 座標の計算
# x : X 座標
#--------------------------------------------------------------------------
def adjust_x(x,lay=0)
if loop_horizontal? && x < @display_x[lay] - (width - screen_tile_x) / 2
x - @display_x[lay] + @map.width
else
x - @display_x[lay]
end
end
#--------------------------------------------------------------------------
# ● 表示座標を差し引いた Y 座標の計算
# y : Y 座標
#--------------------------------------------------------------------------
def adjust_y(y,lay=0)
if loop_vertical? && y < @display_y[lay] - (height - screen_tile_y) / 2
y - @display_y[lay] + @map.height
else
y - @display_y[lay]
end
end
#--------------------------------------------------------------------------
# ● 下にスクロール
# distance : スクロールする距離
#--------------------------------------------------------------------------
def scroll_down(distance,lay=-1)
range = lay==-1 ? 0..4 : lay..lay
range.each do | i |
if loop_vertical?
@display_y[i] += distance
@display_y[i] %= @map.height
@parallax_y += distance if @parallax_loop_y && i==@para_layer
else
last_y = @display_y[i]
@display_y[i] = [@display_y[i] + distance, height - screen_tile_y].min
@parallax_y += @display_y[i] - last_y if i==@para_layer
end
end
end
#--------------------------------------------------------------------------
# ● 左にスクロール
# distance : スクロールする距離
#--------------------------------------------------------------------------
def scroll_left(distance,lay=-1)
range = lay==-1 ? 0..4 : lay..lay
range.each do | i |
if loop_horizontal?
@display_x[i] += @map.width - distance
@display_x[i] %= @map.width
@parallax_x -= distance if @parallax_loop_x && i==@para_layer
else
last_x = @display_x[i]
@display_x[i] = [@display_x[i] - distance, 0].max
@parallax_x += @display_x[i] - last_x if i==@para_layer
end
end
end
#--------------------------------------------------------------------------
# ● 右にスクロール
# distance : スクロールする距離
#--------------------------------------------------------------------------
def scroll_right(distance,lay=-1)
range = lay==-1 ? 0..4 : lay..lay
range.each do | i |
if loop_horizontal?
@display_x[i] += distance
@display_x[i] %= @map.width
@parallax_x += distance if @parallax_loop_x && i==@para_layer
else
last_x = @display_x[i]
@display_x[i] = [@display_x[i] + distance, (width - screen_tile_x)].min
@parallax_x += @display_x[i] - last_x if i==@para_layer
end
end
end
#--------------------------------------------------------------------------
# ● 上にスクロール
# distance : スクロールする距離
#--------------------------------------------------------------------------
def scroll_up(distance,lay=-1)
range = lay==-1 ? 0..4 : lay..lay
range.each do | i |
if loop_vertical?
@display_y[i] += @map.height - distance
@display_y[i] %= @map.height
@parallax_y -= distance if @parallax_loop_y if i==@para_layer
else
last_y = @display_y[i]
@display_y[i] = [@display_y[i] - distance, 0].max
@parallax_y += @display_y[i] - last_y if i==@para_layer
end
end
end
#--------------------------------------------------------------------------
# ● スクロールの更新
#--------------------------------------------------------------------------
def update_scroll
return unless scrolling?
lay = $game_player.active_layer
last_x = @display_x[lay]
last_y = @display_y[lay]
do_scroll(@scroll_direction, scroll_distance)
if @display_x[lay] == last_x && @display_y[lay] == last_y
@scroll_rest = 0
else
@scroll_rest -= scroll_distance
end
end
#--------------------------------------------------------------------------
# ● 挟み込む特殊ピクチャスプライトを表示
#--------------------------------------------------------------------------
def set_spe_picture(layer,filename)
@spe_picture_name = filename
@spe_picture_layer = layer
end
end
#==============================================================================
# ■ Scene_Map
#------------------------------------------------------------------------------
# マップ画面の処理を行うクラスです。
#==============================================================================
class Scene_Map < Scene_Base
#--------------------------------------------------------------------------
# ● 公開インスタンス変数
#--------------------------------------------------------------------------
attr_accessor :spriteset
#--------------------------------------------------------------------------
# ● スプライトセットの作成
#--------------------------------------------------------------------------
def create_spriteset
@spriteset = Spriteset_Map_Ctrl.new
end
#--------------------------------------------------------------------------
# ● 場所移動の処理
#--------------------------------------------------------------------------
def perform_transfer
pre_transfer
$game_player.perform_transfer
dispose_spriteset
create_spriteset
post_transfer
end
end
#==============================================================================
# ■ Spriteset_Map_Ctrl
#------------------------------------------------------------------------------
# レイヤー毎に持っているスプライトセットをまとめて管理
#==============================================================================
class Spriteset_Map_Ctrl
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
def initialize
@spriteset = []
range = 0..$game_map.get_layer_num-1
range.each do |i|
$game_map.set_layer_no(i)
upper_flg = i==$game_map.get_layer_num-1 ? true : false
@spriteset.push(Spriteset_Map.new(i,upper_flg))
end
end
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def update
@spriteset.each { | sprite | sprite.update }
end
#--------------------------------------------------------------------------
# ● 終了処理
#--------------------------------------------------------------------------
def dispose
@spriteset.each { | sprite | sprite.dispose }
end
#--------------------------------------------------------------------------
# ● 内部のレイヤースプライトを取得
#--------------------------------------------------------------------------
def get_layer_sprite
return @spriteset
end
#--------------------------------------------------------------------------
# ● キャラクターのスプライトを解放
#--------------------------------------------------------------------------
def dispose_characters
@spriteset.each { | sprite | sprite.dispose_characters }
end
end
#==============================================================================
# ■ Spriteset_Map
#------------------------------------------------------------------------------
# マップ画面のスプライトやタイルマップなどをまとめたクラスです。このクラスは
# Scene_Map クラスの内部で使用されます。
#==============================================================================
class Spriteset_Map
#--------------------------------------------------------------------------
# ● 公開インスタンス変数
#--------------------------------------------------------------------------
attr_accessor :viewport1
attr_accessor :viewport2
attr_accessor :viewport3
attr_accessor :character_sprites
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
def initialize(pri,top)
@pri = pri
@top = top
create_viewports
create_tilemap
create_parallax if update_parallaxes?
create_spe_pic if update_spe?
create_characters
create_shadow if update?
create_weather if update?
create_pictures if update?
create_timer if update?
update
end
#--------------------------------------------------------------------------
# ● 解放
#--------------------------------------------------------------------------
def dispose
dispose_tilemap
dispose_parallax if update_parallaxes?
dispose_spe_pic if update_spe?
dispose_characters
dispose_shadow if update?
dispose_weather if update?
dispose_pictures if update?
dispose_timer if update?
dispose_viewports
end
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def update
$game_map.set_layer_no(@pri)
update_tileset
update_tilemap
update_parallax if update_parallaxes?
update_spe_pic if update_spe?
update_characters
update_shadow if update?
update_weather if update?
update_pictures if update?
update_timer if update?
update_viewports
end
#--------------------------------------------------------------------------
# ● タイルマップの作成
#--------------------------------------------------------------------------
alias create_tilemap_layer create_tilemap
def create_tilemap
create_tilemap_layer
refresh_tilemap
end
#--------------------------------------------------------------------------
# ● タイルマップの作成
#--------------------------------------------------------------------------
def refresh_tilemap
erase_tile(Game_Map::LAYER_UP)
erase_tile(Game_Map::LAYER_DW)
end
#--------------------------------------------------------------------------
# ● いらないタイルを消す
#--------------------------------------------------------------------------
def erase_tile(id)
x=(id%8)*32 + 256*(id/888)
y=(id-768)/8*32 - 512*(id/888)
@tilemap.bitmaps[8].clear_rect(x, y, 32, 32)
end
#--------------------------------------------------------------------------
# ● キャラクタースプライトの作成
#--------------------------------------------------------------------------
def create_characters
@character_sprites = []
$game_map.events.values.each do |event|
@character_sprites.push(Sprite_Character.new(@viewport1, event, @pri))
end
$game_map.vehicles.each do |vehicle|
@character_sprites.push(Sprite_Character.new(@viewport1, vehicle, @pri))
end
$game_player.followers.reverse_each do |follower|
@character_sprites.push(Sprite_Character.new(@viewport1, follower, @pri))
end
@character_sprites.push(Sprite_Character.new(@viewport1, $game_player, @pri))
@map_id = $game_map.map_id
end
#--------------------------------------------------------------------------
# ● アップデートするか?
#--------------------------------------------------------------------------
def update?
return true if @pri==0
return false
end
#--------------------------------------------------------------------------
# ● アップデートするか?(遠景)
#--------------------------------------------------------------------------
def update_parallaxes?
return @pri==$game_map.para_layer ? true : false
end
#--------------------------------------------------------------------------
# ● アップデートするか?(最上層)
#--------------------------------------------------------------------------
def update_top?
return @top
end
#--------------------------------------------------------------------------
# ● アップデートするか?(挟み込むピクチャ)
#--------------------------------------------------------------------------
def update_spe?
return @pri==$game_map.spe_picture_layer ? true : false
end
#--------------------------------------------------------------------------
# ● ビューポートの更新
#--------------------------------------------------------------------------
def update_viewports
if update_top?
@viewport1.tone = $game_map.screen.tone
end
@viewport1.ox = $game_map.screen.shake
if update_top?
@viewport2.color = $game_map.screen.flash_color
@viewport3.color.set(0, 0, 0, 255 - $game_map.screen.brightness)
end
@viewport1.update
@viewport2.update
@viewport3.update
end
#--------------------------------------------------------------------------
# ● タイルマップの更新
#--------------------------------------------------------------------------
def update_tilemap
@tilemap.map_data = $game_map.data
@tilemap.ox = $game_map.display_x[@pri] * 32
@tilemap.oy = $game_map.display_y[@pri] * 32
@tilemap.update
end
#--------------------------------------------------------------------------
# ● 天候の更新
#--------------------------------------------------------------------------
def update_weather
@weather.type = $game_map.screen.weather_type
@weather.power = $game_map.screen.weather_power
@weather.ox = $game_map.display_x[@pri] * 32
@weather.oy = $game_map.display_y[@pri] * 32
@weather.update
end
#--------------------------------------------------------------------------
# ● 挟み込む特殊ピクチャスプライトを作成
#--------------------------------------------------------------------------
def create_spe_pic
@layer_sprite = Sprite.new
@filename = ""
@old_filename = ""
end
#--------------------------------------------------------------------------
# ● 挟み込む特殊ピクチャスプライトを更新
#--------------------------------------------------------------------------
def update_spe_pic
@layer_sprite.update
filename = $game_map.spe_picture_name
if @pri == $game_map.spe_picture_layer && filename != @old_filename
if filename != ""
name = "Graphics/Pictures/" + $game_map.spe_picture_name
@layer_sprite.bitmap = Bitmap.new(name)
@layer_sprite.wave_amp = 5
@layer_sprite.wave_length = 5
@layer_sprite.wave_speed = 20
@layer_sprite.x = -20
@layer_sprite.y = 0
@layer_sprite.z = 0
@layer_sprite.opacity = 200
@layer_sprite.visible = true
else
@layer_sprite.visible = false
end
@old_filename = filename
end
end
#--------------------------------------------------------------------------
# ● 挟み込む特殊ピクチャスプライトを解放
#--------------------------------------------------------------------------
def dispose_spe_pic
@layer_sprite.dispose if @layer_sprite != nil
end
#--------------------------------------------------------------------------
# ● タイルセットの更新
#--------------------------------------------------------------------------
def update_tileset
if @tileset != $game_map.tileset
load_tileset
refresh_characters
refresh_tilemap
end
end
end
#==============================================================================
# ■ Game_Player
#------------------------------------------------------------------------------
# プレイヤーを扱うクラスです。イベントの起動判定や、マップのスクロールなどの
# 機能を持っています。このクラスのインスタンスは $game_player で参照されます。
#==============================================================================
class Game_Player < Game_Character
#--------------------------------------------------------------------------
# ● マップ通行可能判定
# d : 方向(2,4,6,8)
#--------------------------------------------------------------------------
def map_passable?(x, y, d)
case @vehicle_type
when :boat
$game_map.boat_passable?(x, y, @active_layer)
when :ship
$game_map.ship_passable?(x, y, @active_layer)
when :airship
true
else
super
end
end
#--------------------------------------------------------------------------
# ● 場所移動の実行
#--------------------------------------------------------------------------
def perform_transfer
if transfer?
set_direction(@new_direction)
if @new_map_id != $game_map.map_id
$game_map.setup(@new_map_id,true) # レイヤー間を移動するので常にセット
$game_map.autoplay
end
moveto(@new_x, @new_y)
link_layer_followers
clear_transfer_info
end
end
#--------------------------------------------------------------------------
# ● マップイベントの起動
# triggers : トリガーの配列
# normal : プライオリティ[通常キャラと同じ]かそれ以外か
#--------------------------------------------------------------------------
def start_map_event(x, y, triggers, normal)
$game_map.events_xy(x, y).each do |event|
next unless check_enable_layer(event)
if event.trigger_in?(triggers) && event.normal_priority? == normal
event.start
end
end
end
#--------------------------------------------------------------------------
# ● 更新
#--------------------------------------------------------------------------
alias game_player_update update
def update
game_player_update
$game_system.layer = $game_player.active_layer
end
#--------------------------------------------------------------------------
# ● 乗り物に乗る
# 現在乗り物に乗っていないことが前提。
#--------------------------------------------------------------------------
def get_on_vehicle
add = 0
check_layer = (@active_layer + 1) % $game_map.get_layer_num
add = 1 if $game_map.get_chip_id(self.x, self.y, check_layer) == Game_Map::LAYER_DW
check_layer = (@active_layer - 1) % $game_map.get_layer_num
add =-1 if $game_map.get_chip_id(self.x, self.y, check_layer) == Game_Map::LAYER_UP
front_x = $game_map.x_with_direction(@x, @direction)
front_y = $game_map.y_with_direction(@y, @direction)
@vehicle_type = :boat if $game_map.boat.pos?(front_x, front_y) && @active_layer+add == $game_map.boat.active_layer # 正面に大型船がある?
@vehicle_type = :ship if $game_map.ship.pos?(front_x, front_y) && @active_layer+add == $game_map.ship.active_layer # 正面に小型船がある?
@vehicle_type = :airship if $game_map.airship.pos?(@x, @y)
if vehicle
@vehicle_getting_on = true
force_move_forward unless in_airship?
@followers.gather
end
@vehicle_getting_on
end
#--------------------------------------------------------------------------
# ● 乗り物から降りる
# 現在乗り物に乗っていることが前提。
#--------------------------------------------------------------------------
alias game_player_get_off_vehicle get_off_vehicle
def get_off_vehicle
front_x = $game_map.x_with_direction(@x, @direction)
front_y = $game_map.y_with_direction(@y, @direction)
id0 = $game_map.get_chip_id(front_x, front_y, @active_layer)
id1 = $game_map.get_chip_id(front_x, front_y, (@active_layer+1)%$game_map.get_layer_num)
return if id0 == Game_Map::LAYER_UP || id0 == Game_Map::LAYER_DW
return if id1 == Game_Map::LAYER_UP || id1 == Game_Map::LAYER_DW
game_player_get_off_vehicle
end
#--------------------------------------------------------------------------
# ● スクロール処理
#--------------------------------------------------------------------------
def update_scroll(last_real_x, last_real_y)
ax1 = $game_map.adjust_x(last_real_x, @active_layer)
ay1 = $game_map.adjust_y(last_real_y, @active_layer)
ax2 = $game_map.adjust_x(@real_x, @active_layer)
ay2 = $game_map.adjust_y(@real_y, @active_layer)
$game_map.scroll_down (ay2 - ay1) if ay2 > ay1 && ay2 > center_y
$game_map.scroll_left (ax1 - ax2) if ax2 < ax1 && ax2 < center_x
$game_map.scroll_right(ax2 - ax1) if ax2 > ax1 && ax2 > center_x
$game_map.scroll_up (ay1 - ay2) if ay2 < ay1 && ay2 < center_y
end
#--------------------------------------------------------------------------
# ● フォロワーのレイヤーをリンクする
#--------------------------------------------------------------------------
def link_layer_followers
@followers.each { |f| f.active_layer = @active_layer }
end
end
#==============================================================================
# ■ Game_Vehicle
#------------------------------------------------------------------------------
# 乗り物を扱うクラスです。このクラスは Game_Map クラスの内部で使用されます。
# 現在のマップに乗り物がないときは、マップ座標 (-1,-1) に設定されます。
#==============================================================================
class Game_Vehicle < Game_Character
#--------------------------------------------------------------------------
# ● 接岸/着陸可能判定
# d : 方向(2,4,6,8)
#--------------------------------------------------------------------------
def land_ok?(x, y, d)
if @type == :airship
return false unless $game_map.airship_land_ok?(x, y)
return false unless $game_map.events_xy(x, y).empty?
else
x2 = $game_map.round_x_with_direction(x, d)
y2 = $game_map.round_y_with_direction(y, d)
return false unless $game_map.valid?(x2, y2)
return false unless $game_map.passable?(x2, y2, reverse_dir(d), @active_layer)
return false if collide_with_characters?(x2, y2)
end
return true
end
end
#==============================================================================
# ■ Game_Event
#------------------------------------------------------------------------------
# イベントを扱うクラスです。条件判定によるイベントページ切り替えや、並列処理
# イベント実行などの機能を持っており、Game_Map クラスの内部で使用されます。
#==============================================================================
class Game_Event < Game_Character
#--------------------------------------------------------------------------
# ● 公開インスタンス変数
#--------------------------------------------------------------------------
attr_accessor :id
#--------------------------------------------------------------------------
# ● オブジェクト初期化
# event : RPG::Event
#--------------------------------------------------------------------------
def initialize(map_id, event)
super()
@map_id = map_id
@event = event
@id = @event.id
self.active_layer = @id / Game_Map::MAX_EVENT
moveto(@event.x, @event.y)
refresh
end
#--------------------------------------------------------------------------
# ● 接触イベントの起動判定
#--------------------------------------------------------------------------
def check_event_trigger_touch(x, y)
return if $game_map.interpreter.running?
if @trigger == 2 && $game_player.pos?(x, y) && check_enable_layer($game_player)
start if !jumping? && normal_priority?
end
end
#--------------------------------------------------------------------------
# ● 画面の可視領域付近にいるか判定
# dx : 画面中央から左右何マス以内を判定するか
# dy : 画面中央から上下何マス以内を判定するか
#--------------------------------------------------------------------------
def near_the_screen?(dx = 12, dy = 8)
ax = $game_map.adjust_x(@real_x,@active_layer) - Graphics.width / 2 / 32
ay = $game_map.adjust_y(@real_y,@active_layer) - Graphics.height / 2 / 32
ax >= -dx && ax <= dx && ay >= -dy && ay <= dy
end
end
#==============================================================================
# ■ Game_CharacterBase
#------------------------------------------------------------------------------
# キャラクターを扱う基本のクラスです。全てのキャラクターに共通する、座標やグ
# ラフィックなどの基本的な情報を保持します。
#==============================================================================
class Game_CharacterBase
#--------------------------------------------------------------------------
# ● 公開インスタンス変数
#--------------------------------------------------------------------------
attr_accessor :active_layer
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
alias initialize2 initialize
def initialize
initialize2
@active_layer = 0
end
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def update
update_layer_change
update_animation
return update_jump if jumping?
return update_move if moving?
return update_stop
end
#--------------------------------------------------------------------------
# ● 所属レイヤーの変更
#--------------------------------------------------------------------------
def update_layer_change
return false if $game_map.get_layer_num == 1
return if @old_x == self.x && @old_y == self.y
if @active_layer+1 < $game_map.get_layer_num
id = $game_map.get_chip_id(self.x,self.y,@active_layer+1)
@active_layer=@active_layer+1 if id == Game_Map::LAYER_UP
end
if @active_layer-1 > -1
id = $game_map.get_chip_id(self.x,self.y,@active_layer-1)
@active_layer=@active_layer-1 if id == Game_Map::LAYER_DW
end
@old_x = self.x
@old_y = self.y
end
#--------------------------------------------------------------------------
# ● キャラクター衝突判定
# x : X 座標
# y : Y 座標
# プレイヤーと乗り物を含め、通常キャラの衝突を検出する。
#--------------------------------------------------------------------------
def collide_with_characters?(x, y)
#一歩前を見るのでこの形に
add = 0
check_layer = (@active_layer + 1) % $game_map.get_layer_num
add = 1 if $game_map.get_chip_id(x, y, check_layer) == Game_Map::LAYER_UP
check_layer = (@active_layer - 1) % $game_map.get_layer_num
add =-1 if $game_map.get_chip_id(x, y, check_layer) == Game_Map::LAYER_DW
collide_with_events?(x, y, add) || collide_with_vehicles?(x, y, add)
end
#--------------------------------------------------------------------------
# ● イベントとの衝突判定
#--------------------------------------------------------------------------
def collide_with_events?(x, y, add=0)
$game_map.events_xy_nt(x, y).any? do |event|
if event.active_layer == @active_layer || event.active_layer == @active_layer+add
event.normal_priority? || self.is_a?(Game_Event)
end
end
end
#--------------------------------------------------------------------------
# ● 乗り物との衝突判定
#--------------------------------------------------------------------------
def collide_with_vehicles?(x, y, add=0)
collide_with_boat?(x, y, add) || collide_with_ship?(x, y, add)
end
#--------------------------------------------------------------------------
# ● 大型船との衝突判定
#--------------------------------------------------------------------------
def collide_with_ship?(x, y, add=0)
if $game_map.ship.active_layer != @active_layer+add && $game_map.ship.active_layer != @active_layer
return false
end
$game_map.ship.pos_nt?(x, y)
end
#--------------------------------------------------------------------------
# ● 小型船との衝突判定
#--------------------------------------------------------------------------
def collide_with_boat?(x, y, add=0)
if $game_map.boat.active_layer != @active_layer+add && $game_map.boat.active_layer != @active_layer
return false
end
$game_map.boat.pos_nt?(x, y)
end
#--------------------------------------------------------------------------
# ● 位置設定(イベント位置設定用)
#--------------------------------------------------------------------------
def set_pos(new_x,new_y,dir=@direction,lay=@active_layer)
moveto(new_x, new_y)
set_active_layer(lay)
case dir # 向き
when 8 # 上
turn_up
when 6 # 右
turn_right
when 2 # 下
turn_down
when 4 # 左
turn_left
end
end
#--------------------------------------------------------------------------
# ● 茂み判定
#--------------------------------------------------------------------------
def bush?
$game_map.bush?(@x, @y, @active_layer)
end
#--------------------------------------------------------------------------
# ● マップ通行可能判定
# x : X 座標
# y : Y 座標
#--------------------------------------------------------------------------
def map_passable?(x, y, d)
$game_map.passable?(x, y, d, @active_layer)
end
#--------------------------------------------------------------------------
# ● 違うレイヤーのイベント起動判定
#--------------------------------------------------------------------------
def check_enable_layer(object)
#自分が「上」に乗っている時
#自分は今のレイヤーと一つ下のレイヤーをチェックするはず
id = $game_map.get_chip_id(self.x, self.y, @active_layer)
if id == Game_Map::LAYER_UP
layer =(@active_layer-1) % $game_map.get_layer_num
return true if object.active_layer == @active_layer
return true if object.active_layer == @active_layer-1
end
#自分が「下」に乗っている時
#自分は今のレイヤーと一つ上のレイヤーをチェックするはず
id = $game_map.get_chip_id(self.x, self.y, @active_layer)
if id == Game_Map::LAYER_DW
layer =(@active_layer+1) % $game_map.get_layer_num
return true if object.active_layer == @active_layer
return true if object.active_layer == @active_layer+1
end
#どちらでもない場合
return true if object.active_layer == @active_layer
return false
end
#--------------------------------------------------------------------------
# ● 画面 X 座標の取得
#--------------------------------------------------------------------------
def screen_x
$game_map.adjust_x(@real_x,@active_layer) * 32 + 16
end
#--------------------------------------------------------------------------
# ● 画面 Y 座標の取得
#--------------------------------------------------------------------------
def screen_y
$game_map.adjust_y(@real_y,@active_layer) * 32 + 32 - shift_y - jump_height
end
#--------------------------------------------------------------------------
# ● 所属レイヤーのセット
#--------------------------------------------------------------------------
def set_active_layer(no)
@active_layer = no
end
end
#==============================================================================
# ■ Sprite_Character
#------------------------------------------------------------------------------
# キャラクター表示用のスプライトです。Game_Character クラスのインスタンスを
# 監視し、スプライトの状態を自動的に変化させます。
#==============================================================================
class Sprite_Character < Sprite_Base
#--------------------------------------------------------------------------
# ● オブジェクト初期化
# viewport : ビューポート
# character : キャラクター (Game_Character)
#--------------------------------------------------------------------------
alias sprite_character_initialize initialize
def initialize(viewport, character = nil, layer = 0)
@layer = layer
sprite_character_initialize(viewport, character)
end
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
alias sprite_character_update update
def update
unless update?
self.visible = false
return
end
sprite_character_update
end
#--------------------------------------------------------------------------
# ● フレーム更新を行うか?
#--------------------------------------------------------------------------
def update?
test_x = @character.x
test_y = @character.y
char_layer = @character.active_layer #キャラクターのレイヤー
range = 0..3
check_pos_x = [test_x,test_x,test_x-1,test_x+1]
check_pos_y = [test_y-1,test_y+1,test_y,test_y]
if char_layer+1 == @layer
range.each do | i |
id = $game_map.get_chip_id(check_pos_x[i],check_pos_y[i],@layer)
return true if id == Game_Map::LAYER_UP
end
end
if char_layer == @layer
range.each do | i |
id = $game_map.get_chip_id(check_pos_x[i],check_pos_y[i],@layer)
return true if id != Game_Map::LAYER_UP
end
end
return false
end
#--------------------------------------------------------------------------
# ● 位置の更新
#--------------------------------------------------------------------------
def update_position
self.x = @character.screen_x.round
self.y = @character.screen_y.round
self.z = @character.screen_z
end
end
#==============================================================================
# ■ Game_Interpreter
#------------------------------------------------------------------------------
# イベントコマンドを実行するインタプリタです。このクラスは Game_Map クラス、
# Game_Troop クラス、Game_Event クラスの内部で使用されます。
#==============================================================================
class Game_Interpreter
#--------------------------------------------------------------------------
# ● イベントのセットアップ
# list : 実行内容
# event_id : イベント ID
#--------------------------------------------------------------------------
alias Game_Interpreter_setup setup
def setup(list, event_id = 0)
Game_Interpreter_setup(list, event_id)
#どのレイヤーのイベントが起動したか
@setup_layer = event_id / Game_Map::MAX_EVENT
end
#--------------------------------------------------------------------------
# ● レイヤーの変更
#--------------------------------------------------------------------------
def set_active_layer(lay)
$game_map.events[@event_id].active_layer=lay if @event_id > 0
end
#--------------------------------------------------------------------------
# ● キャラクターの取得
# param : -1 ならプレイヤー、0 ならこのイベント、それ以外はイベント ID
#--------------------------------------------------------------------------
def get_character(param)
if $game_party.in_battle
nil
elsif param < 0
$game_player
else
events = same_map? ? $game_map.events : {}
add = @setup_layer * Game_Map::MAX_EVENT
events[param > 0 ? param+add : @event_id]
end
end
end