저장

[KCG] 2 Pane Save Scene 번역본

by 백호 posted Feb 22, 2009
?

단축키

Prev이전 문서

Next다음 문서

ESC닫기

크게 작게 위로 아래로 댓글로 가기 인쇄
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#_/    ◆2 페인식 세이브 - KGC_2PaneSave◆
#_/----------------------------------------------------------------------------
#_/  2 페인식의 세이브 화면을 작성합니다.
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

#==============================================================================
# ★ 커스터마이즈 항목 ★
#==============================================================================

module KGC
  # ◆페이지수
  #  1 페이지에 대해 세이브 파일 4 개.
  #  너무 많으면 세이브/로드 화면의 표시가 늦어집니다.
  #  ※반드시 1 이상을 지정해 주세요.
  TPS_PAGE_NUMBER = 4
  # ◆파일 번호 서식
  #  【{i}..파일 번호】
  TPS_FILE_INDEX_FORMAT = "FILE {i}"

  # ◆멤버 리스트의 렬수(1~4)
  #  5 이상으로 한다고 표시가 입습니다.
  TPS_MEMBER_COLS = 3
  # ◆후보 멤버도 묘화
  #  ≪많은 사람 파티≫도입시만 유효.
  TPS_DRAW_ALL_MEMBER = true
end

#★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★

$imported = {} if $imported == nil
$imported["2PaneSave"] = true

#==============================================================================
# ■ Window_SaveFile
#==============================================================================

class Window_SaveFile < Window_Base
  attr_accessor :destination
  #--------------------------------------------------------------------------
  # ● 오브젝트 초기화
  #    file_index : 세이브 파일의 인덱스
  #    filename  : 파일명
  #--------------------------------------------------------------------------
  def initialize(file_index, filename)
    super(file_index * 160, 64, 160, 96)
    self.contents = Bitmap.new(width - 32, height - 32)
    @file_index = file_index
    @filename = "Save#{@file_index + 1}.rxdata"
    @time_stamp = Time.at(0)
    @file_exist = FileTest.exist?(@filename)
    if @file_exist
      file = File.open(@filename, "r")
      @time_stamp = file.mtime
      @frame_count = Marshal.load(file)
      unless @frame_count.is_a?(Integer)
        @frame_count = Marshal.load(file)
      end
      9.times { |i|  # 불필요한 개소를 읽어 날리는
        Marshal.load(file)
      }
      @total_sec = @frame_count / Graphics.frame_rate
      file.close
    end
    refresh
    @destination = self.x
    @selected = false
  end
  #--------------------------------------------------------------------------
  # ● 리프레쉬
  #--------------------------------------------------------------------------
  def refresh
    # MapInfo.rxdata 를 로드
    mapinfo = load_data("Data/MapInfos.rxdata")
    self.contents.clear
    # 파일 번호를 묘화
    self.contents.font.color = system_color
    name = KGC::TPS_FILE_INDEX_FORMAT.dup
    name.gsub!(/{i}/) { "#{@file_index + 1}" }
    self.contents.draw_text(4, 0, 120, 32, name)
    @name_width = contents.text_size(name).width
    # 세이브 파일이 존재하는 경우
    if @file_exist
      # 플레이 시간을 묘화
      hour = @total_sec / 60 / 60
      min = @total_sec / 60 % 60
      sec = @total_sec % 60
      time_string = sprintf("%02d:%02d:%02d", hour, min, sec)
      self.contents.font.color = normal_color
      self.contents.draw_text(4, 32, 120, 32, time_string)
    end
  end
  #--------------------------------------------------------------------------
  # ● 프레임 갱신
  #--------------------------------------------------------------------------
  def update
    super
    # 윈도우 이동
    if self.x != @destination
      if (self.x - @destination).abs < 12
        self.x = @destination
      else
        dist = (@destination - self.x) / 8
        if dist < 0
          dist = [dist, -12].min
        else
          dist = [dist, 12].max
        end
        self.x += dist
      end
    end
  end
end

