Skip to content
gerzytet edited this page Dec 9, 2019 · 41 revisions

Activates when GUI is opened, clicked, or closed

In the new design, there will be one .yml file which saves the Size of the inventory, and pre-defined items for the inventory. Then, you will have one flat file that has same name as the .yml file with the actual code file. Unlike the previous design, you have to specify the slot numbes yourself when you add items and define the behaviors depending on the slot number.

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

Creating new Inventory Trigger

As an example, type

/trg i Test create 54

This will create an Inventory Trigger with capable of 54 slots. The size should be always multiple of 9 and should not be larger than 54

You can check plugins/TriggerReactor/InventoryTrigger/ folder to see the following two files are created:

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

TIP) Even though you can one line code like this:

/trg i Test create 54 #MESSAGE "HI"

It's not recommended to define inventory triggers in this way as it will run every time the inventory opens, is clicked on, and closes. There is a specific variable you can use to distinguish what 'triggered' this trigger, so I highly recommend to write your code in in-game code editor or notepad etc.

Trigger behavior (since 0.1.8)

There are three possible events that can an trigger Inventory Trigger: open, click, and close. The internal variable 'trigger' will change depending on which one triggered the script, and you can use an IF statement to differentiate them.

IF trigger == "open"
    ...
ENDIF

IF trigger == "click"
ENDIF

and so on.

You might wonder how three events are handled while having only one trigger; the answer is multi-threading. You don't have to understand what 'multi-threading' is, but you have to know that every time a trigger is activated, the script runs inside of its own 'task,' and that task is seperate than any other tasks that are running. For example, if you click the first item in an inventory, and you click it again, then you have total of two 'tasks' running at the same time that do the exact same thing. They run concurrently!

Concurrency issue

Most of time, you don't want two identical tasks running at the same time. Imagine the following scenario: You have created a slot machine game with Inventory Trigger, and if people can activate the start button while the previous one is already running, then they have no delay between every game. That's why you need to stop this using a local variable. Unlike other triggers, any local variables will be preserved for the 'inventory' until it is closed. For example:

IF trigger == "click"
    IF slot == 0
        FOR 0:10
            do some slot thing
            #WAIT 1
        ENDFOR
    ENDIF
ENDIF  

In this case, the start button in slot index 0 will start the FOR loop for 10 seconds (because WAIT waits 1 second each loop), and you do not want people to start another FOR loop while previous loop is running. To do so:

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

        isRunning = true
        FOR 0:10
            do some slot thing
            #WAIT 1
        ENDFOR
        isRunning = false
    ENDIF
ENDIF

Basically, it stops the trigger right away if isRunning is set to true. Whenever the FOR loop of previous 'task' is done, the isRunning will set back to false, so user can click the slot 0 button again.

This is possible because all the tasks share the variables together. So you can safely assume that the isRunning will be both shared between two tasks

There are a lot of variations to do it, so take your time to come up with the best solution!

WARNING! Do not put an infinite loop inside the trigger == "close" section. It’s safe to put infinite loops inside of the open or click sections because the trigger will just stop when the inventory closes, but TriggerReactor cannot automatically stop the "close" section because it starts after the inventory closes.

However, you are encouraged to put infinite loop inside the "open," so you can update the item, title, or lore in real time. This can be useful if you want to implement animation for your inventory trigger. If you use an infinite loop inside of the open section, use #WAIT to give some delay between loop iterations! Without the #WAIT, the inventory will be updated too fast, and it can suck up all the CPU usage.

Adding icon

Now you made your Inventory Trigger, you need to add the icon that will be shown to the users.

to do so, try the following command while holding an item:

/trg i Test item 0

Notice that the index numbers of Inventories start at 0 not 1.

Deleting icon

Simply use the same command as add command, but this time, do not hold anything on your hand.

/trg i Test item 0

it will delete the icon at index 0

Editing Inventory Trigger

Simply use

/trg i <name> edit

Command.

Deleting Inventory Trigger

Use following command will delete the Inventory Trigger; this cannot be undone, so be careful!

/trg i Test delete

Set custom title and lore for icons

You can set title and lore using simple command provided by TriggerReactor

To change title

/trg item title &aMyTitle

To add lore

/trg item lore add &6Lore1

To delete lore

/trg item lore remove 0

To reset lore

/trg item lore set 0 &7New lore!

Color

You might wonder why the color is not shown but the & sign and color code are.

the reason is because TriggerReactor will not evaluate the color code until the item is displayed in an Inventory Trigger. This is because adding color code right into the item is troublesome when it comes to saving them into the yml file.

Additionally, UTF-8 symbols don’t work with some text editors, and minecraft’s color code symbol is a UTF-8 symbol.

