#==============================================================================
# ■ プレイヤーの8方向移動+斜め歩行グラに対応+その他 (VX Ace用)
#------------------------------------------------------------------------------
# 製作者     : CanariAlternate
# サイト名   : カルトの鳥篭
# サイトURL  : [url]http://canarialt.blog.fc2.com[/url]
#------------------------------------------------------------------------------
# ■ 概要 : 移動関連の機能を詰め込んだスクリプトです。
#           必要な機能だけ追加するように設定することも出来ます。
#           「プレイヤー操作拡張」「斜め向き画像の実装」「ダッシュの入力を反転」「斜めの通行可能判定」
# ■ 必須 : 「注釈取得スクリプト」※斜め歩行グラフィックを使用しない場合は不要
#
# ■ 位置 : 「イベント起動判定拡張」より下
#           「注釈取得スクリプト」より下
#------------------------------------------------------------------------------
# ■ 機能 : プレイヤーの8方向移動&斜め移動でスムーズに移動など
#           臼井の会様にて配布されている斜め歩行グラフィックに対応
#           走行状態をダッシュのデフォルトにする。
#           プレイヤーの移動操作禁止と許可をスイッチで切り替える。
#           斜めの通行可能判定をオートタイル(A1タイル)を考慮したものに変更
#------------------------------------------------------------------------------
# 更新履歴 : 2013/07/08 Ver1.00 複数のスクリプトを再設計し、これにまとめた。
#            2013/07/10 Ver1.01 斜め向きでの起動不可が機能していないバグを修正した。
#            2013/07/10 Ver1.02 スクリプトの設定に関する説明を修正した。
#==============================================================================
 
$imported ||= {}
$imported[:CanariAlternate_MoveSystems] = true
 
#==============================================================================
# ■ Calt
#------------------------------------------------------------------------------
#  CanariAlternateが製作したスクリプト用のモジュールです。
#==============================================================================
module Calt
  #----------------------------------------------------------------------------
  # ◆プレイヤーの8方向移動を使用するか
  DiagonalMovePlayer = true   # true / false
  #
  # 設定した番後のスイッチがONの時は8方向移動を禁止(0の場合は常にOFF)
  DiagonalMoveProhibition = 0 # スイッチ番号
  #
  # 設定した番号のスイッチがONの時は斜め方向の移動に失敗した場合に
  # 滑るように縦または横に移動する機能を無効化(0の場合は常にOFF)
  DiagonalMoveSlide = 0       # スイッチ番号
  #
  # そのキーを押している間は斜め移動しか出来なくなるキーを設定(nil を設定で無効)
  # キー候補一覧 :SHIFT :CTRL :ALT :A :B :C :X :Y :Z :L :R :F5 :F6 :F7 :F8 :F9
  DiagonalMoveOnlyKey = :ALT  # Inputモジュールの定数
  #
  # そのキーを押している間は移動はせず方向転換をするキーを設定(nil を設定で無効)
  # キー候補一覧 :SHIFT :CTRL :ALT :A :B :C :X :Y :Z :L :R :F5 :F6 :F7 :F8 :F9
  ChangeTurnModeKey = :CTRL   # Inputモジュールの定数
  #----------------------------------------------------------------------------
  # ◆斜め歩行グラフィックを使用するか
  DiagonalCharacterGraphic = true # true / false
  #
  # 斜め向きでの起動不可のキーワード
  # ※プレイヤーに斜めの歩行グラフィックを用意すると斜め方向からイベントを起動出来るようになります。
  # 一部のイベントは斜め方向から起動されると都合が悪い場合があります。(例えば、扉など)
  # イベントの実行内容の先頭に注釈でキーワードを記述することで斜め方向から起動出来なくなります。
  DiagonalNotStartNote    = /\[斜め向きでの起動不可\]/  # 記述した頁に適用
  DiagonalNotStartAllNote = /\<斜め向きでの起動不可\>/  # 全ての頁に適用(1頁目に記述)
  DiagonalNotStartReverse = false                       # 全てのイベントの初期状態を反転
  #
  # 斜め歩行グラフィック画像の名前
  # ※この名前の画像を用意すると斜めを向いた時にその画像になる
  #
  # ◇画像名の先頭に $ がついている場合(1キャラ分の画像)
  #   初期設定では斜め向き画像の名前は 画像名-X となる。
  #   例えば、$mainActor に斜め画像をつけたければ $mainActor-X という画像を用意する。
  DiagonalCharacterName      = "%s-X"
  #
  # ◇画像名の先頭に $ がついていない場合(8キャラ分の画像)
  #   初期設定では斜め向き画像の名前は $画像名-X-番号 となる。
  #   番号は 1~8 でどのキャラの斜め画像か指定する。1 2 3 4
  #                                                 5 6 7 8
  #   例えば、actor5 の4番のキャラに斜め画像をつけたければ $actor5-X-4 という画像を用意する。
  DiagonalCharacterIndexName = "$%s-X-%s"
  #----------------------------------------------------------------------------
  # ◆走行状態をダッシュのデフォルトにするを使用するか
  DashDefaultDash = true  # true / false
  #
  # 設定した番号のスイッチがONの時は歩行がデフォルトになる(0の場合は常にOFF)
  DashDefaultWalk = 0     # スイッチ番号
  #----------------------------------------------------------------------------
  # ◆プレイヤーの移動操作禁止を使用するか
  PlayerImpossibleOperation = true  # true / false
  #
  # 設定した番号のスイッチがONの時はプレイヤーの移動操作を禁止(0の場合は常にOFF)
  MoveByInputProhibition = 0        # スイッチ番号
  #----------------------------------------------------------------------------
  # ◆斜めの通行可能判定をオートタイル(A1タイル)を考慮したものに変更を使用するか
  DiagonalMoveNatural = true  # true / false
  #
  # 斜め通過を許可する地形タグ(A1タイルに設定した場合は元々が許可なので禁止に)
  # ここで設定した地形タグを設定したタイルは斜め通過を許可(A1タイルは禁止)する。
  DiagonalMoveNaturalTag = [] # 例 [1, 2, 5]
  #----------------------------------------------------------------------------
