메뉴 건너뛰기

창조도시 기록보관소

RPGXP [스크립트] 파티원 교체.

2006.05.24 09:47

천무 조회 수:424


장면클래스를 띄우려면 이벤트커맨드의 스크립트에 $scene = Scene_파티원재편성.new를 넣어주면됩니다.

우선 아래 스크립트를 찔러넣으세요.

4명이 꽉 찼을 경우 추가하면 대기파티로 추가됩니다.
대기파티에 있는 엑터의 경우 현재파티에 이벤트커맨드로 추가되지 않습니다.
대기파티에 있는 엑터의 경우도 이벤트커맨드로 제외시킬 수 있습니다.







#==============================================================================
# ■ Game_Party
#------------------------------------------------------------------------------
#  파티를 취급하는 클래스입니다. 골드나 아이템등의 정보가 포함됩니다. 이 쿠
# 라스의 인스턴스는 $game_party 로 참조됩니다.
#==============================================================================

class Game_Party
  #--------------------------------------------------------------------------
  # ● 엑터를 가세한다
  #     actor_id : 엑터 ID
  #--------------------------------------------------------------------------
  def add_actor(actor_id)
    # 엑터를 취득
    actor = $game_actors[actor_id]
    # 파티 인원수가 4 명 미만으로, 이 엑터가 파티에 없는 경우
    if @actors.size < 4 and not @actors.include? (actor) and not @대기파티원.include? (actor)
      # 엑터를 추가
      @actors.push(actor)
      # 플레이어를 리프레쉬
      $game_player.refresh
    elsif not @actors.include? (actor) and not @대기파티원.include? (actor)
      @대기파티원.push(actor)
      # 플레이어를 리프레쉬
      $game_player.refresh
    end
  end
  #--------------------------------------------------------------------------
  # ● 엑터를 제외한다
  #     actor_id : 엑터 ID
  #--------------------------------------------------------------------------
  def remove_actor(actor_id)
    # 엑터를 삭제
    @actors.delete($game_actors[actor_id])
    # 플레이어를 리프레쉬
    $game_player.refresh
    @대기파티원.delete($game_actors[actor_id])
    $game_player.refresh
  end

end
class Game_Party
  #--------------------------------------------------------------------------
  # ● 공개 인스턴스 변수
  #--------------------------------------------------------------------------
  attr_reader   :대기파티원 # 엑터
alias 협객_initialize initialize

  def initialize
  @대기파티원 = []
  협객_initialize
  end

  #--------------------------------------------------------------------------
  # ● 파티 멤버의 리프레쉬
  #--------------------------------------------------------------------------
  def refresh
    # 게임 데이터를 로드한 직후는 엑터 오브젝트가
    # $game_actors 로부터 분리해 버리고 있다.
    # 로드마다 엑터를 재설정하는 것으로 문제를 회피한다.
    for i in 0...@actors.size
      @actors[i] = $game_actors[@actors[i]. id]
    end
    for i in 0...@대기파티원.size
      @대기파티원[i] = $game_actors[@대기파티원[i]. id]
    end
  end
end

class Game_Actor < Game_Battler
attr_reader   :actor_id                   # 스킬
end
#==============================================================================
# ■ Window_MenuStatus
#------------------------------------------------------------------------------
#  메뉴 화면에서 파티 멤버의 스테이터스를 표시하는 윈도우입니다.
#==============================================================================

class Window_현재파티원 < Window_Selectable
  attr_reader :max_index
  #--------------------------------------------------------------------------
  # ● 오브젝트 초기화
  #--------------------------------------------------------------------------
  def initialize
    @max_index = $game_party.actors.size + 1
    h = 56 * @max_index + 32
    h = 368 if h > 368
    x = 0
    super(x, 64, 232, h)
    self.contents = Bitmap.new(width - 56, @max_index * 56)
    refresh
    self.active = false
    self.index = -1
  end
  #--------------------------------------------------------------------------
  # ● 리프레쉬
  #--------------------------------------------------------------------------
  def refresh
    self.contents.clear
    @item_max = $game_party.actors.size + 1
    for i in 0...$game_party.actors.size
      x = 56
      y = 56 * i
      actor = $game_party.actors[i]
      draw_actor_name(actor, x, y)
    end
    self.contents.font.color = normal_color
    self.contents.draw_text(x, 56 * $game_party.actors.size, 120, 32, "추가")
  end
