311 lines
No EOL
12 KiB
Ruby
311 lines
No EOL
12 KiB
Ruby
#==============================================================================
|
|
# ■ Game_Event
|
|
#------------------------------------------------------------------------------
|
|
# イベントを扱うクラスです。条件判定によるイベントページ切り替えや、並列処理
|
|
# イベント実行などの機能を持っており、Game_Map クラスの内部で使用されます。
|
|
#==============================================================================
|
|
|
|
class Game_Event < Game_Character
|
|
#--------------------------------------------------------------------------
|
|
# ● 公開インスタンス変数
|
|
#--------------------------------------------------------------------------
|
|
attr_reader :trigger # トリガー
|
|
attr_reader :list # 実行内容
|
|
attr_reader :starting # 起動中フラグ
|
|
#--------------------------------------------------------------------------
|
|
# ● オブジェクト初期化
|
|
# event : RPG::Event
|
|
#--------------------------------------------------------------------------
|
|
def initialize(map_id, event)
|
|
super()
|
|
@map_id = map_id
|
|
@event = event
|
|
@id = @event.id
|
|
moveto(@event.x, @event.y)
|
|
refresh
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● 公開メンバ変数の初期化
|
|
#--------------------------------------------------------------------------
|
|
def init_public_members
|
|
super
|
|
@trigger = 0
|
|
@list = nil
|
|
@starting = false
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● 非公開メンバ変数の初期化
|
|
#--------------------------------------------------------------------------
|
|
def init_private_members
|
|
super
|
|
@move_type = 0 # 移動タイプ
|
|
@erased = false # 一時消去フラグ
|
|
@page = nil # イベントページ
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● キャラクターとの衝突判定
|
|
#--------------------------------------------------------------------------
|
|
def collide_with_characters?(x, y)
|
|
super || collide_with_player_characters?(x, y)
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● プレイヤーとの衝突判定(フォロワーを含む)
|
|
#--------------------------------------------------------------------------
|
|
def collide_with_player_characters?(x, y)
|
|
normal_priority? && $game_player.collide?(x, y)
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● ロック(実行中のイベントが立ち止まる処理)
|
|
#--------------------------------------------------------------------------
|
|
def lock
|
|
unless @locked
|
|
@prelock_direction = @direction
|
|
turn_toward_player
|
|
@locked = true
|
|
end
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● ロック解除
|
|
#--------------------------------------------------------------------------
|
|
def unlock
|
|
if @locked
|
|
@locked = false
|
|
set_direction(@prelock_direction)
|
|
end
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● 停止時の更新
|
|
#--------------------------------------------------------------------------
|
|
def update_stop
|
|
super
|
|
update_self_movement unless @move_route_forcing
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● 自律移動の更新
|
|
#--------------------------------------------------------------------------
|
|
def update_self_movement
|
|
if near_the_screen? && @stop_count > stop_count_threshold
|
|
case @move_type
|
|
when 1; move_type_random
|
|
when 2; move_type_toward_player
|
|
when 3; move_type_custom
|
|
end
|
|
end
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● 画面の可視領域付近にいるか判定
|
|
# dx : 画面中央から左右何マス以内を判定するか
|
|
# dy : 画面中央から上下何マス以内を判定するか
|
|
#--------------------------------------------------------------------------
|
|
def near_the_screen?(dx = 12, dy = 8)
|
|
ax = $game_map.adjust_x(@real_x) - Graphics.width / 2 / 32
|
|
ay = $game_map.adjust_y(@real_y) - Graphics.height / 2 / 32
|
|
ax >= -dx && ax <= dx && ay >= -dy && ay <= dy
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● 自律移動を開始する停止カウントの閾値を計算
|
|
#--------------------------------------------------------------------------
|
|
def stop_count_threshold
|
|
30 * (5 - @move_frequency)
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● 移動タイプ : ランダム
|
|
#--------------------------------------------------------------------------
|
|
def move_type_random
|
|
case rand(6)
|
|
when 0..1; move_random
|
|
when 2..4; move_forward
|
|
when 5; @stop_count = 0
|
|
end
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● 移動タイプ : 近づく
|
|
#--------------------------------------------------------------------------
|
|
def move_type_toward_player
|
|
if near_the_player?
|
|
case rand(6)
|
|
when 0..3; move_toward_player
|
|
when 4; move_random
|
|
when 5; move_forward
|
|
end
|
|
else
|
|
move_random
|
|
end
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● プレイヤーの近くにいるか判定
|
|
#--------------------------------------------------------------------------
|
|
def near_the_player?
|
|
sx = distance_x_from($game_player.x).abs
|
|
sy = distance_y_from($game_player.y).abs
|
|
sx + sy < 20
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● 移動タイプ : カスタム
|
|
#--------------------------------------------------------------------------
|
|
def move_type_custom
|
|
update_routine_move
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● 起動中フラグのクリア
|
|
#--------------------------------------------------------------------------
|
|
def clear_starting_flag
|
|
@starting = false
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● 実行内容が空か否かを判定
|
|
#--------------------------------------------------------------------------
|
|
def empty?
|
|
!@list || @list.size <= 1
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● 指定されたトリガーのいずれかか否かを判定
|
|
# triggers : トリガーの配列
|
|
#--------------------------------------------------------------------------
|
|
def trigger_in?(triggers)
|
|
triggers.include?(@trigger)
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● イベント起動
|
|
#--------------------------------------------------------------------------
|
|
def start
|
|
return if empty?
|
|
@starting = true
|
|
lock if trigger_in?([0,1,2])
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● 一時消去
|
|
#--------------------------------------------------------------------------
|
|
def erase
|
|
@erased = true
|
|
refresh
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● リフレッシュ
|
|
#--------------------------------------------------------------------------
|
|
def refresh
|
|
new_page = @erased ? nil : find_proper_page
|
|
setup_page(new_page) if !new_page || new_page != @page
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● 条件に合うイベントページを見つける
|
|
#--------------------------------------------------------------------------
|
|
def find_proper_page
|
|
@event.pages.reverse.find {|page| conditions_met?(page) }
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● イベントページの条件合致判定
|
|
#--------------------------------------------------------------------------
|
|
def conditions_met?(page)
|
|
c = page.condition
|
|
if c.switch1_valid
|
|
return false unless $game_switches[c.switch1_id]
|
|
end
|
|
if c.switch2_valid
|
|
return false unless $game_switches[c.switch2_id]
|
|
end
|
|
if c.variable_valid
|
|
return false if $game_variables[c.variable_id] < c.variable_value
|
|
end
|
|
if c.self_switch_valid
|
|
key = [@map_id, @event.id, c.self_switch_ch]
|
|
return false if $game_self_switches[key] != true
|
|
end
|
|
if c.item_valid
|
|
item = $data_items[c.item_id]
|
|
return false unless $game_party.has_item?(item)
|
|
end
|
|
if c.actor_valid
|
|
actor = $game_actors[c.actor_id]
|
|
return false unless $game_party.members.include?(actor)
|
|
end
|
|
return true
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● イベントページのセットアップ
|
|
#--------------------------------------------------------------------------
|
|
def setup_page(new_page)
|
|
@page = new_page
|
|
if @page
|
|
setup_page_settings
|
|
else
|
|
clear_page_settings
|
|
end
|
|
update_bush_depth
|
|
clear_starting_flag
|
|
check_event_trigger_auto
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● イベントページの設定をクリア
|
|
#--------------------------------------------------------------------------
|
|
def clear_page_settings
|
|
@tile_id = 0
|
|
@character_name = ""
|
|
@character_index = 0
|
|
@move_type = 0
|
|
@through = true
|
|
@trigger = nil
|
|
@list = nil
|
|
@interpreter = nil
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● イベントページの設定をセットアップ
|
|
#--------------------------------------------------------------------------
|
|
def setup_page_settings
|
|
@tile_id = @page.graphic.tile_id
|
|
@character_name = @page.graphic.character_name
|
|
@character_index = @page.graphic.character_index
|
|
if @original_direction != @page.graphic.direction
|
|
@direction = @page.graphic.direction
|
|
@original_direction = @direction
|
|
@prelock_direction = 0
|
|
end
|
|
if @original_pattern != @page.graphic.pattern
|
|
@pattern = @page.graphic.pattern
|
|
@original_pattern = @pattern
|
|
end
|
|
@move_type = @page.move_type
|
|
@move_speed = @page.move_speed
|
|
@move_frequency = @page.move_frequency
|
|
@move_route = @page.move_route
|
|
@move_route_index = 0
|
|
@move_route_forcing = false
|
|
@walk_anime = @page.walk_anime
|
|
@step_anime = @page.step_anime
|
|
@direction_fix = @page.direction_fix
|
|
@through = @page.through
|
|
@priority_type = @page.priority_type
|
|
@trigger = @page.trigger
|
|
@list = @page.list
|
|
@interpreter = @trigger == 4 ? Game_Interpreter.new : nil
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● 接触イベントの起動判定
|
|
#--------------------------------------------------------------------------
|
|
def check_event_trigger_touch(x, y)
|
|
return if $game_map.interpreter.running?
|
|
if @trigger == 2 && $game_player.pos?(x, y)
|
|
start if !jumping? && normal_priority?
|
|
end
|
|
end
|
|
#--------------------------------------------------------------------------
|
|
# ● 自動イベントの起動判定
|
|
#--------------------------------------------------------------------------
|
|
def check_event_trigger_auto
|
|
start if @trigger == 3
|
|
end
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------
|
|
# ● フレーム更新
|
|
#--------------------------------------------------------------------------
|
|
def update
|
|
super
|
|
check_event_trigger_auto
|
|
return unless @interpreter
|
|
@interpreter.setup(@list, @event.id) unless @interpreter.running?
|
|
@interpreter.update
|
|
end
|
|
end
|
|
|