end
 
###############################################################################
# ■ プレイヤーの8方向移動に関する変更
###############################################################################
if Calt::DiagonalMovePlayer
#==============================================================================
# ■ Game_CharacterBase
#------------------------------------------------------------------------------
#  キャラクターを扱う基本のクラスです。全てのキャラクターに共通する、座標やグ
# ラフィックなどの基本的な情報を保持します。
#==============================================================================
class Game_CharacterBase
  #--------------------------------------------------------------------------
  # ● キャラクターの斜め画像の有無を取得 [新規]
  #--------------------------------------------------------------------------
  def character_diagonal
    return false
  end
end
 
#==============================================================================
# ■ Game_Player
#------------------------------------------------------------------------------
#  プレイヤーを扱うクラスです。イベントの起動判定や、マップのスクロールなどの
# 機能を持っています。このクラスのインスタンスは $game_player で参照されます。
#==============================================================================
class Game_Player < Game_Character
  #--------------------------------------------------------------------------
  # ● 方向ボタン入力による移動処理 [◆再定義]
  #--------------------------------------------------------------------------
  def move_by_input
    return if !movable? || $game_map.interpreter.running?
    if $game_switches[Calt::DiagonalMoveProhibition]
      move_4_way  # 斜め移動を禁止のスイッチがON (4方向移動)
    else
      move_8_way  # 斜め移動を禁止のスイッチがOFF(8方向移動)
    end
  end
  #--------------------------------------------------------------------------
  # ● 4方向移動の処理 [新規]
  #--------------------------------------------------------------------------
  def move_4_way
    if Calt::ChangeTurnModeKey && Input.press?(Calt::ChangeTurnModeKey)
      set_direction(Input.dir4) if Input.dir4 > 0 # 方向転換
    else
      move_straight(Input.dir4) if Input.dir4 > 0 # 移動処理
    end
  end
  #--------------------------------------------------------------------------
  # ● 8方向移動の処理 [新規]
  #--------------------------------------------------------------------------
  def move_8_way
    if Calt::ChangeTurnModeKey && Input.press?(Calt::ChangeTurnModeKey)
      if character_diagonal
        # 方向転換(斜め画像あり)
        if Input.dir8 > 0
          if Calt::DiagonalMoveOnlyKey && Input.press?(Calt::DiagonalMoveOnlyKey)
            set_direction(Input.dir8) if Input.dir8 % 2 == 1  # 方向転換(斜めのみ)
          else
            set_direction(Input.dir8)                         # 方向転換8方向
          end
        end
      else
        set_direction(Input.dir4) if Input.dir4 > 0 # 方向転換(斜め画像なし)
      end
    else
      # 移動処理8方向
      if (d = Input.dir8) > 0
        case d
        when 1 ; move_diagonal_select(4, 2)
        when 3 ; move_diagonal_select(6, 2)
        when 7 ; move_diagonal_select(4, 8)
        when 9 ; move_diagonal_select(6, 8)
        else
          # 移動処理4方向
          unless Calt::DiagonalMoveOnlyKey && Input.press?(Calt::DiagonalMoveOnlyKey)
            move_straight(d)
          end
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● 滑り移動の有無を判定して適当な方の斜め移動を実行 [新規]
  #--------------------------------------------------------------------------
  def move_diagonal_select(horz, vert)
    if $game_switches[Calt::DiagonalMoveSlide] ||
       Calt::DiagonalMoveOnlyKey && Input.press?(Calt::DiagonalMoveOnlyKey)
      move_diagonal(horz, vert)       # 滑り移動は無効
    else
      move_diagonal_slide(horz, vert) # 滑り移動は有効
    end
  end
  #--------------------------------------------------------------------------
  # ● 移動成功か判定(滑り移動付き斜めに移動の処理用) [新規]
  #--------------------------------------------------------------------------
  def move_succeed_slide?
    return true if @move_succeed                  # 普通に移動成功の場合
    return true if $game_map.any_event_starting?  # イベントを起動準備中の場合
    return true if $game_map.interpreter.running? # イベントを実行中の場合
    return false
  end
  #--------------------------------------------------------------------------
  # ● 滑り移動付き斜めに移動(プレイヤー操作専用) [新規]
  #--------------------------------------------------------------------------
  def move_diagonal_slide(horz, vert, turn_ok = true)
    old_direction = @direction  # 現在の向きを記憶
    if Calt::DiagonalCharacterGraphic
      move_diagonal(horz, vert, turn_ok)  # 斜めグラを使用する場合
    else
      move_diagonal(horz, vert)           # 斜めグラを使用しない場合
    end
    new_direction = @direction  # 新しい向きを記憶
    unless move_succeed_slide?
      if old_direction == 2 || old_direction == 8
        direction1 = horz  # 現在、縦の場合は横優先
        direction2 = vert
      elsif old_direction == 4 || old_direction == 6
        direction1 = vert  # 現在、横の場合は縦優先
        direction2 = horz
      else
        direction1 = vert  # 現在、斜めの場合は縦優先
        direction2 = horz
      end
      if passable?(x, y, direction1)
        move_straight(direction1, turn_ok)  # 移動可能なので移動
        #@direction = new_direction if Calt::DiagonalCharacterGraphic  # 向きを斜めに戻す
      elsif passable?(x, y, direction2)
        move_straight(direction2, turn_ok)  # 移動可能なので移動
        #@direction = new_direction if Calt::DiagonalCharacterGraphic  # 向きを斜めに戻す
      else
        # 縦横ともに移動不可なのでイベントの起動を試行
        move_straight(direction1, turn_ok)
        move_straight(direction2, turn_ok) unless move_succeed_slide?
        # 縦横ともに起動不可の場合は向きを戻す
        @direction = new_direction unless move_succeed_slide?
      end
    end
  end
