Skip to content

Inventory Trigger_kr

VillagerJM edited this page Feb 15, 2023 · 12 revisions

인벤토리 트리거는 GUI가 열릴 때(open), 닫힐 때(close), GUI내에서 특정 슬롯을 클릭할 때(click) 실행되는 트리거 입니다.

새로운 형식의 인벤토리 트리거에서는, 인벤토리의 크기와 사전에 정의된 아이템이 저장되어 있는 .yml 파일을 볼 수 있고, 이 .yml파일과 이름이 같은 또하나의 빈 텍스트파일(.trg)이 생성됩니다. 이 텍스트파일이 바로 우리가 사용하는 구문을 작성하는 파일 입니다. 이전의 형식과는 다르게, 새로운 형식에서는 슬롯 넘버를 선택하고, 그 슬롯넘버를 기반으로 하여 실행될 구문을 작성하여야 합니다.

새롭게 Test라는 이름의 인벤토리 트리거를 만들었다면, 다음과 같이 두 파일이 생성됩니다:

plugins/TriggerReactor/InventoryTrigger/Test.yml
plugins/TriggerReactor/InventoryTrigger/Test.trg

새로운 인벤토리 트리거 만들기

예를 들어 설명하도록 하겠습니다.

/trg i Test create 54

위 명령을 입력하면 54슬롯 크기의 인벤토리 트리거가 생성됩니다. 이때 54 부분 즉 슬롯 개수를 입력하는 부분에는 무조건 9의 배수이어야 하며, 54보다 크면 안됩니다.

위 명령을 입력하고 나서 plugins/TriggerReactor/InventoryTrigger 경로의 폴더를 들어가면, 다음 두 파일이 생성되어 있는 것을 볼 수 있습니다:

plugins/TriggerReactor/InventoryTrigger/Test.yml
plugins/TriggerReactor/InventoryTrigger/Test.trg

팁) 만약 코드가 그저 1라인밖에 없다면 다음과 같이 입력해도 됩니다:

/trg i Test create 54 #MESSAGE "HI"

위 명령은 해당 GUI가 열릴 때(open), 닫힐 때(close), 특정 슬롯을 클릭할 때(click) 모두 #MESSAGE "HI" 를 실행하며, 이 방법은 그다지 실용성이 없는 구문입니다. 인벤토리 트리거에는 어떠한 형식의 트리거가 실행 되었는지 구별하는 내부 변수가 있기 때문에, 인게임 구문 에디터나 외부 텍스트파일 에디터로 직접 구문을 입력하는 것 을 추천합니다.

인벤토리 트리거 타이틀 설정하기 (3.3.0.2버전부터 지원)

3.3.0.2버전 이전에는 파일 이름이 즉 인벤토리 타이틀이었습니다.
앞으로는 /tri i <트리거 이름> title <타이틀> 명령어로 타이틀을 따로 지정할 수 있습니다.

인벤토리 트리거 내의 행위 형식(0.1.8버전부터 지원)

깊이 있게 설명을 하자면, 인벤토리 트리거 내에서 실행될 수 있는 이벤트는 open, close, click 이 세가지 입니다.이 이벤트명은 trigger 이라는 내부 변수에 정의되고, 이 세가지를 구문 내에서 구분지으려면 IF조건문을 사용하여야 합니다.

IF조건문으로 구분짓는 방법은 다음과 같습니다:

IF trigger == "open"
    ...
ENDIF

IF trigger == "click"
    ...
ENDIF

IF trigger == "close"
    ...
ENDIF

하지만 어떻게 단지 하나의 트리거에서 3개의 이벤트를 다룰수 있는가 궁금할 수 있습니다. 그것에 대한 답은 바로 Trigger Reactor의 자랑인 Multi-Threading 에 있습니다. 하지만 그렇다고 해서 Multi-Threading을 이해려고 하지 않으셔도 됩니다. 알아야 할 것은, 매번 트리거가 실행될 때마다, 그 실행은 "task"로 옮겨지고, 이 "task"는 다른것에서 실행된 "task"와 다르다는 것 입니다. 예를 들어, GUI에서 당신이 인벤토리 슬롯 번호 0번을 클릭 했다고 하고, 그 슬롯을 또다시 한번 클릭했다고 하면, 당신은 똑같은 일을 하지만 서로 다른 task를 실행시킨 것 이라고 볼 수 있습니다. 그리고 task 여러개가 동시에 실행되는 것을 지원하는 기술, 그것이 바로 Multi-Threading 입니다.

동시 실행 문제