#캐릭터칩의 얼굴이 아닌 진짜얼굴을 나타내고 싶었지만...
    #--------------------------------------------------------------------------
  # ● 선두의 행의 취득
  #--------------------------------------------------------------------------
  def top_row
    # 윈도우 내용의 전송원 Y 좌표를, 1 행의 높이 32 로 나눈다
    return self.oy / 56
  end
  #--------------------------------------------------------------------------
  # ● 선두의 행의 설정
  #     row : 선두에 표시하는 행
  #--------------------------------------------------------------------------
  def top_row=(row)
    # row 가 0 미만의 경우는 0 에 수정
    if row < 0
      row = 0
    end
    # row 가 row_max - 1 초과의 경우는 row_max - 1 에 수정
    if row > row_max - 1
      row = row_max - 1
    end
    # row 에 1 행의 높이 32 를 걸어 윈도우 내용의 전송원 Y 좌표로 한다
    self.oy = row * 56
  end
  def page_row_max
    # 윈도우의 높이로부터, 프레임의 높이 56 를 빼, 1 행의 높이 56 로 나눈다
    return (self.height - 32) / 56
  end
  #--------------------------------------------------------------------------
  # ● 커서의 구형 갱신
  #--------------------------------------------------------------------------
  def update_cursor_rect
    # 커서 위치가 0 미만의 경우
    if @index < 0
      self.cursor_rect.empty
      return
    end
    # 현재의 행을 취득
    row = @index / @column_max
    # 현재의 행이, 표시되고 있는 선두의 행보다 전의 경우
    if row < self.top_row
      # 현재의 행이 선두가 되도록(듯이) 스크롤
      self.top_row = row
    end
    # 현재의 행이, 표시되고 있는 최후미의 행부터 뒤의 경우
    if row > self.top_row + (self.page_row_max - 1)
      # 현재의 행이 최후미가 되도록(듯이) 스크롤
      self.top_row = row - (self.page_row_max - 1)
    end
    # 커서의 폭을 계산
    cursor_width = self.width / @column_max - 32
    # 커서의 좌표를 계산
    x = @index % @column_max * (cursor_width + 56)
    y = @index / @column_max * 56 - self.oy
    # 커서의 구형을 갱신
    self.cursor_rect.set(x, y, cursor_width, 56)
  end  
end

#==============================================================================
# ■ Window_MenuStatus
#------------------------------------------------------------------------------
#  메뉴 화면에서 파티 멤버의 스테이터스를 표시하는 윈도우입니다.
#==============================================================================
class Window_대기파티 < Window_Selectable
  attr_reader :max_index
  #--------------------------------------------------------------------------
  # ● 오브젝트 초기화
  #--------------------------------------------------------------------------
  def initialize
    @max_index = $game_party.대기파티원.size + 1
    h = 56 * @max_index + 32
    h = 368 if h > 368
    x = 300
    super(x, 64, 232, h)
    self.contents = Bitmap.new(width - 56,@max_index * 56)
    refresh
    self.active = false
    self.index = -1
  end
  #--------------------------------------------------------------------------
  # ● 리프레쉬
  #--------------------------------------------------------------------------
  def refresh
    self.contents.clear
    @item_max = $game_party.대기파티원.size + 1
    for i in 0...@item_max
      x = 56
      y = 56 * i
      actor = $game_party.대기파티원[i]
      if $game_party.대기파티원[i] != nil
        draw_actor_name(actor, x, y)
      else
      self.contents.font.color = normal_color
      self.contents.draw_text(x, y, 120, 32, "대기")
      end
    end
  end