end
end
 
###############################################################################
# ■ 斜め歩行グラフィックに関する変更
###############################################################################
if Calt::DiagonalCharacterGraphic
#==============================================================================
# ■ Game_Map
#------------------------------------------------------------------------------
#  マップを扱うクラスです。スクロールや通行可能判定などの機能を持っています。
# このクラスのインスタンスは $game_map で参照されます。
#==============================================================================
class Game_Map
  #--------------------------------------------------------------------------
  # ● 特定の方向に 1 マスずらした X 座標の計算(ループ補正なし)[追加]
  #--------------------------------------------------------------------------
  alias x_with_direction_MoveSystems x_with_direction
  def x_with_direction(x, d)
    d = d == 1 || d == 7 ? 4 : 6 if d % 2 == 1 && d != 5 # dをx方向に変換
    x_with_direction_MoveSystems(x, d)
  end
  #--------------------------------------------------------------------------
  # ● 特定の方向に 1 マスずらした Y 座標の計算(ループ補正なし)[追加]
  #--------------------------------------------------------------------------
  alias y_with_direction_MoveSystems y_with_direction
  def y_with_direction(y, d)
    d = d == 1 || d == 3 ? 2 : 8 if d % 2 == 1 && d != 5 # dをy方向に変換
    y_with_direction_MoveSystems(y, d)
  end
  #--------------------------------------------------------------------------
  # ● 特定の方向に 1 マスずらした X 座標の計算(ループ補正あり)[追加]
  #--------------------------------------------------------------------------
  alias round_x_with_direction_MoveSystems round_x_with_direction
  def round_x_with_direction(x, d)
    d = d == 1 || d == 7 ? 4 : 6 if d % 2 == 1 && d != 5 # dをx方向に変換
    round_x_with_direction_MoveSystems(x, d)
  end
  #--------------------------------------------------------------------------
  # ● 特定の方向に 1 マスずらした Y 座標の計算(ループ補正あり)[追加]
  #--------------------------------------------------------------------------
  alias round_y_with_direction_MoveSystems round_y_with_direction
  def round_y_with_direction(y, d)
    d = d == 1 || d == 3 ? 2 : 8 if d % 2 == 1 && d != 5 # dをy方向に変換
    round_y_with_direction_MoveSystems(y, d)
  end
  #--------------------------------------------------------------------------
  # ● 通常キャラの通行可能判定 [追加]
  #--------------------------------------------------------------------------
  alias passable_MoveSystems? passable?
  def passable?(x, y, d, *args)
    if d % 2 == 1 && d != 5
      horz = d == 1 || d == 7 ? 4 : 6
      vert = d == 1 || d == 3 ? 2 : 8
      x2 = round_x_with_direction(x, horz)
      y2 = round_y_with_direction(y, vert)
      return (passable_MoveSystems?(x, y, vert, *args) &&
              passable_MoveSystems?(x, y2, 10 - vert, *args) &&
              passable_MoveSystems?(x, y2, horz, *args)) ||
             (passable_MoveSystems?(x, y, horz, *args) &&
              passable_MoveSystems?(x2, y, 10 - horz, *args) &&
              passable_MoveSystems?(x2, y, vert, *args))
    else
      return passable_MoveSystems?(x, y, d, *args)
    end
  end
end
 
#==============================================================================
# ■ Game_CharacterBase
#------------------------------------------------------------------------------
#  キャラクターを扱う基本のクラスです。全てのキャラクターに共通する、座標やグ
# ラフィックなどの基本的な情報を保持します。
#==============================================================================
class Game_CharacterBase
  #--------------------------------------------------------------------------
  # ● 公開インスタンス変数
  #--------------------------------------------------------------------------
  attr_reader :character_diagonal  # キャラクターの斜め画像の有無を取得
                                   # ■変数への直接アクセスによる取得は禁止■
  #--------------------------------------------------------------------------
  # ● 公開メンバ変数の初期化 [追加]
  #--------------------------------------------------------------------------
  alias init_public_members_MoveSystems init_public_members
  def init_public_members
    init_public_members_MoveSystems
    @character_diagonal = false
  end
  #--------------------------------------------------------------------------
  # ● 斜め向きか判定 [新規]
  #--------------------------------------------------------------------------
  def direction_diagonal?(d = @direction)
    return d % 2 == 1 && d != 5
  end
  #--------------------------------------------------------------------------
  # ● 斜め画像の有無を設定 [新規]
  #--------------------------------------------------------------------------
  def set_character_diagonal(flag)
    @character_diagonal = flag
    unless @character_diagonal
      # 斜め向きの画像が無い場合の処理
      if direction_diagonal?
        @direction = @direction > 5 ? 8 : 2
      end
      if direction_diagonal?(@prelock_direction)
        @prelock_direction = @prelock_direction > 5 ? 8 : 2
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● 指定方向に向き変更 [◆再定義]
  #--------------------------------------------------------------------------
  def set_direction(d)
    if character_diagonal || !direction_diagonal?(d)
      @direction = d if !@direction_fix && d != 0
    elsif !@direction_fix && d != 0
      @direction = d > 5 ? 8 : 2
    end
    @stop_count = 0
  end
  #--------------------------------------------------------------------------
  # ● 通行可能判定 [追加]
  #--------------------------------------------------------------------------
  alias passable_MoveSystems? passable?
  def passable?(x, y, d)
    if direction_diagonal?(d)
      horz = d == 1 || d == 7 ? 4 : 6
      vert = d == 1 || d == 3 ? 2 : 8
      diagonal_passable?(x, y, horz, vert)  # 斜め向きの時は斜めの判定を実行
    else
      passable_MoveSystems?(x, y, d)
    end
  end
  #--------------------------------------------------------------------------
  # ● まっすぐに移動 [追加]
  #--------------------------------------------------------------------------
  alias move_straight_MoveSystems move_straight
  def move_straight(d, turn_ok = true)
    if direction_diagonal?(d)
      horz = d == 1 || d == 7 ? 4 : 6
      vert = d == 1 || d == 3 ? 2 : 8
      move_diagonal(horz, vert, turn_ok) # 斜め向きの時は斜め移動を実行
    else
      move_straight_MoveSystems(d, turn_ok)
    end
  end
  #--------------------------------------------------------------------------
  # ● 斜めに移動 [◆再定義]
  #--------------------------------------------------------------------------
  def move_diagonal(horz, vert, turn_ok = true) # 向き変更の可否を追加
    @move_succeed = diagonal_passable?(x, y, horz, vert)
    if @move_succeed
      set_direction_diagonal(horz, vert)  # 向き変更
      @x = $game_map.round_x_with_direction(@x, horz)
      @y = $game_map.round_y_with_direction(@y, vert)
      @real_x = $game_map.x_with_direction(@x, reverse_dir(horz))
      @real_y = $game_map.y_with_direction(@y, reverse_dir(vert))
      increase_steps
    elsif turn_ok
      set_direction_diagonal(horz, vert)  # 向き変更
      check_event_trigger_touch_front if character_diagonal  # 斜め画像がある
    end
  end
  #--------------------------------------------------------------------------
  # ● 向きの変更(斜め向き) [新規]
  #--------------------------------------------------------------------------
  def set_direction_diagonal(horz, vert)
    if character_diagonal
      d = horz == 4 ? (vert == 2 ? 1 : 7) : (vert == 2 ? 3 : 9)
      set_direction(d)  # 斜め画像があれば斜めを向く
    else
      set_direction(horz) if @direction == reverse_dir(horz)
      set_direction(vert) if @direction == reverse_dir(vert)
    end
  end
end
 
#==============================================================================
# ■ Game_Character
#------------------------------------------------------------------------------
#  主に移動ルートなどの処理を追加したキャラクターのクラスです。Game_Player、
# Game_Follower、GameVehicle、Game_Event のスーパークラスとして使用されます。
#==============================================================================
class Game_Character < Game_CharacterBase
  #--------------------------------------------------------------------------
  # ● 距離に最適な向きを向く [新規]
  #--------------------------------------------------------------------------
  def set_diagonal_distance_xy_from(sx, sy)
    # distance_x_from, distance_y_fromの返り値をそれぞれsx, syに入れて使う。
    sxabs = sx.abs
    syabs = sy.abs
    if sx == 0 || sy == 0 || (sxabs - syabs).abs * 2 >= sxabs + syabs
      if sxabs > syabs
        set_direction(sx > 0 ? 4 : 6)
      elsif sy != 0
        set_direction(sy > 0 ? 8 : 2)
      end
    else
      set_direction_diagonal(sx > 0 ? 4 : 6, sy > 0 ? 8 : 2)
    end
  end
  #--------------------------------------------------------------------------
  # ● ジャンプ [追加]
  #--------------------------------------------------------------------------
  alias jump_MoveSystems jump
  def jump(x_plus, y_plus)
    jump_MoveSystems(x_plus, y_plus)
    set_diagonal_distance_xy_from(-x_plus, -y_plus) if character_diagonal
  end
  #--------------------------------------------------------------------------
  # ● キャラクターに近づく(斜め移動可) [追加]
  #--------------------------------------------------------------------------
  alias move_toward_character_MoveSystems move_toward_character
  def move_toward_character(character)
    return move_toward_character_MoveSystems(character) unless character_diagonal
    sx = distance_x_from(character.x)
    sy = distance_y_from(character.y)
    if sx == 0 || sy == 0
      if sx.abs > sy.abs
        move_straight(sx > 0 ? 4 : 6)
        move_straight(sy > 0 ? 8 : 2) if !@move_succeed && sy != 0
      elsif sy != 0
        move_straight(sy > 0 ? 8 : 2)
        move_straight(sx > 0 ? 4 : 6) if !@move_succeed && sx != 0
      end
    else
      move_diagonal(sx > 0 ? 4 : 6, sy > 0 ? 8 : 2)
      if !@move_succeed
        if sx.abs > sy.abs
          move_straight(sx > 0 ? 4 : 6)
          move_straight(sy > 0 ? 8 : 2) if !@move_succeed && sy != 0
        elsif sy != 0
          move_straight(sy > 0 ? 8 : 2)
          move_straight(sx > 0 ? 4 : 6) if !@move_succeed && sx != 0
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● キャラクターから遠ざかる(斜め移動可) [追加]
  #--------------------------------------------------------------------------
  alias move_away_from_character_MoveSystems move_away_from_character
  def move_away_from_character(character)
    return move_away_from_character_MoveSystems(character) unless character_diagonal
    sx = distance_x_from(character.x)
    sy = distance_y_from(character.y)
    if sx == 0 || sy == 0
      if sx.abs > sy.abs
        move_straight(sx > 0 ? 6 : 4)
        move_straight(sy > 0 ? 2 : 8) if !@move_succeed && sy != 0
      elsif sy != 0
        move_straight(sy > 0 ? 2 : 8)
        move_straight(sx > 0 ? 6 : 4) if !@move_succeed && sx != 0
      end
    else
      move_diagonal(sx > 0 ? 6 : 4, sy > 0 ? 2 : 8)
      if !@move_succeed
        if sx.abs > sy.abs
          move_straight(sx > 0 ? 6 : 4)
          move_straight(sy > 0 ? 2 : 8) if !@move_succeed && sy != 0
        elsif sy != 0
          move_straight(sy > 0 ? 2 : 8)
          move_straight(sx > 0 ? 6 : 4) if !@move_succeed && sx != 0
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● キャラクターの方を向く(斜め向き可) [追加]
  #--------------------------------------------------------------------------
  alias turn_toward_character_MoveSystems turn_toward_character
  def turn_toward_character(character)
    return turn_toward_character_MoveSystems(character) unless character_diagonal
    sx = distance_x_from(character.x)
    sy = distance_y_from(character.y)
    set_diagonal_distance_xy_from(sx, sy)
  end
  #--------------------------------------------------------------------------
  # ● キャラクターの逆を向く(斜め向き可) [追加]
  #--------------------------------------------------------------------------
  alias turn_away_from_character_MoveSystems turn_away_from_character
  def turn_away_from_character(character)
    return turn_away_from_character_MoveSystems(character) unless character_diagonal
    sx = distance_x_from(character.x)
    sy = distance_y_from(character.y)
    set_diagonal_distance_xy_from(-sx, -sy)
  end
  #--------------------------------------------------------------------------
  # ● 右に 90 度回転 [◆再定義]
  #--------------------------------------------------------------------------
  def turn_right_90
    case @direction
    when 2;  set_direction(4)
    when 4;  set_direction(8)
    when 6;  set_direction(2)
    when 8;  set_direction(6)
    when 1;  set_direction(7)
    when 3;  set_direction(1)
    when 7;  set_direction(9)
    when 9;  set_direction(3)
    end
  end
  #--------------------------------------------------------------------------
  # ● 左に 90 度回転 [◆再定義]
  #--------------------------------------------------------------------------
  def turn_left_90
    case @direction
    when 2;  set_direction(6)
    when 4;  set_direction(2)
    when 6;  set_direction(8)
    when 8;  set_direction(4)
    when 1;  set_direction(3)
    when 3;  set_direction(9)
    when 7;  set_direction(1)
    when 9;  set_direction(7)
    end
  end
  #--------------------------------------------------------------------------
  # ● 右に 45 度回転 [新規]
  #--------------------------------------------------------------------------
  def turn_right_45
    return turn_right_90 unless character_diagonal
    case @direction
    when 1;  set_direction(4)
    when 2;  set_direction(1)
    when 3;  set_direction(2)
    when 4;  set_direction(7)
    when 6;  set_direction(3)
    when 7;  set_direction(8)
    when 8;  set_direction(9)
    when 9;  set_direction(6)
    end
  end
  #--------------------------------------------------------------------------
  # ● 左に 45 度回転 [新規]
  #--------------------------------------------------------------------------
  def turn_left_45
    return turn_left_90 unless character_diagonal
    case @direction
    when 1;  set_direction(2)
    when 2;  set_direction(3)
    when 3;  set_direction(6)
    when 4;  set_direction(1)
    when 6;  set_direction(9)
    when 7;  set_direction(4)
    when 8;  set_direction(7)
    when 9;  set_direction(8)
    end
  end
  #--------------------------------------------------------------------------
  # ● 右に 135 度回転 [新規]
  #--------------------------------------------------------------------------
  def turn_right_135
    return turn_right_90 unless character_diagonal
    case @direction
    when 1;  set_direction(8)
    when 2;  set_direction(7)
    when 3;  set_direction(4)
    when 4;  set_direction(9)
    when 6;  set_direction(1)
    when 7;  set_direction(6)
    when 8;  set_direction(3)
    when 9;  set_direction(2)
    end
  end
  #--------------------------------------------------------------------------
  # ● 左に 135 度回転 [新規]
  #--------------------------------------------------------------------------
  def turn_left_135
    return turn_left_90 unless character_diagonal
    case @direction
    when 1;  set_direction(6)
    when 2;  set_direction(9)
    when 3;  set_direction(8)
    when 4;  set_direction(3)
    when 6;  set_direction(7)
    when 7;  set_direction(2)
    when 8;  set_direction(1)
    when 9;  set_direction(4)
    end
  end
  #--------------------------------------------------------------------------
  # ● 右か左に 45 度回転 [新規]
  #--------------------------------------------------------------------------
  def turn_right_or_left_45
    case rand(2)
    when 0;  turn_right_45
    when 1;  turn_left_45
    end
  end
  #--------------------------------------------------------------------------
  # ● 右か左に 135 度回転 [新規]
  #--------------------------------------------------------------------------
  def turn_right_or_left_135
    case rand(2)
    when 0;  turn_right_135
    when 1;  turn_left_135
    end
  end
  #--------------------------------------------------------------------------
  # ● ランダムに方向転換(斜め向き可) [追加]
  #--------------------------------------------------------------------------
  alias turn_random_MoveSystems turn_random
  def turn_random
    return turn_random_MoveSystems unless character_diagonal
    d = 1 + rand(8)
    d += 1 if d > 4
    set_direction(d)
  end
  #--------------------------------------------------------------------------
  # ● ランダムに移動(斜め向き可) [追加]
  #--------------------------------------------------------------------------
  alias move_random_MoveSystems move_random
  def move_random
    return move_random_MoveSystems unless character_diagonal
    d = 1 + rand(8)
    d += 1 if d > 4
    move_straight(d, false)
  end