하지만 언제든지 간에, 두개의 task가 동시에 실행중인 상태가 되는 것은 그다지 원치 않습니다.

다음 경우를 생각해보세요.

당신은 인벤토리 트리거로 슬롯머신 기계를 만들었습니다. 그리고 만약 이용자들이 이전의 task가 이미 실행중에 있음에도 불구하고(이전 슬롯머신이 아직 돌아가고 있음) 또 start버튼을 누른다면, 결론적으로 두 실행간에는 전혀 딜레이가 없습니다.

위 경우같은 상황을 대비하여, 우리는 지역변수를 활용하여 이를 막아주어야 합니다. 다른 트리거들과는 다르게, 인벤토리 트리거 내에서 생성된 지역변수는 인벤토리 표시를 위해, 닫힐때까지 값이 보존됩니다.

예:

IF trigger == "click"
    IF slot == 0
        FOR 0:10
            해당 슬롯에서 실행할 구문
            #WAIT 1
        ENDFOR
    ENDIF
ENDIF  

위 구문의 경우, 인벤토리 슬롯 넘버 0에 자리한 Start버튼은 FOR반복문을 10초동안 실행합니다.(왜냐하면 매 반복할 때마다 #WAIT 1 을 거치게 되며, 이게 10번 반복되면 10초간 실행되는 것 입니다) 위 FOR반복문을 활용하여 FOR반복문이 실행중에는 또다른 FOR문 즉 또다른 task에서 FOR문을 시작하지 못하도록 설정하려면:

IF trigger == "click"
    IF slot == 0
        IF isRunning
            #STOP
        ENDIF

        isRunning = true

        FOR 0:10
            //슬롯에서 할거 아무거나
            #WAIT 1
        ENDFOR
        isRunning = false
    ENDIF
ENDIF

기본적으로, isRunning 지역변수가 true로 설정되어 있으면 바로 구문은 종료됩니다. 또한 FOR반복문 'task'가 반복을 종료하여 끝난다면, isRunning 지역변수는 false로 되돌아옵니다. 그리하여 유저는 다시 0번 슬롯을 이용할 수 있게됩니다.

모든 ''task'' 는 변수를 공유하기 때문에 이러한 것이 가능합니다. 즉, isRunning변수는 두 ''tasks'' 에서 서로 공유하고 있기 때문에 안심하고 이 방식을 채택하여도 됩니다.

위에서 언급한 방법 말고도 매우 많은 변형의 구문이 있습니다. 잠시 시간을 내어 본인에게 가장 알맞은 방법을 찾아 사용하시기 바랍니다.

주의바람: 트리거 이벤트 형식이 "close"인 부분에 절대로 무한루프 구문을 넣지 마세요! "open"형식과 "click"형식의 트리거 이벤트는 인벤토리가 종료될 때 함께 종료되어 안전하지만, "close"형식은 인벤토리가 닫힌 후에 실행되기 때문에 TriggerReactor에서 자동적으로 멈출 수 있는 방법이 없습니다.

하지만 "open" 형식에서는 무한루프를 사용하기를 추천드립니다. 그 이유는 실시간으로 트리거 내부에 위치한 아이템이나 아이템 이름, 또는 아이템의 로어(lore, 부가설명)를 실시간으로 업데이트 하기 위함입니다. 만약 인벤토리 트리거로 GUI를 이용한 애니메이션을 만들고 싶다면 open에 무한루프를 넣는 방법이 꽤 유용하게 사용되어 질 수 있습니다. 하지만 #WAIT 을 사용하여 업데이트에 지연시간을 부여하는걸 권장드립니다. 지연시간이 없다면 너무 빠르게 업데이트되어 CPU사용량을 모조리 빨아먹을 수 있습니다.

인벤토리에 아이콘(아이템) 넣기

이제 인벤토리 트리거 하나를 생성하였습니다. 자 이제 유저에게 보여질 아이콘을 넣어봅시다.

아이콘을 추가하려면, 다음 명령을 입력하면 됩니다.

/trg i <InvTrigger Name> item <slot index>

여기서 말하는 <InvTrigger Name> 은 생성한 인벤토리 트리거의 이름이며, <slot index> 는 슬롯 번호를 나타냅니다.

예:

/trg i Test item 0

인벤토리 슬롯 번호는 1이 아닌 0에서부터 시작하나 /trg inventory testName item 를 통해 아이템을 넣을 때에는 1부터 시작합니다. 이점 꼭 명심하시길 바랍니다.

또한, /trg i <InvTrigger Name> item <slot index> 명령을 이용하여 인벤토리 트리거에 아이템을 추가할 때는 손에 어떤 아이템이던 들고있어야 합니다. 현재 손에 들고 있는 아이템이 인벤토리 트리거에 아이콘으로써 슬롯 내에 삽입됩니다.

인벤토리에서 아이콘(아이템) 삭제하기

인벤토리에 이미 삽입되어 배치되어 있는 아이템을 지우려면, 간단히 다음 명령을 사용합니다. 다만 이번에는 손에 어떤 아이템도 들고 있으면 안됩니다.

/trg i <InvTrigger Name> item <slot index>

예:

/trg i Test item 0

위 예시는 Test라는 이름을 가진 인벤토리 트리거의 슬롯 0번에 있는 아이템을 제거합니다.

번역자 내용 추가) 슬롯에 추가와 삭제를 하는 커맨드가 완전히 동일한 것을 볼 수 있습니다. 이는 즉 현재 손에 아이템을 들고있는지를 체크하여 추가, 삭제를 구별해 내는 것이라고 보시면 됩니다.