#★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★

#==============================================================================
# ■ Window_SaveFileInfo
#------------------------------------------------------------------------------
#  파일의 정보를 표시하는 윈도우입니다.
#==============================================================================

class Window_SaveFileInfo < Window_Base
  #--------------------------------------------------------------------------
  # ● 오브젝트 초기화
  #--------------------------------------------------------------------------
  def initialize
    super(0, 160, 640, 320)
    self.contents = Bitmap.new(width - 32, height - 32)
    self.contents.font.size = 20
  end
  #--------------------------------------------------------------------------
  # ● 리프레쉬
  #    file_index : 세이브 파일의 인덱스
  #--------------------------------------------------------------------------
  def refresh(file_index)
    if @file_index == file_index
      return
    end
    self.contents.clear
    @file_index = file_index
    filename = "Save#{file_index + 1}.rxdata"
    if FileTest.exist?(filename)
      self.contents.font.color = normal_color
      self.contents.font.name = Font.default_name
      self.contents.font.size = 20
      self.contents.font.bold = Font.default_bold
      draw_file_info(filename)
    else
      self.contents.font.color = disabled_color
      self.contents.font.name = "Times New Roman"
      self.contents.font.size = 32
      self.contents.font.bold = true
      self.contents.draw_text(0, 112, 640, 64, "- NO DATA -", 1)
    end
  end
  #--------------------------------------------------------------------------
  # ● 파일 정보 묘화
  #    filename : 대상 파일명
  #--------------------------------------------------------------------------
  def draw_file_info(filename)
    file = File.open(filename, "r")
    time_stamp = file.mtime
    frame_count = Marshal.load(file)
    unless frame_count.is_a?(Integer)
      frame_count = Marshal.load(file)
    end
    game_system = Marshal.load(file)
    game_switches = Marshal.load(file)
    game_variables = Marshal.load(file)
    game_self_switches = Marshal.load(file)
    game_screen = Marshal.load(file)
    game_actors = Marshal.load(file)
    game_party = Marshal.load(file)
    game_troop = Marshal.load(file)
    game_map = Marshal.load(file)
    total_sec = frame_count / Graphics.frame_rate
    file.close
    # 캐릭터를 묘화
    actors = game_party.actors
    if $imported["LargeParty"] && !KGC::TPS_DRAW_ALL_MEMBER
      actors = game_party.battle_actors
    end
    actors.each_with_index { |actor, i|
      x = i / 5 * (608 / KGC::TPS_MEMBER_COLS)
      y = i % 5 * 48
      out = dead = false
      if $imported["LargeParty"] && !game_party.battle_actors.include?(actor)
        out = true
      elsif actor.dead?
        dead = true
      end
      image = RPG::Cache.character(actor.character_name, actor.character_hue)
      rect = Rect.new(0, 0, image.width >> 2, image.height >> 2)
      self.contents.blt(x, y, image, rect, out ? 128 : 255)
      self.contents.font.color = dead ? knockout_color : normal_color
      self.contents.draw_text(x + 40, y, 108, 24, actor.name)
      self.contents.font.color = system_color
      self.contents.draw_text(x + 40, y + 24, 32, 24, "Lv")
      self.contents.font.color = normal_color
      self.contents.draw_text(x + 72, y + 24, 64, 24, actor.level.to_s)
    }
    # 플레이 시간을 묘화
    hour = total_sec / 3600
    min = total_sec / 60 % 60
    sec = total_sec % 60
    time_string = sprintf("%02d:%02d:%02d", hour, min, sec)
    self.contents.font.color = system_color
    self.contents.draw_text(480, 240, 48, 24, "TIME")
    self.contents.font.color = normal_color
    self.contents.draw_text(528, 240, 80, 24, time_string, 2)
    # 타임 스탬프를 묘화
    time_string = time_stamp.strftime("%Y/%m/%d %H:%M")
    self.contents.draw_text(448, 264, 160, 24, time_string, 2)
    # 세이브 장소·임무를 묘화
    if $imported["PlaceMission"]
      mapinfo = load_data("Data/MapInfos.rxdata")
      place = ""
      # 맵명이 없는 경우
      if game_system.place == nil || game_system.place == ""
        # 맵명을 취득
        place = mapinfo[game_map.map_id].name
      else
        place = game_system.place
      end
      self.contents.font.color = system_color
      cx = self.contents.text_size("세이브 장소").width
      self.contents.draw_text(4, 240, cx, 24, "세이브 장소")
      self.contents.font.color = normal_color
      self.contents.draw_text(8 + cx, 240, 596 - cx, 24, place)
      self.contents.font.color = system_color
      cx = self.contents.text_size("임무").width
      self.contents.draw_text(4, 264, cx, 24, "임무")
      self.contents.font.color = normal_color
      self.contents.draw_text(8 + cx, 264, 596 - cx, 24, game_system.mission)
    end
  end
