Skript Vanilla GUIs

  • Welcome to skUnity!

    Welcome to skUnity! This is a forum where members of the Skript community can communicate and interact. Skript Resource Creators can post their Resources for all to see and use.

    If you haven't done so already, feel free to join our official Discord server to expand your level of interaction with the comminuty!

    Now, what are you waiting for? Join the community now!

Runakai

Supporter
Apr 27, 2018
496
32
28
21
You are looking for a good way of making GUIs in Skript? Without having to update an Addon or possibly risk that it's going to get unmaintained? Well, you cant stop searching now!


Because vanilla GUIs are integrated into Skript. That's how the name origins from. It's a vanilla feature from Skript. I will introduce you to the basic mechanichs of vanilla GUIs and show you multiple ways on how to set them up.
(PS: Best practice would be to go with metadata-values. You'll get what that is in a few minutes.)

In order to use vanilla GUIs it's always good to use the latest Skript version for your respective Minecraft version.
If you're still using 1.8.8 (Why? Update. Seriously. Gross.) you should be using dev36.
Link: https://github.com/SkriptLang/Skript/releases/download/dev36/Skript.jar
Link: https://github.com/Matocolotoe/Skript-1.8/releases/tag/2.5.3

(You may be wondering why there are 2 link! Gios fork (the bottom one) is recommended since it provides more features. Both work though.)

If you're using anything above 1.8.8 but below 1.13, so up to 1.12 you should be using Skript 2.6:
Link: https://github.com/SkriptLang/Skript/releases/tag/2.6
(this may be changed as of now this is the latest working version. It's going to be discontinued working for 1.12 on the next update.)

For anything above 1.12 the latest Skript version is recommended.
Link: https://github.com/SkriptLang/Skript/releases

Let me first describe to you in words how vanilla guis work.
Open an inventory
Set the slots however you like
Check every time a user clicks within the inventory, and do something based on that.

There are 3 ways to set up vanilla GUIs that basically work the same.

The first method that should be prioritized is using metadata.
Metadata means data within data. So basically it is like using variables. The only difference is that metadata have a holder that's usually an entity or a block and it gets deleted when the server stops since it's saved in RAM. Skript's metadata implementation can only store single values per metadata key per holder. So no lists are possible. It is great for saving information short-term based of a single entity or block.
In our case we use it to distinguish inventories.

I will just show you an example of opening inventories with metadata.

Code:
command /vanillaGUI:
    description: The best way of doing something.
    trigger:
        set metadata tag "vanillaGUI" of player to chest inventory with 3 rows named "&7Hello There"
        set slot 0 of metadata tag "vanillaGUI" of player to stone named "&6General Kenobi"
        open (metadata tag "vanillaGUI" of player) to player

Easy, right? Words confuse. Code doesn't.
One thing you will encounter while running that code is that you're able to steal your precious stone. You don't want that, right! Can't let players have fun huh.

Now we're doing the "check if player is clicking" thing. Trust me, it's easy.

Code:
on inventory click:
    #check if the clicked inventory is the one we just created
    if event-inventory = (metadata tag "vanillaGUI" of player):
        #cancel the clicking. This makes the Item unstealable
        cancel event

Et voilà you're done!

Now if you include both pieces of code in your script file you're good to go. Your stone is unstealable and your players are frustrated.

You can learn a bit more about the inventory click event,

To perform different actions you use the Inventory click event, add some conditions and based on that build your own little actions for individual slots OR the entire inventory!
Let's say you want to cancel every click in an inventory without checking each individual slot every time. Simply use this:

Code:
on inventory click:
    if event-inventory = (metadata tag "vanillaGUI" of player):
        #check if the clicked inventory is the one we just created
        cancel event
        #cancel the clicking. This makes the Item unstealable

Pretty self-explanatory, right? Cancel the event, cancel stealing.
The event-values for this event are:
Event-item:
Get the TYPE of an Item. If you click on a stone named "General Kenobi" this will only return stone.
Event-slot:
Get the clicked item including name etc.
Note: if you debug this expression solely, it will return something along "inventory slot X of Y". You can use it in a condition just fine
If event-slot is diamond named "X":
But if you want to get it in a send effect or similar, set a variable to the event-slot and use that variable.
Index of event-slot:
The index expression is universal but we use it to get the clicked slot. Numbers rangin from 0-54
Event-click type:
This is by far the most interesting one. Get the way a player clicked on an Item! All of them can be found here:
https://docs.skunity.com/syntax/search/id:5297
Event-inventory action:
Basically the same as event-click type, just with more options and possibilities such as detecting if a player picked up all of the items or half of the stack etc. List can be found here:
https://docs.skunity.com/syntax/search/id:5153
Event-Inventory:
Get the type of the event-inventory. Ranging from Hoppers to Chests up to Brewing stands etc. A list of them can be found here:
https://docs.skunity.com/syntax/search/id:5321

Remember how I said there are 3 different ways to make vanilla GUIs? I will not describe them much since as I said, they are very similar.
You still open an inventory and see within the inventory click event if it's the desired one.


Instead of using metadata we're using variables. Same thing basically.

code_language.skript:
command /vanillaGUI:
    description: The second best way of doing something.
    trigger:
        set {Inventory::%player%} to chest inventory with 1 row named "Vanilla!"
        set slot 0 of {Inventory::%player%} to stone named "&6General Kenobi"
        open {Inventory::%player%} to player

on inventory click:
    #check if the clicked inventory is the one we just created
    if event-inventory is {Inventory::%player%}:
        #cancel the clicking. This makes the Item unstealable
        cancel event

Nothing more to explain. You set a variable now instead of metadata.

You know if you're lasy, this is perfectly fine to use. Instead of setting a holder (variable or metadata) to an inventory, you just open it.


code_language.skript:
command /vanillaGUI:
    description: The laziest best way of doing something.
    trigger:
       open chest inventory with 4 rows named "&cLazy gurl." to player
       set slot 0 of player's current inventory to stone named "&6General Kenobi"

on inventory click:
    #check if the clicked inventory is the one we just created
    if name of event-inventory is "&cLazy gurl.":
        #cancel the clicking. This makes the Item unstealable
        cancel event

Note that this method does not work on 1.14 unless you are using SkBee. You shouldn't be on 1.14 anyway since server performance is baaad.


The following code is just an example on how to use this system.

Code:
command /vanillaGUI:
    description: The best way of doing something.
    trigger:
        set metadata tag "vanillaGUI" of player to chest inventory with 3 rows# named "&7Hello There"
        set slot 0 of metadata tag "vanillaGUI" of player to stone named "&6General Kenobi"
        set slot 1 of metadata tag "vanillaGUI" of player to player's skull named "&6%player%" with lore "&7Right click me to receive my head!"
        open (metadata tag "vanillaGUI" of player) to player

on inventory click:
    if event-inventory = (metadata tag "vanillaGUI" of player):
        #check if the clicked inventory is the one we just created
        cancel event
        #cancel the clicking. This makes the Item unstealable
        if index of event-slot is 0:
            #check if the clicked slot is the stone, so 0
            give event-slot to player
            #give the clicked item to the player.
        else if index of event-slot is 1:
            #check if the clicked slot is the skull, so 1
            if event-click type is right mouse button:
                #check if the player right clicks the item
                set {_playerHead} to uncolored name of event-slot parsed as player
                give event-slot to player
                send "&6Player %player% has received a skull of you!" to {_playerHead}
                #since we can't use arguments, we just parse the name of the event-slot and get the skull by doing that.
                #you can use the variable as you like. I simply sent a plain text to the player.
                #ban {_playerHead} would also work
                #using NBT will work as well!


If you have any questions let me know in the comment section.

Some Snippets. Some of them require skript-reflect Since it's the most superior add-on you should have it installed anyway. The metadata fix doesn't require skript-reflect.
(Skript-reflect is a fork of skript-mirror)
Code:
import:
    org.bukkit.event.inventory.InventoryClickEvent
expression [event( |-)]([number ]key|hot[[ ]bar][ key])[ button]:
    return type: integer
    get:
        return event.getHotbarButton() + 1 if event.getHotbarButton() != -1
        return -1

expression [event( |-)]([number ]key|hot[[ ]bar][ key])[ button]( |-)slot:
    return type: integer
    get:
        return event.getHotbarButton() if event.getHotbarButton() != -1
        return -1
Code:
function compare(1: inventory, 2: inventory) :: boolean:
    return false if (name of {_1}) != (name of {_2})
    return false if (rows of {_1}) != (rows of {_2})
    return false if type of {_1} != type of {_2}
    return true
Code:
command /gui:
    trigger:
        set metadata tag "vanillaGUI" of player to chest inventory with 3 rows named "Best GUIs"
        set slot 1 of (metadata tag "vanillaGUI" of player) to diamond hoe named "&d:("
        open (metadata tag "vanillaGUI" of player) to player
on inventory click:
    if compare(metadata tag "vanillaGUI" of player, event-inventory) = true:
        cancel event
Thanks to mr.gigi for providing a workaround!
 
Last edited by a moderator:
Sorry but I have a concern using the skript vanila GUI.
I tried to prevent stealing from all type of clicking, but it seems that the expression
Code:
cancel event
only works with left click, while the other click type can still steal the item. How can I solve that?
 
Sorry but I have a concern using the skript vanila GUI.
I tried to prevent stealing from all type of clicking, but it seems that the expression
Code:
cancel event
only works with left click, while the other click type can still steal the item. How can I solve that?
That's something that appeared to me as well, should've mentioned it in the tutorial, you're right! Normally every click should get cancelled however, sometimes it doesn't. I fixed that by adding a condition to see what kind of click type was still able to steal the item and cancel that. That's annoying, I know but it doesn't appear for everyone! On my localhost server it seemed to work perfectly fine on my hosted server however it didn't. Maybe installing newer versions if skript/paper fixes the issue
 
That's something that appeared to me as well, should've mentioned it in the tutorial, you're right! Normally every click should get cancelled however, sometimes it doesn't. I fixed that by adding a condition to see what kind of click type was still able to steal the item and cancel that. That's annoying, I know but it doesn't appear for everyone! On my localhost server it seemed to work perfectly fine on my hosted server however it didn't. Maybe installing newer versions if skript/paper fixes the issue

But I am already using the latest version of skript, which is v2.5-alpha2. So is there another solution?
 
May show me the code?
It is so long, but I already put "cancel event" under ALL tab of my custom GUIs, without considering the click type.
Even if I do something like this:

Code:
on inventory click:
    if event-inventory is not player's inventory:
        if event-click type = left mouse button:
            cancel event
            # Generate some GUI shits
        else:
            cancel event
or this:
Code:
on inventory click:
    if event-inventory is not player's inventory:
        cancel event
        # Generate some GUI shits
also doesn't work.
 
It is so long, but I already put "cancel event" under ALL tab of my custom GUIs, without considering the click type.
Even if I do something like this:

Code:
on inventory click:
    if event-inventory is not player's inventory:
        if event-click type = left mouse button:
            cancel event
            # Generate some GUI shits
        else:
            cancel event
or this:
Code:
on inventory click:
    if event-inventory is not player's inventory:
        cancel event
        # Generate some GUI shits
also doesn't work.
I don't know then, the "ugly" way of cancelling would be to set a variable to the cursor slot, set the cursor slot to air and then setting the original slot to the item in the variable
 
  • Like
Reactions: barrybtw
I don't know then, the "ugly" way of cancelling would be to set a variable to the cursor slot, set the cursor slot to air and then setting the original slot to the item in the variable
What is the expression to get or modify cursor slot?
 
Hi, sorry for replying to such an old thread, but I can't seem to get it to work for an item in the GUI triggering another guy. I can open the GUI, but I can't seem to make the items in the second GUI unstealable. here is code:
Code:
on right click on villager:
    if player is sneaking:
        teleport target to location 200 meters below target
    else:
        cancel event
        set {_name} to name of target entity
        set {_uuid} to target entity's uuid
        set metadata tag "npcgui.%{_uuid}%" of player to chest inventory with 1 row named "%{_name}%"
        set slot 1 of metadata tag "npcgui.%{_uuid}%" of player to writable book named "&6Talk"
        set slot 4 of metadata tag "npcgui.%{_uuid}%" of player to emerald named "&aTrade"
        set slot 7 of metadata tag "npcgui.%{_uuid}%" of player to ender pearl named "&1Quest"
        open (metadata tag "npcgui.%{_uuid}%" of player) to player
on inventory click:
    if event-inventory = (metadata tag "npcgui.63a60701-09cb-4235-a347-42b8ff9344cb" of player):
        cancel event
        if index of event-slot is 1:
            close inventory of player   
            play sound "entity.experience_orb.pickup" with volume 0.5 to the player
            send subtitle "&6Hi there! The name's Bernard." to player
            wait 2 seconds
            play sound "entity.experience_orb.pickup" with volume 0.5 to the player
            send subtitle "&6I found you lying unconscious outside my house." to player
            wait 2 seconds
            play sound "entity.experience_orb.pickup" with volume 0.5 to the player
            send subtitle "&6You had a nasty burn on your shoulder, I fixed you up." to player
            wait 2 seconds
            play sound "entity.experience_orb.pickup" with volume 0.5 to the player
            send subtitle "&6Care to repay me? Water's scarce these days..."
        else if index of event-slot is 4:
            set {_name} to name of targeted entity
            set metadata tag "npctrade.%{_uuid}%" of player to chest inventory with  3 rows named "%{_name}%&e's Trades"
            set slot 0 of metadata tag "npctrade.%{_uuid}%" of player to trident named "&3Pitchfork" with lore "&6ATK: 2"
            open (metadata tag "npctrade.%{_uuid}%" of player) to player
        else if index of event-slot is 7:
            send "&6Quests are still a work in progress!" to player
            close player's inventory
on inventory click:
    if event-inventory = (metadata tag "npctrade.63a60701-09cb-4235-a347-42b8ff9344cb" of player):
        cancel event
Thanks for any help!
 
  • Like
Reactions: barrybtw
No, this code includes two GUIs, the first one has an item which should trigger the second.
You do not have a target entity in the inventory click event. Your uuid local variable is not set in the inventory click
 
  • Like
Reactions: barrybtw
Hello, Sir:emoji_slight_smile:

I am making various GUIs by vanilla GUI.
But I found a error.
That is, when I press the shift key and the mouse button together, the items in the GUI are automatically imported in my inventory.
It cans be a fatal flaw in my project.
How can I stop it?

* I know this code "if click type is left mouse button with shift:" and "cancel event", but it wasn't work as I want.
 
Hello, Sir:emoji_slight_smile:

I am making various GUIs by vanilla GUI.
But I found a error.
That is, when I press the shift key and the mouse button together, the items in the GUI are automatically imported in my inventory.
It cans be a fatal flaw in my project.
How can I stop it?

* I know this code "if click type is left mouse button with shift:" and "cancel event", but it wasn't work as I want.
Hey, could you provide us with code?
 
Vanilla GUIs ~ Create your own little world in a prison called inventory

Are you looking for a good way of making GUIs in Skript? Then you're more than welcome to read this tutorial. If you have used vanilla GUIs before I recommend to read this page again since it will include some useful information and will only require vanilla Skript now since we're approaching them differently now. No need for Skript-mirror, SkQuery or Sk-Bee to get the inventory name. We don't need them. Not even on 1.8! The only thing you need on 1.8 is to see a doctor.
Metadata comparison does not work on 1.12. You need to use a snippet that's provided at the bottom of the tutorial!

Preparation
To get started you need following Skript versions:
Using Vanilla Skript is possible by having the Skript version 2.2dev36. They can be used earlier on but since 2.2dev36 is recommended for 1.8, use that. Since we will focus on Metadata however, dev36 is needed. If you need it to work on earlier versions, use the name of event-inventory effect. You can still use metadata though! Try metadata and just use it.

Link:
https://github.com/SkriptLang/Skript/releases/download/dev36/Skript.jar

Just use the latest version of skript and you're fine.
Link: https://github.com/SkriptLang/Skript/releases
Okay, let me explain how vanilla GUIs work by describing it. You open an inventory and set the slots. Every time you click on the slot you check if certain conditions are met. Based on that you perform effects. You didn't understand that? Look at that:


Code:
command /vanillaGUI:
    description: The best way of doing something.
    trigger:
        set metadata tag "vanillaGUI" of player to chest inventory with 3 rows named "&7Hello There"
        set slot 0 of metadata tag "vanillaGUI" of player to stone named "&6General Kenobi"
        open (metadata tag "vanillaGUI" of player) to player


What is metadata?

Metadata means data within data. So basically it is like using variables. The only difference is that metadata have a holder that's usually an entity or a block and it gets deleted when the server stops since it's saved in RAM. Skript's metadata implementation can only store single values per metadata key per holder. So no lists are possible. It is great for saving information shor-term based of a single entity or block.
In our case we use it to distinguish inventories.

Inventory Click Event

To perform different actions you use the Inventory click event, add some conditions and based on that build your own little actions for individual slots OR the entire inventory!
Let's say you want to cancel every click in an inventory without checking each individual slot every time. Simply use this:

Code:
on inventory click:
    if event-inventory = (metadata tag "vanillaGUI" of player):
        #check if the clicked inventory is the one we just created
        cancel event
        #cancel the clicking. This makes the Item unstealable

Pretty self-explanatory, right? Cancel the event, cancel stealing.
The event-values for this event are:

Event-item:
Get the TYPE of an Item. If you click on a stone named "General Kenobi" this will only return stone.
Event-slot:

Get the clicked item including name etc.
Index of event-slot:

The index effect is universal but we use it to get the clicked slot. Numbers rangin from 0-54
Event-click type:

This is by far the most interesting one. Get the way a player clicked on an Item! All of them can be found here:
https://skripthub.net/docs/?id=2137
Event-inventory action:

Basically the same as event-click type, just with more options and possibilities such as detecting if a player picked up all of the items or half of the stack etc. List can be found here:
https://skripthub.net/docs/?id=2149
Event-Inventory:

Get the type of the event-inventory. Ranging from Hoppers to Chests up to Brewing stands etc. A list of them can be found here:
https://skripthub.net/docs/?id=2151

Let's make a bit of code!


Code:
command /vanillaGUI:
    description: The best way of doing something.
    trigger:
        set metadata tag "vanillaGUI" of player to chest inventory with 3 rows# named "&7Hello There"
        set slot 0 of metadata tag "vanillaGUI" of player to stone named "&6General Kenobi"
        set slot 1 of metadata tag "vanillaGUI" of player to player's skull named "&6%player%" with lore "&7Right click me to receive my head!"
        open (metadata tag "vanillaGUI" of player) to player
 
on inventory click:
    if event-inventory = (metadata tag "vanillaGUI" of player):
        #check if the clicked inventory is the one we just created
        cancel event
        #cancel the clicking. This makes the Item unstealable
        if index of event-slot is 0:
            #check if the clicked slot is the stone, so 0
            give event-slot to player
            #give the clicked item to the player.
        else if index of event-slot is 1:
            #check if the clicked slot is the skull, so 1
            if event-click type is right mouse button:
                #check if the player right clicks the item
                set {_playerHead} to uncolored name of event-slot parsed as player
                give event-slot to player
                send "&6Player %player% has received a skull of you!" to {_playerHead}
                #since we can't use arguments, we just parse the name of the event-slot and get the skull by doing that.
                #you can use the variable as you like. I simply sent a plain text to the player.
                #ban {_playerHead} would also work
                #using NBT will work as well!


If you have any questions let me know in the comment section.

Some Snippets. Some of them require skript mirror 2.0.0. Since it's the most superior add-on you should have it installed anyway. The metadata fix doesn't require skript mirror .
Code:
import:
    org.bukkit.event.inventory.InventoryClickEvent
expression [event( |-)]([number ]key|hot[[ ]bar][ key])[ button]:
    return type: integer
    get:
        return event.getHotbarButton() + 1 if event.getHotbarButton() != -1
        return -1

expression [event( |-)]([number ]key|hot[[ ]bar][ key])[ button]( |-)slot:
    return type: integer
    get:
        return event.getHotbarButton() if event.getHotbarButton() != -1
        return -1
Code:
function compare(1: inventory, 2: inventory) :: boolean:
    return false if (name of {_1}) != (name of {_2})
    return false if (rows of {_1}) != (rows of {_2})
    return false if type of {_1} != type of {_2}
    return true
Code:
command /gui:
    trigger:
        set metadata tag "vanillaGUI" of player to chest inventory with 3 rows named "Best GUIs"
        set slot 1 of (metadata tag "vanillaGUI" of player) to diamond hoe named "&d:("
        open (metadata tag "vanillaGUI" of player) to player
on inventory click:
    if compare(metadata tag "vanillaGUI" of player, event-inventory) = true:
        cancel event

[/COLOR]
Thanks for mr.gigi for providing a workaround!
"The only thing you need on 1.8 is to see a doctor."
thanks for the tutorial, but more than %50 of Minecraft use 1.8.
Thats like idk more than 50k people? My guess?
 
"The only thing you need on 1.8 is to see a doctor."
thanks for the tutorial, but more than %50 of Minecraft use 1.8.
Thats like idk more than 50k people? My guess?
Could you provide us with source?
 
Is there more lag using vanilla guis? Because I have heard if you use an addon, it generates less lag.
 
medatada comparison works on 1.12.2 very well for me, I recommend removing that outdated warning
I still see people having problems on 1.12 and metadata. I might want to rephrase that warning but I'll not remove it.
[doublepost=1605435076,1605435036][/doublepost]
Is there more lag using vanilla guis? Because I have heard if you use an addon, it generates less lag.
It's the other way around. Vanilla skript will always be faster than using addons
 
I know some addons are buggable, where you can bug out items of the GUI, but how is it with vanilla GUI's? Are they safe to use, where players can't bug out items from the GUI? Thank you :emoji_slight_smile:
 
I know some addons are buggable, where you can bug out items of the GUI, but how is it with vanilla GUI's? Are they safe to use, where players can't bug out items from the GUI? Thank you :emoji_slight_smile:
Hey, it's save to use vanilla GUIs. It's the main method of doing GUIs anywhere and they're save :emoji_stuck_out_tongue: