地上の洞窟

どこにも行かず、液晶と「にらめっこ」し続ける人の物語。

【RGSS3】トラベルポイント

トラベルポイントUI
知ってる場所へテレポートができる(ルーラ!

登録された場所へテレポートする画面を追加します。
(動作には「CraftLib」スクリプトが必要です)

スクリプトコマンド一覧

TravelPoint.set(map_id, x, y, name = nil)

マップID、X座標、Y座標、登録名(任意)を指定して、テレポート先を登録します。

TravelPoint.set(6, 21, 33)
TravelPoint.set_player(name = nil)

プレイヤーが現在いる位置をテレポート先として登録します。

TravelPoint.set_player("現在地")
TravelPoint.set_player_target_direction(direction, name = nil)

現在プレイヤーがいる位置から、一歩進んだ地点より、
direction方向に進んだ場所をテレポート先として登録します。

TravelPoint.set_player_target_direction(2)
TravelPoint.delete(map_id, x, y, name)

指定したテレポート先の登録を削除します。
nilを指定した場合、その項目は検索対象にしません。

TravelPoint.delete(5, nil, nil, nil) # マップID:5の登録を全て削除
SceneManager.call(TravelPoint::Scene_TravelPoint)

テレポート先の表示・指定を行うシーンへと遷移します。

SceneManager.call(TravelPoint::Scene_TravelPoint)


更新履歴 バージョン 内容
2024/05/19 v1.0.0 初版

→スクリプト一覧へ


スクリプト(ダブルクリックで全選択)↓

=begin =========================================================================
 ■ 「トラベルポイント」- TravelPoint v1.0.0 by 地上の洞窟
================================================================================
  
  登録された場所へテレポートする画面を追加します。
  (動作には「CraftLib」スクリプトが必要です)

================================================================================
 ■ 仕様
================================================================================

  ・テレポート先はスクリプトコマンドなどで登録し、セーブデータごとに管理
  ・設定次第でテレポート先の指定のみ行い変数に記録し、
   別途イベントなどで場所移動の処理や演出などを行うことも可能
  ・同じテレポート先の複数回登録は重複

================================================================================
 ■ 機能説明
================================================================================

  本スクリプトは以下のスクリプトコマンドを
  イベントなどで実行することで使用できます。

  ・TravelPoint.set(map_id, x, y, name = nil)
  マップID、X座標、Y座標、登録名(任意)を指定して、テレポート先を登録します。
  例: TravelPoint.set(6, 21, 33)
  
  ・TravelPoint.set_player(name = nil)
  プレイヤーが現在いる位置をテレポート先として登録します。
  例: TravelPoint.set_player("現在地")

  ・TravelPoint.set_player_target_direction(direction, name = nil)
  現在プレイヤーがいる位置から、一歩進んだ地点より、
  direction方向に進んだ場所をテレポート先として登録します。
  例: TravelPoint.set_player_target_direction(2)
  
  ・TravelPoint.delete(map_id, x, y, name)
  指定したテレポート先の登録を削除します。
  nilを指定した場合、その項目は検索対象にしません。
  例: TravelPoint.delete(5, nil, nil, nil) # マップID:5の登録を全て削除

  ・SceneManager.call(TravelPoint::Scene_TravelPoint)
  テレポート先の表示・指定を行うシーンへと遷移します。

================================================================================
 ■ 設定項目
=end #==========================================================================

module TravelPoint

  #-----------------------------------------------------------------------------
  # □ 変数
  #-----------------------------------------------------------------------------

  # ● 移動先を選択した際、変数に移動先の情報を記録する
  USE_VARIABLES = true

  # ● 移動先のマップIDを記録する変数の番号
  VARIABLES_MAP_ID = 3

  # ● 移動先のX座標を記録する変数の番号
  VARIABLES_X = 4

  # ● 移動先のY座標を記録する変数の番号
  VARIABLES_Y = 5

  #-----------------------------------------------------------------------------
  # □ 即時テレポート
  #-----------------------------------------------------------------------------

  # ● 即時テレポートを有効にする
  # 移動先を選択した際、自動的に場所移動を行います
  INSTANT_TELEPORT = true

  # ● 即時テレポート後の向き
  # 8: ↑
  # 2: ↓
  # 4: ←
  # 6: →
  INSTANT_TELEPORT_DIRECTION = 2

  # ● 即時テレポート時の画面のフェードの方式
  # 場所移動の仕様に則します
  # 0: 通常
  # 1: 白
  # 2: なし
  INSTANT_TELEPORT_FADE_TYPE = 1

  #-----------------------------------------------------------------------------
  # □ 表示(移動先選択コマンド)
  #-----------------------------------------------------------------------------

  # ● 移動先選択コマンドの幅
  # プレビューの幅は画面幅からこのコマンドの幅を引いたものになる
  COMMAND_WIDTH = Graphics.width / 3

  # ● 移動先の並び順
  # 0: 登録順
  # 1: マップID順
  # 2: 名前順
  COMMAND_SORT_TYPE = 0

  #-----------------------------------------------------------------------------
  # □ 表示(マッププレビュー)
  #-----------------------------------------------------------------------------

  # ● マッププレビューを有効
  ENABLE_PREVIEW = true

  # ● マッププレビューを特別に描画しないマップのID
  PREVIEW_EXCLUDE = [1000, 1001]

  # ● マッププレビューを特別に描画しない場合のテキスト
  PREVIEW_NO_IMAGE = "NO IMAGE"

  # ● マッププレビューのマップ端補正のタイプ
  # 移動先がマップの端で、描画が見切れてしまう場合の修正方法
  # 0: 塗りつぶし(黒)
  # 1: 切り落とし
  # 2: 位置ずらし
  PREVIEW_EDGE_FIX_TYPE = 0

  #-----------------------------------------------------------------------------
  # □ 表示(マップ説明文)
  #-----------------------------------------------------------------------------

  # ● マップ説明文を有効
  ENABLE_DESCRIPTION = true

  # ● マップ説明文の表示高(px)

  DESCRIPTION_HEIGHT = 72

  # ● マップ説明文とマッププレビューの間に罫線を表示

  DESCRIPTION_HORZ = true

  # ● 罫線の高さ(px)

  DESCRIPTION_HORZ_WIDTH = 2

  # ● 罫線の上下マージン(px)
  # プレビューと説明文との間に「罫線の高さ + マージン * 2」分のスペースが出来る

  DESCRIPTION_HORZ_MARGIN = 11

  # ● マップIDに対応するマップ説明文
  # マップID => '',
  # 制御文字が使用可能、改行は\n

  DESCRIPTION = {
    12 => '世界の果てに位置する、未曽有の遺跡。\n富、名声、力。あと、お金。\nこの世の全てがそこに眠るという。',
    14 => '陽は穏やかで風は爽やかに。\n幾度の出会いと別れを見届ける、\n冒険者達の集う町。',
  }

  #-----------------------------------------------------------------------------
  # □ 表示(その他)
  #-----------------------------------------------------------------------------

  # ● ヘルプに表示するテキスト
  LIST_HELP_TEXT = "テレポート先を選択します。"

#===============================================================================
# ■ ここからソースコード
#===============================================================================

  class << self
    def set(map_id, x, y, name = nil)
      name ||= load_data(sprintf("Data/Map%03d.rvdata2", map_id)).display_name
      $game_system.travel_point_set(map_id, x, y, name)
    end

    def set_player(name = nil)
      set($game_map.map_id, $game_player.x, $game_player.y, name)
    end

    def set_player_target_direction(direction, name = nil)
      x2 = $game_map.round_x_with_direction(
        $game_map.round_x_with_direction($game_player.x, $game_player.direction),
        direction
      )
      
      y2 = $game_map.round_y_with_direction(
        $game_map.round_y_with_direction($game_player.y, $game_player.direction),
        direction
      )
      
      set($game_map.map_id, x2, y2, name)
    end

    def delete(map_id, x, y, name)
      $game_system.travel_point_delete(map_id, x, y, name)
    end
  end

  class Window_TravelPointList < Window_Command
    def initialize(travel_point_list)
      @travel_point_list = travel_point_list
      super(0, 0)
    end

    def visible_line_number
      10
    end

    def window_width
      COMMAND_WIDTH
    end
    
    def make_command_list
      @travel_point_list.each do |array|
        add_command(array[3], :command)
      end
      add_command(Vocab.cancel, :cancel)
    end

    def select(index)
      super(index)
      call_handler(:select)
    end

    def current_travel_point_data
      @travel_point_list[index]
    end

    def update_help
      @help_window.set_text(LIST_HELP_TEXT)
    end
  end

  class Window_TravelPointBack < Window_Base
    def initialize(x, y)
      super(x, y, Graphics.width - x, Graphics.height - y)
    end

    def preview_height
      ENABLE_PREVIEW ? contents.height - description_height : 0
    end

    def description_height
      ENABLE_DESCRIPTION ? description_horz_height + DESCRIPTION_HEIGHT : 0
    end

    def description_horz_height
      DESCRIPTION_HORZ ? DESCRIPTION_HORZ_WIDTH + DESCRIPTION_HORZ_MARGIN * 2 : 0
    end

    def map_id
      @map_id
    end

    def map_id=(id)
      @map_id = id
      refresh
    end

    def line_color
      color = normal_color
      color.alpha = 48
      color
    end

    def refresh
      contents.clear
      if ENABLE_PREVIEW
        if PREVIEW_EXCLUDE.include?(map_id)
          draw_text(
            0,
            preview_height / 2 - line_height / 2,
            contents.width,
            line_height,
            PREVIEW_NO_IMAGE,
            1
          )
        elsif PREVIEW_EDGE_FIX_TYPE == 0
          contents.fill_rect(0, 0, contents.width, preview_height, Color.new(0, 0, 0))
        end
      end

      if ENABLE_DESCRIPTION
        y = preview_height

        if DESCRIPTION_HORZ
          contents.fill_rect(
            0,
            y + DESCRIPTION_HORZ_MARGIN,
            contents.width,
            DESCRIPTION_HORZ_WIDTH,
            line_color
          )
          y += description_horz_height
        end

        if (text = DESCRIPTION[@map_id])
          text.split('\n').each do |str|
            draw_text_ex(4, y, str)
            y += line_height
          end
        end
      end
    end
  end

  class Scene_TravelPoint < CraftLib::Scene_MapViewer
    def start_map_id
      return @travel_point_list[0][0] unless @travel_point_list.empty?
      super
    end

    def start
      @travel_point_list = $game_system.travel_point_list
      super
      create_background
      create_help_window
      create_list_window
      create_back_window
      setup_map_viewport
      @list_window.select(0)
    end
    
    def terminate
      super
      dispose_background
    end

    def each_viewport
      @spriteset.instance_variables.each do |varname|
        (ivar = @spriteset.instance_variable_get(varname)).is_a?(Viewport) and yield ivar
      end
    end

    def setup_map_viewport
      each_viewport do |viewport|
        viewport.z += 1000
        viewport.rect.set(
          @back_window.x + @back_window.standard_padding,
          @back_window.y + @back_window.standard_padding,
          @back_window.contents.width,
          @back_window.preview_height,
        )
      end
    end

    def create_background
      @background_sprite = Sprite.new
      @background_sprite.bitmap = SceneManager.background_bitmap
      @background_sprite.color.set(16, 16, 16, 128)
    end

    def create_help_window
      @help_window = Window_Help.new(1)
      @help_window.viewport = @viewport
    end

    def create_list_window
      @list_window = Window_TravelPointList.new(@travel_point_list)
      @list_window.help_window = @help_window
      @list_window.viewport = @viewport
      @list_window.y = @help_window.height
      @list_window.set_handler(:select  , method(:on_list_select))
      @list_window.set_handler(:command , method(:on_list_ok))
      @list_window.set_handler(:cancel  , method(:return_scene))
    end

    def create_back_window
      @back_window = Window_TravelPointBack.new(
        @list_window.width,
        @help_window.height        
      )
      @back_window.viewport = @viewport
      @center_x = (@back_window.contents.width / 32.0 - 1) / 2.0
      @center_y = (@back_window.preview_height / 32.0 - 1) / 2.0
      @back_window_tile_x = @back_window.contents.width / 32.0
      @back_window_tile_y = @back_window.preview_height / 32.0
    end

    def dispose_background
      @background_sprite.bitmap.dispose
      @background_sprite.dispose
    end

    def on_list_select
      if (data = @list_window.current_travel_point_data)
        map_id, x, y = data
        $game_map.setup(map_id)
      else
        map_id = @last_game_map.map_id
        x = $game_player.x
        y = $game_player.y
      end

      setup_map(map_id)
      @back_window.map_id = map_id

      display_x = dxf = x - @center_x
      display_y = dyf = y - @center_y
      
      unless $game_map.loop_horizontal?
        (m = $game_map.width - @back_window_tile_x) < dxf and dxf = m
        dxf < 0 and dxf = 0
      end

      unless $game_map.loop_vertical?
        (m = $game_map.height - @back_window_tile_y) < display_y and dyf = m
        dyf < 0 and dyf = 0
      end

      delta_x = dxf - display_x
      delta_y = dyf - display_y

      px = (
        if delta_x < 0
          PREVIEW_EDGE_FIX_TYPE == 2 ? dxf : display_x
        else
          $game_map.loop_horizontal? ? display_x : dxf
        end
      )

      py = (
        if delta_y < 0
          PREVIEW_EDGE_FIX_TYPE == 2 ? dyf : display_y
        else
          $game_map.loop_vertical? ? display_y : dyf
        end
      )

      $game_map.force_display_pos(px, py)
      
      rx = @back_window.x + @back_window.standard_padding
      ry = @back_window.y + @back_window.standard_padding
      rw = @back_window.contents.width
      rh = @back_window.preview_height

      if PREVIEW_EDGE_FIX_TYPE != 2
        unless $game_map.loop_horizontal?
          if delta_x < 0
            rw += delta_x * 32
          end

          if delta_x > 0
            rx += (v = delta_x * 32)
            rw -= v
          end
        end

        unless $game_map.loop_vertical?
          if delta_y < 0
            rh += delta_y * 32
          end

          if delta_y > 0
            ry += (v = delta_y * 32)
            rh -= v
          end

        end
      end

      flag = !PREVIEW_EXCLUDE.include?(map_id)
      each_viewport do |viewport|
        viewport.rect.set(rx, ry, rw, rh)
        viewport.visible = flag
      end
      @spriteset.update
    end

    def on_list_ok
      if (data = @list_window.current_travel_point_data)
        map_id, x, y = data
        if INSTANT_TELEPORT
          $game_player.reserve_transfer(map_id, x, y, INSTANT_TELEPORT_DIRECTION)
          $game_temp.fade_type = INSTANT_TELEPORT_FADE_TYPE
        end

        if USE_VARIABLES
          $game_variables[VARIABLES_MAP_ID] = map_id
          $game_variables[VARIABLES_X] = x
          $game_variables[VARIABLES_Y] = y
        end
      end
      return_scene
    end
  end
end

class Game_System
  alias tvlp_initialize initialize
  def initialize
    tvlp_initialize
    @travel_point = []
  end

  def travel_point_set(map_id, x, y, name)
    @travel_point << [map_id, x, y, name]
  end

  def travel_point_delete(map_id, x, y, name)
    @travel_point.delete_if do |array|
      c_map_id, c_x, c_y, c_name = array
      (map_id ? c_map_id == map_id : true) &&
      (x ? c_x == x : true) &&
      (y ? c_y == y : true) &&
      (name ? c_name == name : true)
    end
  end

  def travel_point_list
    case TravelPoint::COMMAND_SORT_TYPE
    when 1 then travel_point_list_map_id
    when 2 then travel_point_list_name
    else @travel_point
    end
  end

  def travel_point_list_map_id
    @travel_point.sort_by { |array| array[0] }
  end

  def travel_point_list_name
    @travel_point.sort_by { |array| array[3] }
  end
end

class Game_Map
  def force_display_pos(x, y)
    @parallax_x = @display_x = x
    @parallax_y = @display_y = y
  end
end