#캐릭터칩의 얼굴이 아닌 진짜얼굴을 나타내고 싶었지만...
    #--------------------------------------------------------------------------
  # ● 선두의 행의 취득
  #--------------------------------------------------------------------------
  def top_row
    # 윈도우 내용의 전송원 Y 좌표를, 1 행의 높이 32 로 나눈다
    return self.oy / 56
  end
  #--------------------------------------------------------------------------
  # ● 선두의 행의 설정
  #     row : 선두에 표시하는 행
  #--------------------------------------------------------------------------
  def top_row=(row)
    # row 가 0 미만의 경우는 0 에 수정
    if row < 0
      row = 0
    end
    # row 가 row_max - 1 초과의 경우는 row_max - 1 에 수정
    if row > row_max - 1
      row = row_max - 1
    end
    # row 에 1 행의 높이 32 를 걸어 윈도우 내용의 전송원 Y 좌표로 한다
    self.oy = row * 56
  end
  def page_row_max
    # 윈도우의 높이로부터, 프레임의 높이 56 를 빼, 1 행의 높이 56 로 나눈다
    return (self.height - 32) / 56
  end
  #--------------------------------------------------------------------------
  # ● 커서의 구형 갱신
  #--------------------------------------------------------------------------
  def update_cursor_rect
    # 커서 위치가 0 미만의 경우
    if @index < 0
      self.cursor_rect.empty
      return
    end
    # 현재의 행을 취득
    row = @index / @column_max
    # 현재의 행이, 표시되고 있는 선두의 행보다 전의 경우
    if row < self.top_row
      # 현재의 행이 선두가 되도록(듯이) 스크롤
      self.top_row = row
    end
    # 현재의 행이, 표시되고 있는 최후미의 행부터 뒤의 경우
    if row > self.top_row + (self.page_row_max - 1)
      # 현재의 행이 최후미가 되도록(듯이) 스크롤
      self.top_row = row - (self.page_row_max - 1)
    end
    # 커서의 폭을 계산
    cursor_width = self.width / @column_max - 32
    # 커서의 좌표를 계산
    x = @index % @column_max * (cursor_width + 56)
    y = @index / @column_max * 56 - self.oy
    # 커서의 구형을 갱신
    self.cursor_rect.set(x, y, cursor_width, 56)
  end  
end


class Scene_파티원재편성
  def main
    @spriteset = Spriteset_Map.new
    # 커멘드 윈도우를 작성
    bmp = RPG::Cache.character($game_party.actors[0].character_name, 0)
    px = $game_player.screen_x
    py = $game_player.screen_y - bmp.rect.height / 4 / 2
#대기파티 윈도우 작성
    @대기파티_window = Window_대기파티.new
    @대기파티_window.z = 400
    @대기파티_window.active = false
    @대기파티_window.visible = true
    @대기파티_window.index = 0