end
 
#==============================================================================
# ■ Game_Player
#------------------------------------------------------------------------------
#  プレイヤーを扱うクラスです。イベントの起動判定や、マップのスクロールなどの
# 機能を持っています。このクラスのインスタンスは $game_player で参照されます。
#==============================================================================
class Game_Player < Game_Character
  #--------------------------------------------------------------------------
  # ● 歩行グラフィック 斜め画像の有無を取得 [新規]
  #--------------------------------------------------------------------------
  def character_diagonal
    return @character_diagonal if @vehicle_type == :walk  # 歩行の場合は通常通り
    # プレイヤーに斜め画像が無い場合は処理が面倒なので乗り物に斜め画像があっても無効
    return @character_diagonal && vehicle.character_diagonal # 乗り物に搭乗中はその乗り物
  end
  #--------------------------------------------------------------------------
  # ● 斜めに移動 [◆再定義]
  #--------------------------------------------------------------------------
  def move_diagonal(horz, vert, turn_ok = true) # 向き変更の可否を追加
    @followers.move if diagonal_passable?(@x, @y, horz, vert)
    super
  end
end
 
#==============================================================================
# ■ Game_Event
#------------------------------------------------------------------------------
#  イベントを扱うクラスです。条件判定によるイベントページ切り替えや、並列処理
# イベント実行などの機能を持っており、Game_Map クラスの内部で使用されます。
#==============================================================================
class Game_Event < Game_Character
  #--------------------------------------------------------------------------
  # ● 公開インスタンス変数
  #--------------------------------------------------------------------------
  attr_accessor :diagonal_dont_start      # 斜め向きでのイベント起動不可
  #--------------------------------------------------------------------------
  # ● 公開メンバ変数の初期化 [追加]
  #--------------------------------------------------------------------------
  alias init_public_members_MoveSystems2 init_public_members
  def init_public_members
    init_public_members_MoveSystems2
    @diagonal_dont_start = false
  end
  #--------------------------------------------------------------------------
  # ● 斜め向きでのイベント起動不可か判定 [新規]
  #--------------------------------------------------------------------------
  def diagonal_dont_start?
    event_result = event_note_include?(Calt::DiagonalNotStartNote)
    whole_result = whole_note_include?(Calt::DiagonalNotStartAllNote)
    return event_result ^ whole_result ^ Calt::DiagonalNotStartReverse
  end
  #--------------------------------------------------------------------------
  # ● 注釈から設定を取得する処理 [追加]
  #--------------------------------------------------------------------------
  alias setup_page_settings_MoveSystems setup_page_settings
  def setup_page_settings
    setup_page_settings_MoveSystems
    @diagonal_dont_start = diagonal_dont_start?
  end
  unless $imported[:CanariAlternate_EventEveryone]
    #--------------------------------------------------------------------------
    # ● イベント起動 [追加]
    #--------------------------------------------------------------------------
    alias start_MoveSystems start
    def start
      return if $game_player.direction_diagonal? && @diagonal_dont_start
      start_MoveSystems
    end
  else
    #--------------------------------------------------------------------------
    # ● イベント起動(イベント起動判定拡張との競合回避バージョン) [追加]
    #--------------------------------------------------------------------------
    alias start_MoveSystems start
    def start
      @invoker_event ||= $game_player # 明示されてない場合はプレイヤーが実行者
      if @invoker_event.direction_diagonal? && @diagonal_dont_start
        @invoker_event = nil if @invoker_event  # 処理終了時に初期化
        return
      end
      start_MoveSystems
    end
  end
end
 
#==============================================================================
# ■ Sprite_Character
#------------------------------------------------------------------------------
#  キャラクター表示用のスプライトです。Game_Character クラスのインスタンスを
# 監視し、スプライトの状態を自動的に変化させます。
#==============================================================================
class Sprite_Character < Sprite_Base
  #--------------------------------------------------------------------------
  # ● 転送元ビットマップの更新 [◆再定義]
  #--------------------------------------------------------------------------
  def update_bitmap
    if graphic_changed?
      @tile_id = @character.tile_id
      @character_name = @character.character_name
      @character_index = @character.character_index
      if @tile_id > 0
        set_tile_bitmap
        @cross_character_name = nil  # 初期化
        @character.set_character_diagonal(false)  # 斜め画像無しを設定
      else
        set_character_bitmap
        @cross_character_name = get_cross_character_name # 斜め向き画像名の取得
      end
      @cross_bitmap = false  # 初期化
    end
  end
  #--------------------------------------------------------------------------
  # ● 斜め向き画像名の取得 [新規]
  #--------------------------------------------------------------------------
  def get_cross_character_name
    if @character_name =~ /^\!?\$./
      setting = Calt::DiagonalCharacterName
      cross_name = sprintf(setting, @character_name)
    else
      setting = Calt::DiagonalCharacterIndexName
      index = @character.character_index
      cross_name = sprintf(setting, @character_name, index + 1)
    end
    begin
      Cache.character(cross_name) # 取得を試みて失敗なら斜め画像は存在しない
    rescue
      @character.set_character_diagonal(false)  # 斜め画像無しを設定
      return nil
    end
    @character.set_character_diagonal(true) # 斜め画像有りを設定
    return cross_name
  end
  #--------------------------------------------------------------------------
  # ● 斜め向きキャラクターのビットマップを設定 [新規]
  #--------------------------------------------------------------------------
  def set_cross_character_bitmap
    unless @cross_character_name
      p "エラー:斜め向き画像が存在しないキャラが斜め向きになっています!!"
      return
    end
    self.bitmap = Cache.character(@cross_character_name)
    @cw = bitmap.width / 3
    @ch = bitmap.height / 4
    self.ox = @cw / 2
    self.oy = @ch
  end
  #--------------------------------------------------------------------------
  # ● 転送元矩形の更新 [◆再定義]
  #--------------------------------------------------------------------------
  def update_src_rect
    if @tile_id == 0
      d = @character.direction
      if @character.direction_diagonal?
        index = 0
        unless @cross_bitmap
          set_cross_character_bitmap  # 斜め向き画像をセット
          @cross_bitmap = true
        end
        d = case d
        when 1; 2 # 左斜め下(1行目)
        when 7; 4 # 左斜め上(2行目)
        when 3; 6 # 右斜め下(3行目)
        when 9; 8 # 右斜め上(4行目)
        end
      else
        index = @character.character_index
        if @cross_bitmap
          set_character_bitmap  # 通常の画像をセット
          @cross_bitmap = false
        end
      end
      pattern = @character.pattern < 3 ? @character.pattern : 1
      sx = (index % 4 * 3 + pattern) * @cw
      sy = (index / 4 * 4 + (d - 2) / 2) * @ch
      self.src_rect.set(sx, sy, @cw, @ch)
    end
  end
end
end
 
###############################################################################
# ■ 走行状態をダッシュのデフォルトにするに関する変更
###############################################################################
if Calt::DashDefaultDash
#==============================================================================
# ■ Game_Player
#------------------------------------------------------------------------------
#  プレイヤーを扱うクラスです。イベントの起動判定や、マップのスクロールなどの
# 機能を持っています。このクラスのインスタンスは $game_player で参照されます。
#==============================================================================
class Game_Player < Game_Character
  #--------------------------------------------------------------------------
  # ● ダッシュ状態判定 [◆再定義]
  #--------------------------------------------------------------------------
  def dash?
    return false if @move_route_forcing || $game_map.disable_dash? || vehicle
    return Input.press?(:A) ^ !$game_switches[Calt::DashDefaultWalk]
  end
end
end
 
