RPGXP [스크립트] 파티원 교체.
2006.05.24 09:47
장면클래스를 띄우려면 이벤트커맨드의 스크립트에 $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