#현재파티 윈도우 작성
    @status_window = Window_현재파티원.new
    @status_window.z = 200
    @status_window.active = true
    @status_window.visible = true
    @status_window.index = 0
    # 트란지션 실행
    Graphics.transition
    # 메인 루프
    loop do
      # 게임 화면을 갱신
      Graphics.update
      # 입력 정보를 갱신
      Input.update
      # 프레임 갱신
      update
      # 화면이 바뀌면(자) 루프를 중단
      if $scene != self
        break
      end
    end
    # 트란지션 준비
    Graphics.freeze
    @spriteset.dispose    
    @대기파티_window.dispose
    @status_window.dispose
  end
  #--------------------------------------------------------------------------
  # ● 프레임 갱신
  #--------------------------------------------------------------------------
  def update
    # 윈도우를 갱신
    @status_window.update
    @대기파티_window.update
    if @status_window.active
      update_status
      return
    end
    if @대기파티_window.active
      update_대기파티
      return
    end
  end
  #--------------------------------------------------------------------------
  # ● 프레임 갱신 (스테이터스 윈도우가 액티브의 경우)
  #--------------------------------------------------------------------------
  def update_status
    # B 버튼이 밀렸을 경우
    if Input.trigger?(Input::B)
      # 캔슬 SE 을 연주
      $game_system.se_play($data_system.cancel_se)
      # 커멘드 윈도우를 액티브하게 하는
      $scene = Scene_Map.new
      $game_player.refresh
      return
    end
    # C 버튼이 밀렸을 경우
    if Input.trigger?(Input::C)
      # 커멘드 윈도우의 커서 위치에서 분기
        $game_system.se_play($data_system.decision_se)
        # 스테이터스 화면으로 전환하고
      @대기파티_window.active = true
      @status_window.active = false
      return
    end
  end
  #--------------------------------------------------------------------------
  # ● 프레임 갱신 (스테이터스 윈도우가 액티브의 경우)
  #--------------------------------------------------------------------------
  def update_대기파티
    # B 버튼이 밀렸을 경우
    if Input.trigger?(Input::B)
      # 캔슬 SE 을 연주
      $game_system.se_play($data_system.cancel_se)
      # 커멘드 윈도우를 액티브하게 하는
      @대기파티_window.active = false
      @status_window.active = true
      return
    end
    # C 버튼이 밀렸을 경우
    if Input.trigger?(Input::C)
      # 커멘드 윈도우의 커서 위치에서 분기
        $game_system.se_play($data_system.decision_se)
        # 대기파티의 멤버를 현재파티와 교환.
        교환
      $scene = Scene_파티원재편성.new
      return
    end
  end #메소드 종료

  def 교환
    if $game_party.actors.size != 1
      if $game_party.대기파티원[$game_party.대기파티원.size - 1] != nil #배열 마지막 요소가 엑터일 때
        #배열에 대기하는 파티인원이 있으므로 추가인지 확인
          if $game_party.actors[@status_window.index] == nil #추가
            if $game_party.대기파티원[@대기파티_window.index] != nil
            actor_id = $game_party.대기파티원[@대기파티_window.index].actor_id
            $game_party.actors.push($game_actors[actor_id])
            $game_party.대기파티원.delete_at(@대기파티_window.index)  
            end
          elsif $game_party.대기파티원[@대기파티_window.index] != nil
          #교환
          actor_id = $game_party.대기파티원[@대기파티_window.index].actor_id
          $game_party.actors.push($game_actors[actor_id])
          actor_id = $game_party.actors[@status_window.index].actor_id
          $game_party.대기파티원.push($game_actors[actor_id])
          $game_party.actors.delete($game_party.actors[@status_window.index])    
          $game_party.대기파티원.delete_at(@대기파티_window.index)  
          else #대기
          actor_id = $game_party.actors[@status_window.index].actor_id
          $game_party.대기파티원.push($game_actors[actor_id])
          $game_party.actors.delete($game_party.actors[@status_window.index])            
          end
      else #대기
    #배열이 비어 있으므로 대기만 가능
        if $game_party.actors[@status_window.index] != nil #추가가 아닐 때
          actor_id = $game_party.actors[@status_window.index].actor_id
          $game_party.대기파티원.push($game_actors[actor_id])
          $game_party.actors.delete($game_party.actors[@status_window.index])                      
        end #교환의 경우는 생각하지 않아도 좋다.
      end
    else # 게임파티에 1명밖에 없으므로 대기불가
    #추가, 교환만 가능
        if $game_party.대기파티원[@대기파티_window.index] != nil
          if $game_party.actors[@status_window.index] == nil #추가
          actor_id = $game_party.대기파티원[@대기파티_window.index].actor_id
          $game_party.actors.push($game_actors[actor_id])
          $game_party.대기파티원.delete_at(@대기파티_window.index)  
          else
          #교환
          actor_id = $game_party.대기파티원[@대기파티_window.index].actor_id
          $game_party.actors.push($game_actors[actor_id])
          actor_id = $game_party.actors[@status_window.index].actor_id
          $game_party.대기파티원.push($game_actors[actor_id])
          $game_party.actors.delete($game_party.actors[@status_window.index])    
          $game_party.대기파티원.delete_at(@대기파티_window.index)  
          end
        end
    end #if문 종료
  end #메소드 종료
end #클래스 종료

#따로 링메뉴등에 넣으실 분은 여기서 스톱! 아래는 메뉴에서 위의 스크립트를 불러오도록한 부분

#==============================================================================
# ■ Scene_Menu
#------------------------------------------------------------------------------
#  메뉴 화면의 처리를 실시하는 클래스입니다.
#==============================================================================

class Scene_Menu

  #--------------------------------------------------------------------------
  # ● 메인 처리
  #--------------------------------------------------------------------------
  def main
    # 커멘드 윈도우를 작성
    s1 = $data_system.words.item
    s2 = $data_system.words.skill
    s3 = $data_system.words.equip
    s4 = "파티원재편성"
    s5 = "케릭터 장비보기"
    s6 = "저장 하기"
    s7 = "끝내기"
    @command_window = Window_Command.new(160, [s1, s2, s3, s4, s5, s6, s7])
    @command_window.index = @menu_index
    # 파티 인원수가 0 명의 경우
    if $game_party.actors.size == 0
      # 아이템, 스킬, 장비, 스테이터스를 무효화
      @command_window.disable_item(0)
      @command_window.disable_item(1)
      @command_window.disable_item(2)
      @command_window.disable_item(3)
    end
    # 세이브 금지의 경우
    if $game_system.save_disabled
      # 세이브를 무효로 한다
      @command_window.disable_item(4)
    end
    # 플레이 시간 윈도우를 작성
    @playtime_window = Window_PlayTime.new
    @playtime_window.x = 0
    @playtime_window.y = 224
    # 보수 윈도우를 작성
    @steps_window = Window_Steps.new
    @steps_window.x = 0
    @steps_window.y = 320
    # 골드 윈도우를 작성
    @gold_window = Window_Gold.new
    @gold_window.x = 0
    @gold_window.y = 416
    # 스테이터스 윈도우를 작성
    @status_window = Window_MenuStatus.new
    @status_window.x = 160
    @status_window.y = 0
    # 트란지션 실행
    Graphics.transition
    # 메인 루프
    loop do
      # 게임 화면을 갱신
      Graphics.update
      # 입력 정보를 갱신
      Input.update
      # 프레임 갱신
      update
      # 화면이 바뀌면(자) 루프를 중단
      if $scene != self
        break
      end
    end
    # 트란지션 준비
    Graphics.freeze
    # 윈도우를 해방
    @command_window.dispose
    @playtime_window.dispose
    @steps_window.dispose
    @gold_window.dispose
    @status_window.dispose
  end

  #--------------------------------------------------------------------------
  # ● 프레임 갱신 (커멘드 윈도우가 액티브의 경우)
  #--------------------------------------------------------------------------
  def update_command
    # B 버튼이 밀렸을 경우
    if Input.trigger? (Input::B)
      # 캔슬 SE 를 연주
      $game_system.se_play($data_system.cancel_se)
      # 맵 화면으로 전환하고
      $scene = Scene_Map.new
      return
    end
    # C 버튼이 밀렸을 경우
    if Input.trigger? (Input::C)
      # 파티 인원수가 0 명이, 세이브, 게임 종료 이외의 커멘드의 경우
      if $game_party.actors.size == 0 and @command_window.index < 4
        # 버저 SE 를 연주
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      # 커멘드 윈도우의 커서 위치에서 분기
      case @command_window.index
      when 0  # 아이템
        # 결정  SE 를 연주
        $game_system.se_play($data_system.decision_se)
        # 아이템 화면으로 전환하고
        $scene = Scene_Item.new
      when 1  # 스킬
        # 결정 SE 를 연주
        $game_system.se_play($data_system.decision_se)
        # 스테이터스 윈도우를 액티브하게 한다
        @command_window.active = false
        @status_window.active = true
        @status_window.index = 0
      when 2  # 장비
        # 결정 SE 를 연주
        $game_system.se_play($data_system.decision_se)
        # 스테이터스 윈도우를 액티브하게 한다
        @command_window.active = false
        @status_window.active = true
        @status_window.index = 0
      when 3
        $scene = Scene_파티원재편성.new
      when 4  # 스테이터스
        # 결정 SE 를 연주
        $game_system.se_play($data_system.decision_se)
        # 스테이터스 윈도우를 액티브하게 한다
        @command_window.active = false
        @status_window.active = true
        @status_window.index = 0
      when 5  # 세이브
        # 세이브 금지의 경우
        if $game_system.save_disabled
          # 버저 SE 를 연주
          $game_system.se_play($data_system.buzzer_se)
          return
        end
        # 결정 SE 를 연주
        $game_system.se_play($data_system.decision_se)
        # 세이브 화면으로 전환하고
        $scene = Scene_Save.new
      when 6  # 게임 종료
        # 결정 SE 를 연주
        $game_system.se_play($data_system.decision_se)
        # 게임 종료 화면으로 전환하고
        $scene = Scene_End.new
      end
      return
    end
  end
  #--------------------------------------------------------------------------
  # ● 프레임 갱신 (스테이터스 윈도우가 액티브의 경우)
  #--------------------------------------------------------------------------
  def update_status
    # B 버튼이 밀렸을 경우
    if Input.trigger? (Input::B)
      # 캔슬 SE 를 연주
      $game_system.se_play($data_system.cancel_se)
      # 커멘드 윈도우를 액티브하게 한다
      @command_window.active = true
      @status_window.active = false
      @status_window.index = -1
      return
    end
    # C 버튼이 밀렸을 경우
    if Input.trigger? (Input::C)
      # 커멘드 윈도우의 커서 위치에서 분기
      case @command_window.index
      when 1  # 스킬
        # 이 엑터의 행동 제한이 2 이상의 경우
        if $game_party.actors[@status_window.index]. restriction >= 2
          # 버저 SE 를 연주
          $game_system.se_play($data_system.buzzer_se)
          return
        end
        # 결정 SE 를 연주
        $game_system.se_play($data_system.decision_se)
        # 스킬 화면으로 전환하고
        $scene = Scene_Skill.new(@status_window.index)
      when 2  # 장비
        # 결정 SE 를 연주
        $game_system.se_play($data_system.decision_se)
        # 장비 화면으로 전환하고
        $scene = Scene_Equip.new(@status_window.index)
      when 4  # 스테이터스
        # 결정 SE 를 연주
        $game_system.se_play($data_system.decision_se)
        # 스테이터스 화면으로 전환하고
        $scene = Scene_Status.new(@status_window.index)
      end
      return
    end
  end
