Skip to content

Examples

butterwaffles edited this page Jan 6, 2024 · 1 revision

Examples

The following code is used in the context of Minecraft cannoning, where such GUIs are useful when testing cannons on cannon test servers.

To register any GUI (must extend the abstract class BaseGui, have the required annotations [TypeAlias, GuiTitle, GuiSize], and one method annotated with DefaultContents, the code is:

val guiApi = VerneGui.get()
guiApi.register(MagicSandGui::class)
guiApi.register(TracersGui::class)

Retrieving an instance of the MagicSandGui (which is the static example), or TracersGui (the dynamic example) is as simple as this (requires the init method to be called, which is shown after):

// assuming a player variable is present
val guiApi = VerneGui.get()
val staticGui= guiApi[MagicSandGui::class]
val dynamicGui = guiApi[TracersGui::class, player] // player being an instance of org.bukkit.entity.Player

The order in which GUIs or dependencies are registered does not matter, but they all have to be configured before the final init method on the API is called:

val guiApi = VerneGui.get()

// register GUIs and dependencies in between

guiApi.init(plugin) // the plugin variable being the instance of your plugin

Static GUI Example

Magic Sand GUI

@TypeAlias(type = STATIC)
@GuiTitle(
    value = MAGIC_SAND_GUI_NAME, 
    color = ChatColor.LIGHT_PURPLE, 
    bold = true,
)
@GuiSize(rows = 3)
class MagicSandGui : BaseGui() {
    @DefaultContents
    fun onDefault() {
        contents.fill(DefaultItems.FILLER_PANE.item)

        contents.close(
            row = 2, column = 2,
            item = MAGIC_SAND,
        ) { player ->
            player.setHandItem(MAGIC_SAND)
        }
    }
}

This GUI when registered would create a static GUI that is used by all players and has one slot that when clicked closes the inventory of the player and adds a special item to their inventory.

Dynamic GUI Example

Tracers GUI

@TypeAlias(DYNAMIC)
@GuiTitle(
    value = TRACERS_GUI_NAME, 
    color = LIGHT_PURPLE, 
    bold = true,
)
@GuiSize(rows = 3)
@ClickDelay(delay = 10L)
class TracersGui : BaseGui() {
    @Dependency private lateinit var settings: TracerSettingsContainer //some data class storing some player settings

    @DefaultContents
    fun onDefault() {
        contents.fill(FILLER_PANE.item)

        contents.set(
            row = 2, column = 1,
            item = tracerToggleItem(settings.enabled), //some function that creates an item based on a boolean setting
        ) { player, _ -> // the second parameter storing the clickType can be used, but is not used here
            settings.enabled = !settings.enabled //change the settings

            player.sendMessage("setting updated") //some message for feedback
        }
    }
}

This GUI when registered creates a dynamic GUI for each player and injects the TracerSettingsContainer dependency on creation which can be used to dynamically update items within a GUI. On every player click of a clickable item, the GUI is refreshed and all of the contents are cleared in addition to the onDefault method being called to recreate the items. This GUI also has a 0.5 second delay, where clickable items can only be clicked and handled every 0.5 seconds, or 10 gameticks.

This would require that a resolver be registered for injecting the instance of TracerSettingsContainer for each player GUI instance, especially for if one wants to have persistent data:

val guiApi = VerneGui.get()
guiApi.registerDynamic(TracerSettingsContainer::class) { player, plugin ->
    // code to create or retrieve the instance
}

Clone this wiki locally