인벤토리 트리거 수정하기

간단하게 다음 명령을 이용하여 인벤토리 트리거를 수정할 수 있습니다.

/trg i <InvTrigger Name> edit

(인게임 에디터가 실행됩니다)

예:

/trg i Test edit

인벤토리 트리거 삭제하기

다음 명령을 사용하여 존재하는 인벤토리 트리거를 삭제할 수 있습니다.

/trg i <InvTrigger Name> delete

예:

/trg i Test delete

일단 한번 삭제가 실행되면 멈추거나 되돌릴 수 없으니 조심하시기 바랍니다.

트리거 내 아이템에 사용자 정의(커스텀) 이름, 로어 사용하기

단순하게도, TriggerReactor에서 제공하는 명령어로 아이템의 이름및 로어를 설정할 수 있습니다.

아이템의 이름을 바꾸려면, 다음 명령을 입력하세요.

/trg misc title <title>

예:

/trg misc title &a야생으로 이동

아이템에 로어를 추가하려면, 다음 명령을 입력하세요.

/trg misc lore add <lore>

예:

/trg misc lore add &6야생으로 이동합니다.

아이템에서 <index> 번의 로어를 삭제하려면, 다음 명령을 입력하세요.

/trg misc lore remove <index>

아이템에서 <index> 번의 로어를 바꾸려면, 다음 명령을 입력하세요.

/trg misc lore set <index> <lore>

예:

/trg misc lore set 0 &a와일드한 야생으로 이동!

번역자 내용 추가) 로어 번호 역시 슬롯 번호처럼 0부터 시작합니다. 이점 명심하시길 바랍니다. + /trg misc 명령어는 손에 든 아이템의 정보를 수정하는 것 입니다.

색깔 적용에서의 유의점

아이템에 &등으로 색깔을 부여하면, &또는 색코드를 포함하여 색으로는 바뀌지 않고 입력한 것 그대로 나타나는 것을 볼 수 있습니다.

이러한 현상이 발생하는 이유는 Trigger Reactor에서 인벤토리 트리거에 해당 아이템을 넣기 전까지는 색코드 변환을 하지 않기 때문입니다.

색코드 변환을 하지 않는 이유는 색코드를 그대로 .yml파일에 적용시키는 작업이 약간 복잡하고 번거롭기 때문입니다.

UTF-8 기호들 중에서 몇몇은 텍스트 에디터에서 작동하지 않으며, 그중 하나가 바로 마인크래프트에서 사용하는 색코드 입니다. 즉, 이것을 피하기 위하여 위와 같이 작동하도록 하였습니다.

장문 예시

.../plugins/TriggerReactor/InventoryTrigger/menu.trg

open 부분 예시