###############################################################################
# ■ プレイヤーの移動操作禁止に関する変更
###############################################################################
if Calt::PlayerImpossibleOperation
#==============================================================================
# ■ Game_Player
#------------------------------------------------------------------------------
#  プレイヤーを扱うクラスです。イベントの起動判定や、マップのスクロールなどの
# 機能を持っています。このクラスのインスタンスは $game_player で参照されます。
#==============================================================================
class Game_Player < Game_Character
  #--------------------------------------------------------------------------
  # ● ダッシュ状態判定 [追加]
  #--------------------------------------------------------------------------
  alias dash_MoveSystems? dash?
  def dash?
    return false if $game_switches[Calt::MoveByInputProhibition]
    return dash_MoveSystems?
  end
  #--------------------------------------------------------------------------
  # ● 方向ボタン入力による移動処理 [追加]
  #--------------------------------------------------------------------------
  alias move_by_input_MoveSystems move_by_input
  def move_by_input
    return if $game_switches[Calt::MoveByInputProhibition]
    move_by_input_MoveSystems
  end
end
end
 
###############################################################################
# ■ 斜めの通行可能判定をオートタイル(A1タイル)を考慮したものに変更に関する変更
###############################################################################
if Calt::DiagonalMoveNatural
#==============================================================================
# ■ Game_CharacterBase
#------------------------------------------------------------------------------
#  キャラクターを扱う基本のクラスです。全てのキャラクターに共通する、座標やグ
# ラフィックなどの基本的な情報を保持します。
#==============================================================================
class Game_CharacterBase
  #--------------------------------------------------------------------------
  # ● 定数
  #--------------------------------------------------------------------------
  AutoTile_UpLeft    = {34=>:T, 35=>:T, 42=>:T, 43=>:T, 46=>:T} # 左上が通行可のパターン
  AutoTile_UpRight   = {36=>:T, 37=>:T, 42=>:T, 45=>:T, 46=>:T} # 右上が通行可のパターン
  AutoTile_DownLeft  = {40=>:T, 41=>:T, 43=>:T, 44=>:T, 46=>:T} # 左下が通行可のパターン
  AutoTile_DownRight = {38=>:T, 39=>:T, 44=>:T, 45=>:T, 46=>:T} # 右下が通行可のパターン
  #--------------------------------------------------------------------------
  # ● 斜めの通行可能判定 [◆再定義]
  #--------------------------------------------------------------------------
  def diagonal_passable?(x, y, horz, vert)
    x2 = $game_map.round_x_with_direction(x, horz)
    y2 = $game_map.round_y_with_direction(y, vert)
    route_vert = passable?(x, y, vert) && passable?(x, y2, horz)  # 縦横ルート
    route_horz = passable?(x, y, horz) && passable?(x2, y, vert)  # 横縦ルート
    return true if route_vert && route_horz # 全ルート通行可能
    if map_passable?(x, y, horz) && map_passable?(x, y, vert) &&
       map_passable?(x2, y2, reverse_dir(horz)) &&
       map_passable?(x2, y2, reverse_dir(vert)) &&
       !collide_with_characters?(x2, y2)
      # 現在地と移動先は斜めに通行可
      if route_vert || passable_tile?(x, y2, horz, vert, false)
        if route_horz || passable_tile?(x2, y, horz, vert, true)
          return true
        end
      end
    end
    return false # 通行不可
  end
  #--------------------------------------------------------------------------
  # ● 斜めの通行可能判定(タイル判定) [新規]
  #--------------------------------------------------------------------------
  def passable_tile?(x, y, horz, vert, route_horz=false)
    $game_map.all_tiles(x, y).each do |tile_id|
      flag = $game_map.tileset.flags[tile_id]
      next if flag & 0x10 != 0          # [☆] : 通行に影響しない
      if tile_id.between?(2048, 2815)   # A1タイル(海・水辺など)
        return false if Calt::DiagonalMoveNaturalTag.include?(flag >> 12) # 通行不可
        auto_id = (tile_id - 2048) % 48 # オートタイルのパターンを取得
        auto_id_list = auto_id_list_A1_tile(horz, vert, route_horz)
        return false unless auto_id_list[auto_id] # 通行不可
      else
        unless diagonal_passable_tile?(flag, horz, vert, route_horz)
          return false unless Calt::DiagonalMoveNaturalTag.include?(flag >> 12) # 通行不可
        end
      end
      return false if collide_with_characters?(x, y) # イベントとの衝突判定
      return true # 通行可
    end
    return false  # 通行不可
  end
  #--------------------------------------------------------------------------
  # ● 通行可能なA1タイルの配列を取得 [新規]
  #--------------------------------------------------------------------------
  def auto_id_list_A1_tile(horz, vert, route_horz)
    if horz == 4 # 方向とルートに対応する通行可のパターンを取得
      if vert == 2
        return route_horz ? AutoTile_DownRight : AutoTile_UpLeft
      else
        return route_horz ? AutoTile_UpRight : AutoTile_DownLeft
      end
    else
      if vert == 2
        return route_horz ? AutoTile_DownLeft : AutoTile_UpRight
      else
        return route_horz ? AutoTile_UpLeft : AutoTile_DownRight
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● 斜め通行可能なタイルか判定 [新規]
  #--------------------------------------------------------------------------
  def diagonal_passable_tile?(flag, horz, vert, route_horz)
    corner_flag = if horz == 4
      vert == 2 ? (route_horz ? 0x05 : 0x0a) : (route_horz ? 0x0c : 0x03)
    else
      vert == 2 ? (route_horz ? 0x03 : 0x0c) : (route_horz ? 0x0a : 0x05)
    end
    return flag & corner_flag == 0x00 ? true : false
  end
end
end