end

번호 제목 글쓴이 날짜 조회 수
371 레벨에 따라 값을 더 받아보자! [5] 다크세이버™ 2006.06.05 273
370 강력한 무료 에디터 Elitpad 6.5 file 나라 2006.06.04 138
369 제 2 부 ! 나도 게임을 만들수 있다 ! [5] 다크세이버™ 2006.06.01 320
368 [스크립트기초] 제 4과. 그림표시, 배열과 해시의 클래스. [1] 천무 2006.05.24 473
367 [스크립트] 배틀포인트, 배틀샵 [1] 천무 2006.05.24 669
366 [스크립트] 창고 시스템 [9] 천무 2006.05.24 621
365 [스크립트] KGC 몬스터도감 [4] 천무 2006.05.24 795
364 [연금술사] 드디어 완성! 스크립트로 점프&데쉬하기 [5] file 천무 2006.05.24 762
363 [비밀소년] 한글이름입력기 v1.76 [6] file 천무 2006.05.24 2117
362 [비밀소년] ◆공부용◆ 01 - 숫자게이지바 [1] file 천무 2006.05.24 683
361 [툴기능] RPG XP로 액알만들기.(스샷) [10] 천무 2006.05.24 1541
360 [스크립트기초] 제 3과. 조건분기와 루프. [2] 천무 2006.05.24 222
» [스크립트] 파티원 교체. [2] 천무 2006.05.24 424
358 [스크립트] 스탯포인트로 스테이터스 조절하기입니다. 출처:gunmong [6] 천무 2006.05.24 506
357 [스크립트] 이전의 액알게이지바와는 비교도 안될 멋진 초고속 게이지바 - 그라데이션 [7] 천무 2006.05.24 879
356 [스크립트] 대화창에 이름+얼굴 띄우기: 메시지 플러스 가장 최신버전 (2005년 2월1일 버전) [4] 천무 2006.05.24 755
355 [스크립트] 소지수 한계 돌파 [1] 천무 2006.05.24 250
354 [스크립트] 대화창 크기 위치를 내맘대로! 좀더 간단화 시켰습니다.(소형윈도우 네임도 추가) [1] 천무 2006.05.24 444
353 [스크립트] 전투시 몬스터 머리위로 게이지바 만들기 [6] 천무 2006.05.24 835
352 [스크립트] 레벨과 능력치 한계를 자유자재로. 출처: 모모모 [1] 천무 2006.05.24 384