end

#★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★

#==============================================================================
# ■ Scene_Title
#==============================================================================

class Scene_Title
  #--------------------------------------------------------------------------
  # ● 프레임 갱신
  #--------------------------------------------------------------------------
  alias update_KGC_2PaneSave update
  def update
    # 콘티 뉴 판정
    unless @continue_checked
      found = false
      (KGC::TPS_PAGE_NUMBER * 4).times { |i|
        if FileTest.exist?("Save#{i+1}.rxdata")
          found = true
          break
        end
      }
      # 세이브 파일이 발견되었을 경우
      if found
        # 커서를 콘티 뉴에 맞추는
        @command_window.index = 1
      end
      @continue_checked = true
    end

    update_KGC_2PaneSave
  end
end

#★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★

#==============================================================================
# ■ Scene_File
#==============================================================================

class Scene_File
  #--------------------------------------------------------------------------
  # ● 메인 처리
  #--------------------------------------------------------------------------
  def main
    @file_number = KGC::TPS_PAGE_NUMBER * 4
    create_sprites
    # 마지막에 조작한 파일을 선택
    @file_index = $game_temp.last_file_index
    @savefile_windows[@file_index].selected = true
    @index_x = @file_index % 4
    @top_position = 0
    (@file_index / 4).times { |i|
      @top_position -= 160 * 4
    }
    @scroll = 0
    # 윈도우 이동
    move_window(true)
    @info_window.refresh(@file_index)
    # 트란지션 실행
    Graphics.transition
    # 메인 루프
    loop {
      Graphics.update
      Input.update
      update
      if $scene != self
        break
      end
    }
    # 트란지션 준비
    Graphics.freeze
    dispose_sprites
  end
  #--------------------------------------------------------------------------
  # ● 스프라이트 생성
  #--------------------------------------------------------------------------
  def create_sprites
    # 헬프 윈도우 작성
    @help_window = Window_Help.new
    @help_window.set_text(@help_text)
    # 세이브 파일 윈도우 작성
    @savefile_windows = []
    @file_number.times { |i|
      @savefile_windows << Window_SaveFile.new(i, make_filename(i))
    }
    # 정보 윈도우 작성
    @info_window = Window_SaveFileInfo.new
    # 안내 윈도우 작성
    if KGC::TPS_PAGE_NUMBER > 1
      @navi_window = []
      @navi_sprite = []
      2.times { |i|
        @navi_window[i] = Window_Base.new(0, 140, 80, 36)
        @navi_window[i].back_opacity = 160
        @navi_window[i].z = 1000
        @navi_sprite[i] = Sprite.new
        @navi_sprite[i].bitmap = Bitmap.new(64, 24)
        @navi_sprite[i].bitmap.font.size = 20
        @navi_sprite[i].y = 144
        @navi_sprite[i].z = 1001
      }
      @navi_sprite[0].bitmap.draw_text(0, 0, 64, 24, "← Prev", 1)
      @navi_sprite[0].x = 8
      @navi_sprite[1].bitmap.draw_text(0, 0, 64, 24, "Next →", 1)
      @navi_window[1].x = 560
      @navi_sprite[1].x = 568
    end
    # 윈도우 반투명화
    window_alpha if $imported["MenuAlter"] && KGC::MA_MENU_TRANSPARENT
  end
  #--------------------------------------------------------------------------
  # ● 스프라이트 파기
  #--------------------------------------------------------------------------
  def dispose_sprites
    # 안내 윈도우 파기
    if KGC::TPS_PAGE_NUMBER > 1
      2.times { |i|
        @navi_window[i].dispose
        @navi_sprite[i].bitmap.dispose
        @navi_sprite[i].bitmap = nil
        @navi_sprite[i].dispose
        @navi_window[i] = @navi_sprite[i] = nil
      }
    end
    # 윈도우 파기
    @help_window.dispose
    @help_window = nil
    @savefile_windows.each_index { |i|
      @savefile_windows[i].dispose
      @savefile_windows[i] = nil
    }
    @info_window.dispose
    @info_window = nil
    # 스프라이트 세트 파기
    if @spriteset != nil
      @spriteset.dispose
      @spriteset = nil
    end
  end
  #--------------------------------------------------------------------------
  # ● 프레임 갱신
  #--------------------------------------------------------------------------
  def update
    # 윈도우를 갱신
    @help_window.update
    @savefile_windows.each { |w|
      w.update
    }
    # C 버튼
    if Input.trigger?(Input::C)
      on_decision(make_filename(@file_index))
      $game_temp.last_file_index = @file_index
      return
    # B 버튼
    elsif Input.trigger?(Input::B)
      on_cancel
      return
    # →
    elsif Input.repeat?(Input::RIGHT)
      # →의 압하 상태가 리피트가 아닌 경우인가,
      # 또는 커서 위치가 파일 개수보다 전의 경우
      if Input.trigger?(Input::RIGHT) || @file_index < @file_number - 1
        # 커서 SE 를 연주
        $game_system.se_play($data_system.cursor_se)
        # 커서를 오른쪽으로 이동
        @savefile_windows[@file_index].selected = false
        @file_index = (@file_index + 1) % @file_number
        @savefile_windows[@file_index].selected = true
        @index_x += 1
        self.move_window
        return
      end
    # ←
    elsif Input.repeat?(Input::LEFT)
      # ←의 압하 상태가 리피트가 아닌 경우인가,
      # 또는 커서 위치가 0 보다 뒤의 경우
      if Input.trigger?(Input::LEFT) || @file_index > 0
        # 커서 SE 를 연주
        $game_system.se_play($data_system.cursor_se)
        # 커서를 왼쪽으로 이동
        @savefile_windows[@file_index].selected = false
        @file_index = (@file_index + @file_number - 1) % @file_number
        @savefile_windows[@file_index].selected = true
        @index_x -= 1
        self.move_window
        return
      end
    # ↓또는R
    elsif Input.repeat?(Input::DOWN) || Input.repeat?(Input::R)
      # ↓,R 의 압하 상태가 리피트가 아닌 경우
      if Input.trigger?(Input::DOWN) || Input.trigger?(Input::R)
        # 커서 SE 를 연주
        $game_system.se_play($data_system.cursor_se)
        # 커서를 오른쪽으로 이동
        @savefile_windows[@file_index].selected = false
        @file_index = (@file_index + 4) % @file_number
        @savefile_windows[@file_index].selected = true
        @scroll = 1
        self.move_window
        return
      end
    # ↑또는L
    elsif Input.repeat?(Input::UP) || Input.repeat?(Input::L)
      # ↑,L 의 압하 상태가 리피트가 아닌 경우
      if Input.trigger?(Input::UP) || Input.trigger?(Input::L)
        # 커서 SE 를 연주
        $game_system.se_play($data_system.cursor_se)
        # 커서를 왼쪽으로 이동
        @savefile_windows[@file_index].selected = false
        @file_index = (@file_index + @file_number - 4) % @file_number
        @savefile_windows[@file_index].selected = true
        @scroll = -1
        self.move_window
        return
      end
    end
    @info_window.refresh(@file_index)
  end
  #--------------------------------------------------------------------------
  # ● 세이브 윈도우의 이동
  #    force : 강제 이동
  #--------------------------------------------------------------------------
  def move_window(force = false)
    if !force
      # 보통으로 커서 이동했을 경우
      if @scroll == 0 && @index_x >= 0 && @index_x <= 3
        return
      end
      if @index_x == 4 || @scroll == 1  # 오른쪽으로 스크롤
        if @file_index <= 3  # 좌단에 이동
          @top_position = 0
        else  # 페이지 이동
          @top_position -= 160 * 4
        end
        @index_x = 0 if @scroll == 0
      elsif @index_x == -1 || @scroll == -1  # 왼쪽으로 스크롤
        if @file_index >= @file_number - 4  # 우단에 이동
          @top_position = (@file_number - 4) * -160
        else  # 통상 이동
          @top_position += 160 * 4
        end
        @index_x = 3 if @scroll == 0
      end
      @scroll = 0
      @file_number.times { |i|
        @savefile_windows[i].destination = @top_position + 160 * i
      }
    else
      @file_number.times { |i|
        @savefile_windows[i].x = @savefile_windows[i].destination =
          @top_position + 160 * i
      }
    end
  end
  #--------------------------------------------------------------------------
  # ● 윈도우 반투명화
  #--------------------------------------------------------------------------
  def window_alpha
    # [Scene_Save]로 재정의
  end