Long example

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

IF trigger == "open" // This only happens when the inventory first open
    WHILE true // infinite loop is safe in the "open" as closing the inventory will terminate it later.
        //sky
        index = 0 //set index variable to zero before calling "Bungee:ItemServerInfo" NamedTrigger
        address = "127.0.0.1:25501" //set address variable
        message = "&a>> Click to move to wild server" //set message variable
        #CALL "Bungee:ItemServerInfo" //now let the "Bungee:ItemServerInfo" NamedTrigger to handle the rest
        //war
        index = 2
        address = "127.0.0.1:25502"
        message = "&a>> Click to move to pvp server"
        #CALL "Bungee:ItemServerInfo"
        //mini
        index = 4
        address = "127.0.0.1:25503"
        message = "&a>> Click to move to minigames server"
        #CALL "Bungee:ItemServerInfo"

        #WAIT 1 //be aware of this part. This makes the loop to wait for one second before proceed
                //without the #WAIT, the update will be too fast, and it will be buggy on client side
        
        //sky
        index = 0
        address = "127.0.0.1:25501"
        message = "&f>> Click to move to wild server"
        #CALL "Bungee:ItemServerInfo"
        //war
        index = 2
        address = "127.0.0.1:25502"
        message = "&f>> Click to move to pvp server"
        #CALL "Bungee:ItemServerInfo"
        //mini
        index = 4
        address = "127.0.0.1:25503"
        message = "&f>> Click to move to minigames server"
        #CALL "Bungee:ItemServerInfo"

        #WAIT 1
    ENDWHILE
ENDIF

IF trigger == "click" // This is when a player click the slot. Doesn't matter if there is icon or not.
                      // Still will be called even if the slot is empty.
    IF isCoolddown // check if the player pressed icon too quickly.
                   // notice that if isCooldown is not set, it will be treated as false
                   // check out Conditions section of Wiki for more information.
        #MESSAGE "&6Please slow down!"
        #STOP //stop the trigger immediately, so the codes below will not be executed
    ENDIF
    
    isCoolddown = true // set isCooldown to 'true.' This will stop player from clicking the slot until
                       // isCooldown is set to 'false' again.
    
    IF slot == 0
        #SERVER "skyblock"
        #BROADCAST "&8[&6ServerMove&8]&7 &6"+$playername+" &7-> &6Wild"
    ENDIF
    IF slot == 2
        //#SERVER "war"
        //#BROADCAST "&8[&6ServerMove&8]&7 &6"+$playername+" &7-> &6War"
    ENDIF
    IF slot == 4
        #SERVER "minigames"
        #BROADCAST "&8[&6ServerMove&8]&7 &6"+$playername+" &7-> &6MiniGames"
    ENDIF
    
    #WAIT 1 // wait for one second
    isCoolddown = false // now set isCooldown to false so player can click the slots again.
ENDIF

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

//'inventory' inventory to update
//'index' item index
//'address' address of server
//'message' message color

IF placeholder //check if PlaceholderAPI exists.
    item = inventory.getItem(index) // get item in the 'index'th slot of the inventory
    clearLore(item) // first delete all lores
    addLore(item, placeholder.parse(player, "&7Status&8: &6%pinger_isonline_"+address+"%"))
    addLore(item, placeholder.parse(player, "&7Online Players&8: &6%pinger_players_"+address+"%"))
    addLore(item, placeholder.parse(player, "&7Version&8: &6%pinger_gameversion_"+address+"%"))
    addLore(item, "")
    addLore(item, color(message))
    inventory.setItem(index, item) // you put item back the inventory
ENDIF

Executors and Placeholders for inventory triggers

#SETSLOT Coming in 3.0

  • SETSLOT {slot} {item} Set the slot number of the inventory trigger to the item. This is not a permanent change, it will only apply to the current player and only last until the inventory trigger stops.

$slot $slot:0 Coming in 3.0

Gets the item in slot number specified.

Internal Variables

This is a list of the internal variables you can use in your inventory triggers. You can also use all Third Party Internal Variables.

Variable Data Type Description
event Bukkit, Sponge The event called when a player opens an inventory. Used in open trigger.
event Bukkit, Sponge The event called when a player clicks a slot in an inventory. Used in click trigger.
event Bukkit, Sponge The event called when a player closes an inventory. Used in close trigger.
player Bukkit, Sponge Player who triggered the event
inventory Bukkit, Sponge The current inventory the playing is looking at. You may add or delete items to/from GUI dynamically with it.
item Bukkit, Sponge The item player clicked.
slot Number Clicked slot number
trigger String Indicates what trigger is being used. (open, click, or close)

To learn more about variables, see 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