IF trigger == "open" // 해당 인벤토리 트리거가 처음 열릴 때 실행할 코드
    WHILE true // 인벤토리가 닫힐 때 구문이 자동으로 종료되므로 실시간 업데이트를 위해 무한루프를 사용하여도 안전합니다.
        // 야생 서버
        // Bungee폴더 내에 있는 ItemServerInfo 지명 트리거를 불러오기 전에, 필요한 변수들을 정의합니다.
        index = 0 // index 지역변수를 0으로 설정합니다.
        address = "127.0.0.1:25501" // 서버 주소정보를 지역변수 address에 담습니다.
        message = "&a>> 야생서버로 이동합니다." // 보내질 메시지를 지역변수 message에 담습니다.
        #CALL "Bungee:ItemServerInfo" // 모두 설정되었다면, ItemServerInfo를 불러와 나머지를 처리하도록 합니다.
        // 전쟁 서버 - 야생서버에서 설정했던 방식대로 합니다.
        index = 2 // index 지역변수를 2로 설정합니다. 
        address = "127.0.0.1:25502"
        message = "&a>> pvp서버로 이동합니다."
        #CALL "Bungee:ItemServerInfo"

        // 미니게임 서버 - 야생서버에서 설정했던 방식대로 합니다.
        index = 4
        address = "127.0.0.1:25503"
        message = "&a>> 미니게임 서버로 이동합니다."
        #CALL "Bungee:ItemServerInfo"

        #WAIT 1 // 이 부분은 이미 설명드렸듯이, 반복문에서 1초의 지연을 주기 위함입니다.
                // 지연 없이는 반복문이 매우 빠르게 돌아가며, 이는 서버 이용자및 서버에 매우 큰 무리를 줍니다.

click 부분 예시

IF trigger == "click" // 인벤토리 트리거에서 아이템을 클릭했을때, 실행되는 트리거
                      // 클릭한 슬롯이 비어있더라도 이 구문은 호출됩니다.
    IF isCooldown // 플레이어가 아이템 클릭을 너무 빠르게 연속적으로 누르는지 체크합니다.
                   // isCooldown 지역변수가 설정(정의)되어 있지 않으면 false로 작용합니다.기억하세요!
                   // 더 많은 정보는 위키의 Conditions 메뉴를 참조하세요.
        #MESSAGE "&c너무 빠르게 누르고 있습니다! 진정하세요!"
        #STOP // 트리거를 즉각 중지시켜 구문 실행을 막습니다.
    ENDIF
    
    isCooldown = true // isCooldown변수를 'true'로 설정합니다. 이 변수는 구문이 종료되고 false가 될 때까지
                       // IF에서 true로 작용하여 구문 반복실행을 막습니다.
    
    IF slot == 0
        #SERVER "wild"
        #BROADCAST "&8[&6서버 이동&8] &6"+$playername+" &7-> &a야생 서버"
    ENDIF
    IF slot == 2
        //#SERVER "war"
        //#BROADCAST "&8[&6서버 이동&8] &6"+$playername+" &7-> &6전쟁 서버"
    ENDIF
    IF slot == 4
        #SERVER "minigames"
        #BROADCAST "&8[&6서버 이동&8] &6"+$playername+" &7-> &6미니게임 서버"
    ENDIF
    
    #WAIT 1 // 1초의 딜레이를 설정합니다.
    isCoolddown = false // 이제 위 구문이 실행 완료되었고, isCooldown이 false로 설정되어 플레이어는 다시 슬롯을 이용할 수 있습니다.
ENDIF

.../plugins/TriggerReactor/NamedTriggers/Bungee/ItemServerInfo

//'inventory' 실시간으로 업데이트될 인벤토리
//'index' 슬롯 번호

//'address' 서버 주소
//'message' 메시지 색

IF placeholder //서버에 PlaceholderAPI 플러그인이 있는지 체크합니다.
    item = inventory.getItem(index) // 인벤토리 트리거에서 'index'번 슬롯에 있는 아이템을 불러옵니다.
    clearLore(item) // 모든 로어(lore, 부가설명)을 삭제합니다.
    //서버 상태를 실시간으로 업데이트하는 로어를 추가합니다.
    addLore(item, placeholder.parse(player, "&7서버 상태&8: &6%pinger_isonline_"+address+"%"))
    // 서버에 접속되어 있는 온라인 플레이어 수(명)을 실시간으로 업데이트하는 로어를 추가합니다.
    addLore(item, placeholder.parse(player, "&7온라인&8: &6%pinger_players_"+address+"%"))
    // 서버 버전을 실시간으로 업데이트하는 로어를 추가합니다.
    addLore(item, placeholder.parse(player, "&7서버 버전&8: &6%pinger_gameversion_"+address+"%"))
    // 빈줄(공백)의 로어를 추가합니다.
    addLore(item, "")
    // message변수에 있는 내용을 color()를 이용하여 색을 적용한 후에 로어로써 추가합니다. 
    addLore(item, color(message))
    // 이제 모든 설정이 끝났기에 'index'번 슬롯에 'item' 아이템을 배치합니다.
    inventory.setItem(index, item)
ENDIF

내부 변수 목록

다음 목록은 인벤토리 트리거에서 사용할 수 있는 내부 변수입니다. 또한 You can also use all Third Party Internal Variables 페이지에 있는 변수도 모두 사용할 수 있습니다.

