본문 바로가기
마인크래프트/Skript 기초 활용편

스크립트 기초 활용 10편(자동심기)

by 스터디립트 2023. 1. 2.

마인크래프트의 마인팜 서버들을 플레이하다 보면, 자동심기라는 기능에 대해 알 수 있습니다. 다 익은 작물을 캤을 경우, 그리고 플레이어의 인벤토리에 그 작물의 씨앗이 있는 경우에 플레이어의 인벤토리에 있는 씨앗을 캔 작물의 자리에 자동으로 심어주는 기능입니다. 이번 시간에는, 그 자동심기 기능을 스크립트로 따라 만들어 보도록 하겠습니다.

 

1. 자동심기 대상 작물들 설정하기

마인크래프트에는 여러 작물들이 있습니다. 그 중 자동심기를 적용시킬 만한 작물들은 일부로, 더 있을 수도 있겠지만 제가 찾은 것들로는 밀, 사탕무, 당근, 감자 정도가 있습니다. 오직 그 4개의 작물들을 캤을 시에만 자동심기가 작동하도록 해야하므로, 자동심기 대상 작물들을 넣어놓는 배열변수를 만들겠습니다. 아래는 그 코드입니다.

on script load:
    set {crops::*} to ripe wheat plant, ripe carrot plant, ripe potato plant and ripe beetroot plant

스크립트가 로드될 때, 즉 서버가 열릴 때 {crops::*}에 4가지 작물들이 들어가도록 만들었습니다. 주의하실 점은 "다 자란 작물들"만 자동심기가 적용되어야 하므로 앞에 ripe를 꼭 붙여주셔야 합니다.

 

2. 작물(블록)을 씨앗(아이템)으로 변환하기

마인크래프트에서 작물들은 블록 판정이므로, skript에서는 block 타입으로 취급됩니다. 마찬가지로 씨앗들은 아이템 판정이므로, skript에서는 item 또는 itemtype으로 취급됩니다. 플레이어의 인벤토리에 해당 작물의 씨앗이 있는 지 확인해야 하므로 작물을 씨앗으로, 즉 블록을 아이템으로 변환하는 과정이 필요합니다. 아래는 그 코드입니다.

function seedTransfer(b: block) :: itemtype:
    if {_b} is ripe wheat plant:
        return seed
    else if {_b} is ripe carrot plant:
        return carrot
    else if {_b} is ripe potato plant:
        return potato
    else if {_b} is ripe beetroot plant:
        return beetroot seed

저는 함수를 이용해서 block타입의 인자를 넣으면 itemtype을 리턴하는 형식으로 블록을 넣어 아이템을 받아내는 함수를 만들었습니다.

 

3. 자동심기 온오프 기능 만들기

항상 자동심기가 작동된다면, 밭을 싹 밀고 다른 건물을 짓고 싶은 상황같이, 자동심기가 없어야 하는 상황에서 불편함이 생길 수 있습니다. 따라서 자동심기 시스템이 있는 모든 마인팜 서버들은 온오프 기능도 같이 탑재하고 있습니다. 저는 /자동심기 명령어를 사용할 시 온 오프가 토글이 되도록 만들어 보도록 하겠습니다. 아래는 그 코드입니다.

command /자동심기:
    trigger:
        if {autoSeed.%uuid of player%} is not set:
            set {autoSeed.%uuid of player%} to false
        if {autoSeed.%uuid of player%} is false:
            set {autoSeed.%uuid of player%} to true
            checkAutoSeedStatus(player)
            exit
        set {autoSeed.%uuid of player%} to false
        checkAutoSeedStatus(player)
        exit


function checkAutoSeedStatus(p: player):
    set {_s} to {autoSeed.%uuid of {_p}%}
    if {_s} is true:
        send "현재 자동심기 상태 : &a활성화" to {_p}
        exit
    else:
        send "현재 자동심기 상태 : &c비활성화" to {_p}
        exit

자동심기 변수 값이 지정되어있지 않은, 즉 자동심기 명령어를 한번도 사용하지 않은 플레이어의 경우에는 위 명령어를 사용했을 시 우선 false로 값을 지정해줍니다. 그 후 자동심기 변수 값이 false라면 true로, true라면 false로 바꿔준 뒤 함수를 이용하여 자동심기 상태를 플레이어에게 메시지로 알려줍니다.

 

4. 자동심기 기능 만들기

이제 드디어 이번 시간의 주 내용입니다. 위의 3가지 베이스와 on block break 이벤트문을 이용하여 블록을 부쉈을 때, 자동심기가 켜져있고, 배열변수에 해당 블록이 있으며, 플레이어의 인벤토리에 블록에서 아이템으로 변환한 아이템이 있을 시에 자동심기가 적용되도록 만들어보겠습니다. 아래는 그 코드입니다.

on block break:
    if {autoSeed.%uuid of event-player%} is not true:
        exit
    loop {crops::*}:
        if {crops::%loop-index%} is type of event-block:
            set {_s} to seedTransfer( event-block )
            if event-player has {_s}:
                remove 1 of {_s} from event-player's inventory
                set event-block's block data to "%raw name of event-block%[age=0]" parsed as blockdata

코드의 윗 부분들은 1,2,3 단계를 이용한 것들일 뿐이니 따로 더 살펴보진 않겠습니다.

 

if event-player has {_s}:
    remove 1 of {_s} from event-player's inventory
    set event-block's block data to "%raw name of event-block%[age=0]" parsed as blockdata

이 부분만 더 살펴보자면, skript 2.5버전 이상부터 생긴 blockdata를 이용한 구문입니다. 더 살펴보시고 싶으시다면 아래의 링크를 참고해주세요

https://docs.skriptlang.org/classes.html#blockdata

https://docs.skriptlang.org/expressions.html#ExprBlockData

 

마인크래프트의 작물들은 자랄 때마다 블록데이터의 age값이 1씩 상승합니다. 0이 방금 막 심었을 시의 한번도 자라지 않은 상태이고요. 따라서 블록이 부숴진 후, 그 자리에 age값이 0인 블록을 새로 설치해주는 방식으로 작동합니다.

 

제가 처음에 이렇게 코드를 짠 후 한 가지 의문점이, 블록을 설치 -> block break 이벤트이니 어차피 다시 설치해도 다시 부숴짐? -> 아이템 드롭 안됨? 이라는 의문점이 들었는데, 실제로 테스트 해 보니

기존 블록을 부숨 -> 아이템 드랍 -> 새로운 블록 설치 순서대로 작동했습니다.

 

 

 

이번 시간에는 스크립트로 마인팜 서버의 꽃, 자동심기 기능을 따라 만들어 보았습니다. 한 가지 아쉬운 점은 대부분의 마인팜 서버에서는 자동심기에 타이머 기능을 넣어놓고, 쿠폰과 같은 아이템을 만들어 쿠폰을 우클릭 할 시 자동심기 시간이 추가되는 방식이지만, 이번 시간에서는 타이머 기능을 제외한 부분만 만들었다는 것입니다. 기회가 된다면 타이머 기능까지 다 넣어서 한번 만들어 보겠습니다.

 

질문이 있으시다면 이 글의 댓글에 적어주시면 답변해드리도록 하겠습니다.

 

아래는 스크립트 파일들입니다

주석미포함

autoseed.sk
0.00MB

댓글