오늘은 서버내 우편함과 돈 시스템, 랜무서버에 필요한 간단한 기능들을 추가하겠습니다
대부분 서버마다 우편함 시스템이 있어 강좌글에 적용해봤습니다
options:
r : &d&l[ &f&l우편함 &d&l] &f
on join: # 플레이어가 서버에 접속했을때 이벤트
set {_pos} to size of {postbox.%uuid of player%::*} #임시변수는 해당 플레이어에 고유식별자 배열의 크기로 설정합니다
if {_pos} >= 1: # 설정한 변수에 크기가 1이상이라면
send "{@r} 우편함에 확인하지 않은 아이템이 있습니다" to player
stop
# 서버에 접속했을때 플레이어에 우편함에 아이템이 있을경우 해당 문구를 보여줍니다
command /우편함:
trigger:
open chest with 6 rows named "&d&l[ &f&l우편함 &d&l] &f%player%" to player #플레이어에게 9x6크기에 상자를 보여줍니다 (큰상자)
loop {postbox.%uuid of player%::*}: # 해당 고유식별자 배열변수를 반복합니다
add 1 to {_player} # 임시변수에 1을 이 배열에 크기만큼 계속해서 더해갑니다
set slot {_player}-1 of player's current inventory to loop-value # 임시변수에 -1인 값을 해당 슬롯에 아이템으로 설정합니다
#여기서 -1을 한 이유는 전 11강좌에서 슬롯은 0번부터 시작하기때문에 이 배열변수에 1에 값을 -1을 해서 해당 슬롯 0번 위치에 아이템을 설정한겁니다)
command /우편 [<text>] [<player>]:
trigger:
if arg 1 is not set:
send "{@r} /우편함"
send "{@r} /우편 보내기 [플레이어]"
if player is op:
send "{@r}"
send "{@r} OP "
send "{@r} /우편 열기 [닉네임] = 닉네임의 우편함을 열어봅니다"
send "{@r} /우편 초기화 [플레이어] = 해당 플레이어에 우편함을 초기화 합니다"
send "{@r} /우편 전체주기 = 손에 든 아이템을 서버내 모든 플레이어들에게 보낸다"
if arg 1 is "보내기":
if arg 2 is set:
if player is arg 2:
send "{@r} 자신한테 우편을 보낼 수 없습니다"
stop
if player's tool is not air:
set {_pos} to size of {postbox.%uuid of arg 2%::*} #임시변수는 arg 2닉네임인 플레이어에 고유식별자 배열의 크기로 설정합니다
if {_pos} < 54: #설정한 변수에 크기가 54 미만이라면 (즉 53이하)
if inventory name of arg 2's current inventory contains "우편함": #해당 arg 2님에 인벤토리 이름에 해당 문자열이 포함될때
close arg 2's inventory #그 사람에 인벤토리를 닫습니다 (즉 다른 사람한테 우편을 보냈는데 그사람이 우편함을 열고있으면 자동적으로 우편함이 닫힙니다)
add player's tool to {postbox.%uuid of arg 2%::*}#플레이어 도구를 arg 2닉네임의 플레이어에 고유식별자 배열로 추가합니다
remove player's tool from player
send "{@r} %arg 2% 님에게 우편을 보냈습니다!"
send "{@r} %player% 님이 보낸 우편이 도착했어요!" to arg 2
else: #만약 54보다 크다면
send "{@r} 해당 플레이어 우편함이 꽉찼습니다" # 우편 보내는걸 취소합니다
stop
else:
send "{@r} 우편을 보낼 아이템을 들어주세요"
stop
else:
send "{@r} 상대방 닉네임을 입력해주세요"
stop
if arg 1 is "전체주기":
if player is op:
if player's tool is not air:
loop all players: # 서버내 모든 플레이어를 반복합니다
set {_size} to size of {postbox.%uuid of loop-player%::*} # 해당 변수는 고유식별자 배열변수에 크기로 설정합니다
if {_size} < 54: #설정한 변수에 크기가 54 미만이라면
add player's tool to {postbox.%uuid of loop-player%::*} #위에랑 동일
send "{@r} 우편이 도착했어요!" to loop-player
if {_size} >= 54: #54 이상이라면
send "{@r} 당신은 우편함이 꽉차서 우편을 받지 못했습니다" to loop-player # 캔슬
remove player's tool from player's inventory
else:
send "{@r} 우편을 보낼 아이템을 들어주세요"
stop
if arg 1 is "열기":
if arg 2 is set:
open chest with 6 rows named "&d&l[ &f&l우편함 &d&l] &f%arg 2%" to player # arg 2님에 인벤토리를 엽니다
loop {postbox.%uuid of arg 2%::*}: # 위에랑 동일
add 1 to {_player}
set slot {_player}-1 of player's current inventory to loop-value
stop
if arg 1 is "초기화":
if player is op:
if arg 2 is set:
delete {postbox.%uuid of arg 2%::*} # 해당 고유식별자 배열에 변수를 삭제합니다
send "{@r} %arg 2% 님의 우편함을 청소했습니다"
send "{@r} 관리자에 의하여 우편함이 청소되었습니다" to arg 2
on inventory click:
if inventory name of current inventory of player contains "우편함": # 플레이어에 인벤토리 이름에 해당 문자열이 포함되어있을때
cancel event # 클릭 이벤트를 캔슬합니다
if click item is not air: # 클릭한 아이템이 공기가 아니라면
loop all items in player's inventory: #이 인벤토리를 연 플레이어에 인벤토리를 반복합니다
add 1 to {_n} # 플레이어에 아이템 갯수가 있는 만큼 +1을 더합니다
if {_n} > 35: # 만약 아이템 갯수가 36개라면
close player's inventory # 인벤토리를 닫습니다
send "{@r} 인벤토리를 비우고 진행해주세요"
stop
if name of clicked inventory contain "우편함": # 만약 클릭한 아이템이 해당 문자열 인벤토리 안이라면
set {_item} to click item # 임시변수는 클릭한 아이템으로 설정합니다
set {_slot} to clicked slot # 임시변수는 클릭한 슬롯으로 설정합니다
set {_postlist} to {_slot} +1 #임시변수는 클릭한 슬롯 변수에 +1을 더한값으로 설정합니다
set slot {_slot} of player's current inventory to air #클릭한 인벤토리에 슬롯을 공기로 바꿉니다
delete {postbox.%uuid of player%::%{_postlist}%} #해당 고유식별자 배열변수에 클릭한 슬롯변수에 +1을 더한값을 삭제합니다
give {_item} to player #클릭한 아이템을 줍니다
stop
소스 코드가 길어서 분할로 사진을 추가하지 않았습니다
uuid of player와 player 차이?
uuid of player는 고유 식별자 정보를 가져오기 때문에
계정명을 변경했을때 그전 닉네임의 정보가 그대로 남아있습니다
하지만 플레이어로 설정해주면
플레이어가 계정명을 변경했을때 그전 닉네임에 정보를 가져올 수 없기 때문에
uuid of player를 사용하게 되었습니다
인벤토리 클릭 이벤트 구문에서
{_postlist} 변수에 클릭한 슬롯 변수에 +1을 한이유가
앞에 우편 보내기 기능에서 슬롯에 아이템을 설정하기 위해 -1을 해줬습니다
이것을 반대로 우리가 값을 가져와야하기 때문에 +1을 해준값을
해당 고유식별자 배열변수 위치에 넣은겁니다
추가로
앞에서 if inventory name of current inventory of player contains "우편함":
조건을 추가해줬는데 왜? 또 if name of clicked inventory contain "우편함": 조건을
추가했냐면 위에 첫번째 조건은
현재 플레이어 인벤토리에 이름이 우편함이 포함될때이고
두번째 조건은 클릭한 아이템 인벤토리에 이름이 우편함일때이다
즉 두번째 조건은 우편함이라는 GUI를 연 상태에서 우편함 GUI내부 아이템을 클릭했을때 인식하기 위하여 추가한거다
만약 두번째 조건이 없었고 우편함에서 아이템을 인벤토리로 받았다고 가정해보자
그러면 플레이어 보관함 인벤토리에 우편함에서 받은 아이템을 계속 클릭하면 무한으로 받아집니다
이를 방지하기 위해서 조건문을 하나 더 추가한겁니다
나머지는 주석처리로 쉽게 이해할 수 있을겁니다
options:
r: &b&l[ &f&l랜무서버 &b&l]&e&l
command /돈 [<string>] [<string>] [<integer>]:
trigger:
if arg 1 is not set:
send "&f"
send "&c&l ▒※ &6&lEconomy System &c&l※▒"
send "{@r} &e&l/돈 보내기 [닉네임] [금액] &7&l- &a&l해당 유저 에게 돈을 보냅니다."
send "{@r} &e&l/돈 순위 &7&l- &a&l돈 순위를 확인 합니다."
send "{@r} 보유금액: &a%player's money%"
send "&f"
player is op:
send " &b&l※ &e&l관리자 명령어 &b&l※"
send "&f"
send "{@r} &e&l/돈 주기 [닉네임] [금액] &7&l- &a&l해당 유저 에게 돈을 지급합니다."
send "{@r} &e&l/돈 뺏기 [닉네임] [금액] &7&l- &a&l해당 유저 에게 돈을 뺏습니다."
send "{@r} &e&l/돈 설정 [닉네임] [금액] &7&l- &a&l해당 유저의 돈을 설정 합니다."
send "{@r} &e&l/돈 확인 [닉네임] &7&l- &a&l해당 유저의 소유 금액을 확인 합니다."
send "&f"
else if arg 1 is "보내기":
if arg 2 is not set:
send "{@r} 보낼 플레이어를 적어 주세요."
exit
if arg 3 is not set:
send "{@r} 보낼 금액을 입력해 주세요."
exit
if arg 3 > player's money:
send "{@r} 돈이 부족 합니다 !"
exit
if arg 3 <= 0:
send "{@r} 올바른 금액을 입력하세요!"
exit
make player run cmd "/pay %arg 2% %arg 3%" as op #에센셜 기본 명령어를 이용한겁니다
exit
else if arg 1 is "주기":
if player is op:
if arg 2 is not set:
send "{@r} 지급할 플레이어를 적어 주세요."
exit
if arg 3 is not set:
send "{@r} 지급할 금액을 입력해 주세요."
exit
set {_PLAYER.a} to arg 2 parsed as player # 현재 arg 2기본 타입이 string이므로 플레이어로 변환된 타입으로 설정합니다
add arg 3 to money of {_PLAYER.a} # 타입이 변환된 플레이어에게 해당 금액을 지급합니다
send "{@r} &6&l%arg 2% &e&l님에게 &a&l%arg 3%원&e&l을 지급 했습니다 !"
send "{@r} &c&l관리자&e&l로 부터 &a&l%arg 3%원&e&l을 지급 받았습니다 !" to {_PLAYER.a}
exit
else if arg 1 is "뺏기":
if player is op:
if arg 2 is not set:
send "{@r} 뺏을 플레이어를 적어 주세요."
exit
if arg 3 is not set:
send "{@r} 뺏을 금액을 입력해 주세요."
exit
set {_PLAYER.a} to arg 2 parsed as player # 위에랑 동일
if money of {_PLAYER.a} < arg 3:
send "{@r} 해당 플레이어가 충분한 금액을 가지고 있지 않습니다."
exit
subtract arg 3 from money of {_PLAYER.a}
send "{@r} &6&l%arg 2% &e&l님에게 &a&l%arg 3%원&e&l을 차감 시켯 습니다 !"
send "{@r} &c&l관리자&e&l로 부터 &a&l%arg 3%원&e&l을 빼았겼습니다 !" to {_PLAYER.a}
exit
else if arg 1 is "설정":
if player is op:
if arg 2 is not set:
send "{@r} 뺏을 플레이어를 적어 주세요."
exit
if arg 3 is not set:
send "{@r} 뺏을 금액을 입력해 주세요."
exit
set {_PLAYER.a} to arg 2 parsed as player
set money of {_PLAYER.a} to arg 3
send "{@r} &6%arg 2% &e&l님의 돈을 &a&l%arg 3%원 &e&l으로 설정 했습니다 !"
exit
else if arg 1 is "순위":
make player run cmd "/balancetop" as op #에센셜 돈 순위 기능과 연동한겁니다
exit
else if arg 1 is "확인":
if player is op:
if arg 2 is not set:
send "{@r} 확인할 플레이어를 적어 주세요."
exit
set {_PLAYER.a} to arg 2 parsed as player
set {_INT.a} to money of {_PLAYER.a}
send "{@r} &6%arg 2% &e&l님의 보유금액: &a%{_INT.a}%" # 해당 플레이어에 금액을 보여줍니다
exit
else:
send "{@r} 보유금액: &a%player's money%"
exit
해당 스크립트는 예전 블로그에서 다운받은것을 조금 수정하였습니다
에센셜 돈 기능과 연동해서 구현한겁니다
( 스크립트 파일을 새롭게 만들어주세요 / 파일명 : 돈 )
돈 스크립트는 보시다시피 어려운 부분이 없습니다
on join:
set join message to "&b&l[+] &e%player% &f님이 &a&l&n입장&f 하셨습니다. &e&l&o(%size of all players%명)"
on quit:
set quit message to "&b&l[-] &e%player% &f님이 &c&l&n퇴장&f 하셨습니다. &e&l&o(%size of all players-1%명)"
이 기능은 스크립트 시스템 파일 부분에 추가해줍니다
size of all players은 서버에 모든 플레이어들에 크기 ( 즉 서버에 몇명있는지 파악 )
플레이어가 나갔다 들어오면 해당 문구를 보여줍니다
options:
접두사: &d&l[ &f&l랜무서버 &d&l]&f
#무한내구도
on damage:
repair attacker's tool # 공격자 무기를 수리합니다
wait 1 tick
repair attacker's tool
wait 1 tick
repair attacker's tool
on damage:
repair victim's helmet # 피해자 모자를 수리합니다
repair victim's chestplate
repair victim's leggings
repair victim's boots
wait 1 ticks
repair victim's helmet
repair victim's chestplate
repair victim's leggings
repair victim's boots
#랜무서버에 내구도 무한은 필수여서 추가하였습니다
on script load: # 스크립트를 리로드할때
if {clear} is not set: # 서버 전체 변수가 설정되어있지 않으면
set {clear} to 10 # 10으로 설정
every a minute: # 1분마다 해당 이벤트가 작동됩니다
if {clear} > 0:
subtract 1 from {clear} # 1분마다 1씩 뺍니다
if {clear} is 5:
broadcast "{@접두사} &6%{clear}% &f분 뒤, 바닥에 떨어진 모든 아이템이 청소됩니다."
if {clear} is 3:
broadcast "{@접두사} &6%{clear}% &f분 뒤, 바닥에 떨어진 모든 아이템이 청소됩니다."
if {clear} is 2:
broadcast "{@접두사} &6%{clear}% &f분 뒤, 바닥에 떨어진 모든 아이템이 청소됩니다."
if {clear} is 1:
broadcast "{@접두사} &6%{clear}% &f분 뒤, 바닥에 떨어진 모든 아이템이 청소됩니다."
if {clear} is 0:
broadcast "{@접두사} &610 &f초 뒤, 바닥에 떨어진 모든 아이템이 청소됩니다."
wait 5 seconds
broadcast "{@접두사} &c5 &f초 뒤, 바닥에 떨어진 모든 아이템이 청소됩니다."
wait 1 seconds
broadcast "{@접두사} &64 &f초 뒤, 바닥에 떨어진 모든 아이템이 청소됩니다."
wait 1 seconds
broadcast "{@접두사} &e3 &f초 뒤, 바닥에 떨어진 모든 아이템이 청소됩니다."
wait 1 seconds
broadcast "{@접두사} &a2 &f초 뒤, 바닥에 떨어진 모든 아이템이 청소됩니다."
wait 1 seconds
broadcast "{@접두사} &b1 &f초 뒤, 바닥에 떨어진 모든 아이템이 청소됩니다."
wait 1 seconds
set {_entity} to 0
loop all dropped items: #바닥에 떨어진 모든 아이템을 반복합니다
kill loop-entity # 모두 제거합니다
add 1 to {_entity} # 떨어진 아이템 갯수 만큼 해당 변수에 1씩 더합니다
broadcast "{@접두사} &c%{_entity}% &f개의 아이템이 모두 청소되었습니다."
set {clear} to 10 # 다시 10으로 설정하여 10분마다 무한 작동되게 하였씁니다
#지난 강좌때 바닥에 엔티티가 많을수록 서버에 렉이 걸릴수 있다고 말했는데 이를 방지하기 위해서 아이템 청소 스크립트를 추가하였습니다
command /채팅청소:
trigger:
if player is op:
loop 100 times: #100번 반복
broadcast ""
broadcast "{@접두사} &6&l%player% &f&l님께서 채팅창을 청소하셨습니다."
broadcast "{@접두사} &f&l현재 접속자 수 : &e&l[ &f&l%number of all players%&f 명 &e&l]"
broadcast "{@접두사} &f&l현재 시간 : &a&l%now%"
if player is not op:
loop 100 times:
send ""
send "{@접두사} &f&l개인 채팅창을 청소하셨습니다."
send "{@접두사} &f&l현재 접속자 수 : &e&l[ &f&l%number of all players%&f 명 &e&l]"
send "{@접두사} &f&l현재 시간 : &a&l%now%"
command /쓰레기통:
trigger:
open chest with 6 row named "&8&l[쓰레기통]" to player
#현재 쓰레기통 스크립트는 인벤토리 클릭과 닫는 이벤트가 없어서 여기에 아이템을 넣고 쓰레기통 인벤토리를 닫아주면 자동적으로 아이템이 삭제됩니다
간단한 기능 입니다
전부 시스템 부분에 추가해주세요
따로 필요없는 부분은 추가 안하셔도 됩니다
우리가 여태까지 만든 스크립트 파일입니다
이제 대강 랜무서버가 만들어지고 있습니다