변수명 변수 타입 변수 설명
event Bukkit, Sponge 플레이어가 GUI를 열 때 발생하는 이벤트 입니다. open 행위 형식의 트리거에서 사용됩니다.
event Bukkit, Sponge 플레이어가 GUI에서 특정 슬롯을 클릭할 때 발생하는 이벤트 입니다. click 행위 형식의 트리거에서 사용됩니다.
event Bukkit, Sponge 플레이어가 GUI를 닫거나 자동으로 닫힐 때 발생하는 이벤트 입니다. close 행위 형식의 트리거에서 사용됩니다.
player Bukkit, Sponge 해당 이벤트를 실행시킨 플레이어를 받아옵니다.
inventory Bukkit, Sponge 플레이어가 트리거를 실행하여 현재 플레이어의 화면에 표시되어 있는 GUI를 받아옵니다. 이 변수로 해당 GUI에 아이템을 추가하거나 삭제할 수 있습니다.
item Bukkit, Sponge 플레이어가 클릭한 아이템을 받아옵니다.
slot Number 플레이어가 클릭한 슬롯을 받아옵니다.
trigger String 어떠한 형식의 트리거가 사용되었는지 판별하여 받아옵니다. ( open , click , close 중 하나)

변수에 대하여 더 알고 싶으시다면, Variables 문서를 참고하시기 바랍니다.

번역자 내용 추가) 해당 트리거는 체스트커맨드등의 플러그인 대용으로 사용할 수 있습니다.

Plugin Description / 목차

1. Getting Started () (рус)

S.L. In-game Editor () (рус)

2. Triggers () (рус)

List and usage of Triggers / 트리거 목록과 사용 방법:

  • List of Executors / 실행자(Executor) 목록

4. Placeholders () (рус)

  • Using PlaceholderAPI / PlaceholderAPI 사용법
  • List of Placeholders / 플레이스 홀더(Placeholder) 목록

5. Conditions () (рус)

  • Creating Conditions / 조건식 만들기
    • Boolean Expressions / 부울 (Boolean) 표현 방법
  • Logical Operators / 연산자 사용법
  • IF statement / IF 조건문
  • Null Checking / Null 검사법
  • Switch Case / Switch Case 조건

6. Variables () (рус)

  • Local Variables / 지역 변수
  • Global Variables / 전역 변수

Advanced

Timings () (рус)

7. Methods () (рус)

  • Using Methods / 메소드 사용법
  • Special Data Types / 특수한 데이터 형식
  • Reading Javadocs / Javadoc 읽기
  • Handling Enum / Enum 데이터 처리
  • Lambda Expresion / Lambda(람다) 식 사용법

8. Array () (рус)

  • Creating an empty array / 빈 배열 만들기
  • Storing data into array / 배열에 데이터값 저장하기
  • Read data from array / 배열에서 데이터 읽기(불러오기)

9. Loops () (рус)

  • WHILE loop / WHILE 반복문
  • FOR loop / FOR 반복문
    • Iterating Collection / Collection 형식의 변수 순회법
    • #BREAK executor / #BREAK 실행자
    • #CONTINUE executor / #CONTINUE 실행자

10. Sync Mode () (рус)

  • #CANCELEVENT executor / #CANCELEVENT 실행자
  • Setting Sync/Async Mode / 동기, 비동기 모드 전환
    • Custom Trigger
    • Area Trigger

11. Custom Executors () (рус)

12. Plugin Access () (рус)

  • Check And Use / 플러그인 존재여부 확인
    • Get Third Party Plugin / 제 3자 플러그인 불러오기
    • Check Eligibility / 호환성 확인하기
    • Use the Plugin / 플러그인 사용하기

13. IMPORT Statement () (рус)

  • Creating new instance / 새 인스턴스 생성하기
  • Accessing static method / 종속 메소드 불러오기
  • Accessing static field / 종속 Enum 불러오기

14. IS Statement () (рус)

  • Understanding / 이해하기
    • Understanding Instance / 인스턴스 이해하기
    • Understanding Superclass / 부모클래스 이해하기
    • Understanding Subclass / 자식클래스 이해하기
  • Using IS Statement / IS조건연산자 사용하기

15. TRY-CATCH Statement () (рус)

  • Understanding TRY-CATCH Exception Handling / TRY-CATCH 예외처리 이해하기

Misc

16. Interface Casting () (рус)

module x.x does not "opens x.x" problem

  • List of Custom Events

Examples

Trigger

Trigger Example () (рус)

More Examples: Bukkit, Sponge

Case Specific

Clone this wiki locally