486 lines
20 KiB
Ruby
486 lines
20 KiB
Ruby
#==============================================================================
|
||
# ■ Game_Player
|
||
#------------------------------------------------------------------------------
|
||
# プレイヤーを扱うクラスです。イベントの起動判定や、マップのスクロールなどの
|
||
# 機能を持っています。このクラスのインスタンスは $game_player で参照されます。
|
||
#==============================================================================
|
||
|
||
class Game_Player < Game_Character
|
||
#--------------------------------------------------------------------------
|
||
# ● 公開インスタンス変数
|
||
#--------------------------------------------------------------------------
|
||
attr_reader :followers # フォロワー(隊列メンバー)
|
||
#--------------------------------------------------------------------------
|
||
# ● オブジェクト初期化
|
||
#--------------------------------------------------------------------------
|
||
def initialize
|
||
super
|
||
@vehicle_type = :walk # 現在乗っている乗り物の種類
|
||
@vehicle_getting_on = false # 乗る動作の途中フラグ
|
||
@vehicle_getting_off = false # 降りる動作の途中フラグ
|
||
@followers = Game_Followers.new(self)
|
||
@transparent = $data_system.opt_transparent
|
||
clear_transfer_info
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 場所移動情報のクリア
|
||
#--------------------------------------------------------------------------
|
||
def clear_transfer_info
|
||
@transferring = false # 場所移動フラグ
|
||
@new_map_id = 0 # 移動先 マップ ID
|
||
@new_x = 0 # 移動先 X 座標
|
||
@new_y = 0 # 移動先 Y 座標
|
||
@new_direction = 0 # 移動後の向き
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● リフレッシュ
|
||
#--------------------------------------------------------------------------
|
||
def refresh
|
||
@character_name = actor ? actor.character_name : ""
|
||
@character_index = actor ? actor.character_index : 0
|
||
@followers.refresh
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 対応するアクターの取得
|
||
#--------------------------------------------------------------------------
|
||
def actor
|
||
$game_party.battle_members[0]
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 停止中判定
|
||
#--------------------------------------------------------------------------
|
||
def stopping?
|
||
return false if @vehicle_getting_on || @vehicle_getting_off
|
||
return super
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 場所移動の予約
|
||
# d : 移動後の向き(2,4,6,8)
|
||
#--------------------------------------------------------------------------
|
||
def reserve_transfer(map_id, x, y, d = 2)
|
||
@transferring = true
|
||
@new_map_id = map_id
|
||
@new_x = x
|
||
@new_y = y
|
||
@new_direction = d
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 場所移動の予約中判定
|
||
#--------------------------------------------------------------------------
|
||
def transfer?
|
||
@transferring
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 場所移動の実行
|
||
#--------------------------------------------------------------------------
|
||
def perform_transfer
|
||
if transfer?
|
||
set_direction(@new_direction)
|
||
if @new_map_id != $game_map.map_id
|
||
$game_map.setup(@new_map_id)
|
||
$game_map.autoplay
|
||
end
|
||
moveto(@new_x, @new_y)
|
||
clear_transfer_info
|
||
end
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● マップ通行可能判定
|
||
# d : 方向(2,4,6,8)
|
||
#--------------------------------------------------------------------------
|
||
def map_passable?(x, y, d)
|
||
case @vehicle_type
|
||
when :boat
|
||
$game_map.boat_passable?(x, y)
|
||
when :ship
|
||
$game_map.ship_passable?(x, y)
|
||
when :airship
|
||
true
|
||
else
|
||
super
|
||
end
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 現在乗っている乗り物を取得
|
||
#--------------------------------------------------------------------------
|
||
def vehicle
|
||
$game_map.vehicle(@vehicle_type)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 小型船に乗っている状態判定
|
||
#--------------------------------------------------------------------------
|
||
def in_boat?
|
||
@vehicle_type == :boat
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 大型船に乗っている状態判定
|
||
#--------------------------------------------------------------------------
|
||
def in_ship?
|
||
@vehicle_type == :ship
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 飛行船に乗っている状態判定
|
||
#--------------------------------------------------------------------------
|
||
def in_airship?
|
||
@vehicle_type == :airship
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 通常歩行状態判定
|
||
#--------------------------------------------------------------------------
|
||
def normal_walk?
|
||
@vehicle_type == :walk && !@move_route_forcing
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● ダッシュ状態判定
|
||
#--------------------------------------------------------------------------
|
||
def dash?
|
||
return false if @move_route_forcing
|
||
return false if $game_map.disable_dash?
|
||
return false if vehicle
|
||
return Input.press?(:A)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● デバッグすり抜け状態判定
|
||
#--------------------------------------------------------------------------
|
||
def debug_through?
|
||
$TEST && Input.press?(:CTRL)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 衝突判定(フォロワーを含む)
|
||
#--------------------------------------------------------------------------
|
||
def collide?(x, y)
|
||
!@through && (pos?(x, y) || followers.collide?(x, y))
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 画面中央の X 座標
|
||
#--------------------------------------------------------------------------
|
||
def center_x
|
||
(Graphics.width / 32 - 1) / 2.0
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 画面中央の Y 座標
|
||
#--------------------------------------------------------------------------
|
||
def center_y
|
||
(Graphics.height / 32 - 1) / 2.0
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 画面中央に来るようにマップの表示位置を設定
|
||
#--------------------------------------------------------------------------
|
||
def center(x, y)
|
||
$game_map.set_display_pos(x - center_x, y - center_y)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 指定位置に移動
|
||
#--------------------------------------------------------------------------
|
||
def moveto(x, y)
|
||
super
|
||
center(x, y)
|
||
make_encounter_count
|
||
vehicle.refresh if vehicle
|
||
@followers.synchronize(x, y, direction)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 歩数増加
|
||
#--------------------------------------------------------------------------
|
||
def increase_steps
|
||
super
|
||
$game_party.increase_steps if normal_walk?
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● エンカウント カウント作成
|
||
#--------------------------------------------------------------------------
|
||
def make_encounter_count
|
||
n = $game_map.encounter_step
|
||
@encounter_count = rand(n) + rand(n) + 1
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● エンカウントする敵グループの ID を作成
|
||
#--------------------------------------------------------------------------
|
||
def make_encounter_troop_id
|
||
encounter_list = []
|
||
weight_sum = 0
|
||
$game_map.encounter_list.each do |encounter|
|
||
next unless encounter_ok?(encounter)
|
||
encounter_list.push(encounter)
|
||
weight_sum += encounter.weight
|
||
end
|
||
if weight_sum > 0
|
||
value = rand(weight_sum)
|
||
encounter_list.each do |encounter|
|
||
value -= encounter.weight
|
||
return encounter.troop_id if value < 0
|
||
end
|
||
end
|
||
return 0
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● エンカウント項目の採用可能判定
|
||
#--------------------------------------------------------------------------
|
||
def encounter_ok?(encounter)
|
||
return true if encounter.region_set.empty?
|
||
return true if encounter.region_set.include?(region_id)
|
||
return false
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● エンカウント処理の実行
|
||
#--------------------------------------------------------------------------
|
||
def encounter
|
||
return false if $game_map.interpreter.running?
|
||
return false if $game_system.encounter_disabled
|
||
return false if @encounter_count > 0
|
||
make_encounter_count
|
||
troop_id = make_encounter_troop_id
|
||
return false unless $data_troops[troop_id]
|
||
BattleManager.setup(troop_id)
|
||
BattleManager.on_encounter
|
||
return true
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● マップイベントの起動
|
||
# triggers : トリガーの配列
|
||
# normal : プライオリティ[通常キャラと同じ]かそれ以外か
|
||
#--------------------------------------------------------------------------
|
||
def start_map_event(x, y, triggers, normal)
|
||
$game_map.events_xy(x, y).each do |event|
|
||
if event.trigger_in?(triggers) && event.normal_priority? == normal
|
||
event.start
|
||
end
|
||
end
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 同位置のイベント起動判定
|
||
#--------------------------------------------------------------------------
|
||
def check_event_trigger_here(triggers)
|
||
start_map_event(@x, @y, triggers, false)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 正面のイベント起動判定
|
||
#--------------------------------------------------------------------------
|
||
def check_event_trigger_there(triggers)
|
||
x2 = $game_map.round_x_with_direction(@x, @direction)
|
||
y2 = $game_map.round_y_with_direction(@y, @direction)
|
||
start_map_event(x2, y2, triggers, true)
|
||
return if $game_map.any_event_starting?
|
||
return unless $game_map.counter?(x2, y2)
|
||
x3 = $game_map.round_x_with_direction(x2, @direction)
|
||
y3 = $game_map.round_y_with_direction(y2, @direction)
|
||
start_map_event(x3, y3, triggers, true)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 接触イベントの起動判定
|
||
#--------------------------------------------------------------------------
|
||
def check_event_trigger_touch(x, y)
|
||
start_map_event(x, y, [1,2], true)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 方向ボタン入力による移動処理
|
||
#--------------------------------------------------------------------------
|
||
def move_by_input
|
||
return if !movable? || $game_map.interpreter.running?
|
||
move_straight(Input.dir4) if Input.dir4 > 0
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 移動可能判定
|
||
#--------------------------------------------------------------------------
|
||
def movable?
|
||
return false if moving?
|
||
return false if @move_route_forcing || @followers.gathering?
|
||
return false if @vehicle_getting_on || @vehicle_getting_off
|
||
return false if $game_message.busy? || $game_message.visible
|
||
return false if vehicle && !vehicle.movable?
|
||
return true
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● フレーム更新
|
||
#--------------------------------------------------------------------------
|
||
def update
|
||
last_real_x = @real_x
|
||
last_real_y = @real_y
|
||
last_moving = moving?
|
||
move_by_input
|
||
super
|
||
update_scroll(last_real_x, last_real_y)
|
||
update_vehicle
|
||
update_nonmoving(last_moving) unless moving?
|
||
@followers.update
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● スクロール処理
|
||
#--------------------------------------------------------------------------
|
||
def update_scroll(last_real_x, last_real_y)
|
||
ax1 = $game_map.adjust_x(last_real_x)
|
||
ay1 = $game_map.adjust_y(last_real_y)
|
||
ax2 = $game_map.adjust_x(@real_x)
|
||
ay2 = $game_map.adjust_y(@real_y)
|
||
$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 update_vehicle
|
||
return if @followers.gathering?
|
||
return unless vehicle
|
||
if @vehicle_getting_on
|
||
update_vehicle_get_on
|
||
elsif @vehicle_getting_off
|
||
update_vehicle_get_off
|
||
else
|
||
vehicle.sync_with_player
|
||
end
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 乗り物に乗る動作の更新
|
||
#--------------------------------------------------------------------------
|
||
def update_vehicle_get_on
|
||
if !@followers.gathering? && !moving?
|
||
@direction = vehicle.direction
|
||
@move_speed = vehicle.speed
|
||
@vehicle_getting_on = false
|
||
@transparent = true
|
||
@through = true if in_airship?
|
||
vehicle.get_on
|
||
end
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 乗り物から降りる動作の更新
|
||
#--------------------------------------------------------------------------
|
||
def update_vehicle_get_off
|
||
if !@followers.gathering? && vehicle.altitude == 0
|
||
@vehicle_getting_off = false
|
||
@vehicle_type = :walk
|
||
@transparent = false
|
||
end
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 移動中でない場合の処理
|
||
# last_moving : 直前に移動中だったか
|
||
#--------------------------------------------------------------------------
|
||
def update_nonmoving(last_moving)
|
||
return if $game_map.interpreter.running?
|
||
if last_moving
|
||
$game_party.on_player_walk
|
||
return if check_touch_event
|
||
end
|
||
if movable? && Input.trigger?(:C)
|
||
return if get_on_off_vehicle
|
||
return if check_action_event
|
||
end
|
||
update_encounter if last_moving
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● エンカウントの更新
|
||
#--------------------------------------------------------------------------
|
||
def update_encounter
|
||
return if $TEST && Input.press?(:CTRL)
|
||
return if $game_party.encounter_none?
|
||
return if in_airship?
|
||
return if @move_route_forcing
|
||
@encounter_count -= encounter_progress_value
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● エンカウント進行値の取得
|
||
#--------------------------------------------------------------------------
|
||
def encounter_progress_value
|
||
value = $game_map.bush?(@x, @y) ? 2 : 1
|
||
value *= 0.5 if $game_party.encounter_half?
|
||
value *= 0.5 if in_ship?
|
||
value
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 接触(重なり)によるイベント起動判定
|
||
#--------------------------------------------------------------------------
|
||
def check_touch_event
|
||
return false if in_airship?
|
||
check_event_trigger_here([1,2])
|
||
$game_map.setup_starting_event
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 決定ボタンによるイベント起動判定
|
||
#--------------------------------------------------------------------------
|
||
def check_action_event
|
||
return false if in_airship?
|
||
check_event_trigger_here([0])
|
||
return true if $game_map.setup_starting_event
|
||
check_event_trigger_there([0,1,2])
|
||
$game_map.setup_starting_event
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 乗り物の乗降
|
||
#--------------------------------------------------------------------------
|
||
def get_on_off_vehicle
|
||
if vehicle
|
||
get_off_vehicle
|
||
else
|
||
get_on_vehicle
|
||
end
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 乗り物に乗る
|
||
# 現在乗り物に乗っていないことが前提。
|
||
#--------------------------------------------------------------------------
|
||
def get_on_vehicle
|
||
front_x = $game_map.round_x_with_direction(@x, @direction)
|
||
front_y = $game_map.round_y_with_direction(@y, @direction)
|
||
@vehicle_type = :boat if $game_map.boat.pos?(front_x, front_y)
|
||
@vehicle_type = :ship if $game_map.ship.pos?(front_x, front_y)
|
||
@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
|
||
#--------------------------------------------------------------------------
|
||
# ● 乗り物から降りる
|
||
# 現在乗り物に乗っていることが前提。
|
||
#--------------------------------------------------------------------------
|
||
def get_off_vehicle
|
||
if vehicle.land_ok?(@x, @y, @direction)
|
||
set_direction(2) if in_airship?
|
||
@followers.synchronize(@x, @y, @direction)
|
||
vehicle.get_off
|
||
unless in_airship?
|
||
force_move_forward
|
||
@transparent = false
|
||
end
|
||
@vehicle_getting_off = true
|
||
@move_speed = 4
|
||
@through = false
|
||
make_encounter_count
|
||
@followers.gather
|
||
end
|
||
@vehicle_getting_off
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 強制的に一歩前進
|
||
#--------------------------------------------------------------------------
|
||
def force_move_forward
|
||
@through = true
|
||
move_forward
|
||
@through = false
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● ダメージ床判定
|
||
#--------------------------------------------------------------------------
|
||
def on_damage_floor?
|
||
$game_map.damage_floor?(@x, @y) && !in_airship?
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● まっすぐに移動
|
||
#--------------------------------------------------------------------------
|
||
def move_straight(d, turn_ok = true)
|
||
@followers.move if passable?(@x, @y, d)
|
||
super
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 斜めに移動
|
||
#--------------------------------------------------------------------------
|
||
def move_diagonal(horz, vert)
|
||
@followers.move if diagonal_passable?(@x, @y, horz, vert)
|
||
super
|
||
end
|
||
end
|