end

#★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★

#==============================================================================
# ■ Scene_Save
#==============================================================================

class Scene_Save < Scene_File
  #--------------------------------------------------------------------------
  # ● 윈도우 반투명화
  #--------------------------------------------------------------------------
  def window_alpha
    # 스프라이트 세트 작성
    @spriteset = Spriteset_Map.new
    # 각 윈도우를 반투명화
    @help_window.back_opacity = 160
    @savefile_windows.each { |w|
      w.back_opacity = 160
    }
    @info_window.back_opacity = 160
  end
  #--------------------------------------------------------------------------
  # ● 세이브 데이터의 써
  #    file : 기입용 파일 오브젝트 (오픈이 끝난)
  #--------------------------------------------------------------------------
  def write_save_data(file)
    # 플레이 시간 계측용의 프레임 카운트를 쓰는
    Marshal.dump(Graphics.frame_count, file)
    # 세이브 회수를 1 늘리는
    $game_system.save_count += 1
    # magic number-를 보존하는
    # (에디터로 보존할 때마다 랜덤인 값에 고쳐 쓸 수 있는)
    $game_system.magic_number = $data_system.magic_number
    # 각종 게임 오브젝트를 쓰는
    Marshal.dump($game_system, file)
    Marshal.dump($game_switches, file)
    Marshal.dump($game_variables, file)
    Marshal.dump($game_self_switches, file)
    Marshal.dump($game_screen, file)
    Marshal.dump($game_actors, file)
    Marshal.dump($game_party, file)
    Marshal.dump($game_troop, file)
    Marshal.dump($game_map, file)
    Marshal.dump($game_player, file)
  end
end

#★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★

#==============================================================================
# ■ Scene_Load
#==============================================================================

class Scene_Load < Scene_File
  #--------------------------------------------------------------------------
  # ● 오브젝트 초기화
  #--------------------------------------------------------------------------
  def initialize
    # 텐포라리오브제크트를 재작성
    $game_temp = Game_Temp.new
    # 타임 스탬프가 최신의 파일을 선택
    $game_temp.last_file_index = 0
    latest_time = Time.at(0)
    (KGC::TPS_PAGE_NUMBER * 4).times { |i|
      filename = make_filename(i)
      if FileTest.exist?(filename)
        file = File.open(filename, "r")
        if file.mtime > latest_time
          latest_time = file.mtime
          $game_temp.last_file_index = i
        end
        file.close
      end
    }
    super("어느 파일을 로드합니까?")
  end
end