[Open Source] SkyBlock Minecraft Addon - Loot boxes added [New feature #13]
![](https://steemitimages.com/640x0/https://cdn.steemitimages.com/DQmTbYLVt4AAUQv6eHQUdCgt3egxX9FcmLs4HoFy5Fmpipn/3.png)
Now, server operators can use loot boxes and give their player all kinds of items and tools using the loot box add-on.
Hello steemians and Minecraft players,
Today, I have to show off a new add-on for SKYBLOCK.SK, a Minecraft game mode, which allows server operators a completely customizable SkyBlock game server experience without the need to know Java. The new add-on is very useful, because server operators can also give away items, which have been added by other SKYBLOCK.SK add-ons, like JetBoots or Storage units.
This allows the server operator have some super custom configurations and rewards. Loot boxes are a way of multiple on how to engage users to vote for the server, it is very important for servers to engage their users to vote for them to increase the chance of getting more players.
1. Repository
https://github.com/Abwasserrohr/SKYBLOCK.SK
2. Index
- Repository
- Index
- New Features
3.1. Added loot boxes - Pull requests
- GitHub Account
- How to contribute
3. New Features
3.1. Added loot boxes
This time, I want to only show off one big change, the loot box add-on. I created multiple different loot box prototypes and this one I now show off managed to be the best one, which I finalized through the last days by asking the community how they like the process the best and this is what it turned out to be.
A video of the loot box opening process, the idea was to make the process feel rewarding, if the player gets something. Also the chance each time to win big should give the player some reason to get those loot boxes. The loot boxes could be given away for voting for the server.
The add-on contains multiple functionalities:
/givelootbox <tier> <player> [<amount>] [<boolean>]
:
This command allows the admin or the console to give out loot boxes.
The tier can be defined between 1, 2 or 3.
If the boolean is true, the player gets the loot box as a variable stored on the server, if it is not set, the physical version is preferred./openloot
:
The/openloot
command calls theopenlootboxmenu(p:player)
function.openlootboxmenu(p:player)
function:
This function opens the loot boxes menu, which displays all available loot boxes of the different tiers to the player.openlootbox(p:player,tier:integer)
function:
Theopenlootbox
function is called through theopenlootboxmenu(p:player)
function, if a player clicks on a item there, the loot box opening can be started by the player.startlootbox(p:player,tier:integer)
function:
This function starts the loot box opening and also generates the random items, which have predefined chances.cratereward(p:player,reward:item)
function:
Once thestartlootbox
function is done, it knows what the player should get as a reward. The loot box reward process is made by thecratereward(p:player,reward:item)
, which creates an animation with particles and falling items from the sky to make the whole experience more interesting.
Now, I want to show some parts on how the process of the random item slot is working.
function startlootbox(p:player,tier:integer):
To get things started, I decided to show off the entire startlootbox
function today. I really like the idea of having some small snippets but this whole thing kind of makes only sense of I show it in it's whole "glory" :P
set {_item} to {@lootboxitem}
set {_i} to 0
setguiitem({_p},13,"{@lootboxitem}",1," "," ","actionbar(""%{_p}%"" parsed as player,"" "")",false)
Once the function is called, the loot box triggering item in the menu is replaced instantly with another item which only sends an empty message to the player if clicked, which results in nothing happening. This is needed to prevent the player from starting the function multiple times. It is predefined that the item is in the slot 13 and easy to change out because of that.
if line 3 of lore of {_p}'s tool contains "&0|%{_tier}%":
set {_tool} to {_p}'s tool
remove 1 of {_tool} from {_p}'s inventory
There are two "types" of loot boxes, the physical ones and the virtual loot boxes. If the player opened a physical one, we can remove it here.
else:
set {_uuid} to uuid of {_p}
set {_lang} to {SK::lang::%{_uuid}%}
if {SR::crates::%{_uuid}%} is not set:
set {SR::crates::%{_uuid}%} to "0||0||0"
set {_crates::*} to {SR::crates::%{_uuid}%} split at "||"
loop {_crates::*}:
if loop-index is "%{_tier}%":
set {_crates::%loop-index%} to {_crates::%loop-index%} parsed as integer
remove 1 from {_crates::%loop-index%}
set {SR::crates::%{_uuid}%} to "%{_crates::1}%||%{_crates::2}%||%{_crates::3}%"
If the player opened a virtual loot box, we have to get the crates variable string, which looks like this: "1||5||0", which means that the player has 1 of tier 1 loot box, 5 of tier 2 loot boxes and 0 of tier 3 loot boxes. This string is then separated into a list out of three values, which are parsed as integer to make changes on it possible. Once that's done, it is saved back to the variable as a string. The reason to make a string instead of having three variables is that it is more resource intensive to save three integers instead of one singe string because the variable names have to be saved and loaded too, saving them three times would increase the amount more and more.
Once I got some more time and the players have no more new ideas, I might want to add a function which allows a json like format storage within a file for every player which only gets into the memory of the server if it is really needed. Variables in Skript are very fast but data which isn't needed anytime and not that much used might be better not instantly accessed and only loaded if it is really needed which can save some resources on the server.
wait 5 ticks
loop 27 times:
setguiitem({_p},{_i},"{@secondarymenuitem}",1," "," ","actionbar(""%{_p}%"" parsed as player,"" "")",true)
add 1 to {_i}
Then we let the player wait for 5 ticks, that's about 0.25 seconds to make the process look better.
After that, the whole inventory is set to a predefined inventory decoration item. Default: black glass pane. This looks quite nice on the inventories of Minecraft Vanilla and that's why I'm using it. =) Because this is an option, the server operator can easily change that on top of the add-on file.
set slot 4 of {_p}'s current inventory to {@primparymenuitem} named " "
set slot 22 of {_p}'s current inventory to {@primparymenuitem} named " "
set slot 13 of {_p}'s current inventory to air
Then, the marking spots are created, which signalize the player where then has to stop to get it. I hope it is understandable what I mean with that but I'm talking about the two yellow stained glass panes, which are also visible in the video. ^^
set {_cinv} to {_p}'s current inventory
Getting the current inventory is necessary to prevent any item gliches into the inventory of the player, which would be very nice for players to abuse but not good for the server operator. =D
In a following pull request, the current inventory is set directly after the function call. Since the player currently has 5 ticks time to go out of the menu and get some bugged items from it.
set {_loot::*} to {SB::crates::%{_tier}%::loot::*}
set {_chance::*} to {SB::crates::%{_tier}%::chance::*}
Every loot box tier has its own chances and loots, take the loot and chances out of the existing variables into new local variables to help the eyes...
set {_lootslots} to "1"
The {_loopslots}
contains the list index of all items which are displayed within the slots of the random item slot. To start, there is only "1", which is going to get bigger while the function is running. If there is a "1", it means that this item is the first one in the {SB::crates::%{_tier}%::loot::*}
list.
set {_world} to {_p}'s world
set {_loc} to {_p}'s location
set {_loops} to 0
set {_wait} to 1 tick
set {_done} to false
Setting some local variables, they're needed within the while loop and that's why they are defined before starting with it to prevent writing them too much... =)
while {_done} is false:
wait {_wait}
playsound({_p},location of {_p},"{@movesound}","master",1,1)
add 1 to {_loops}
if {_loops} >= 15:
set {_r} to random integer between 1 and 2
if {_r} is 1:
add 1 tick to {_wait}
As long as the {_done}
variable is false, this loop won't stop.
Every time, the while loop repeats, a sound is played to the player to make the process a better experience.
Then, 1 is added to the {_loops}
variable. It defined how many times the while loop already looped. If there already 15 or more loops, then it is going slower with every new while loop with a chance of 50% to give it some "randomness".
while {_luck} is false:
loop {_loot::*}:
chance of {_chance::%loop-index%}%:
#add loop-value to {_luckitems::*}
set {_lootslots} to "%loop-index%||%{_lootslots}%"
set {_luck} to true
stop loop
This while loop is repeating until an item has been selected, there is luck involved and this is done to prevent to have no changes in the random slot menu. I forgot to remove the commented "#add loop-value to {_luckitems::*}" from the pull request, this is going to be removed in a future pull request.
If the chance has happened and the item is the lucky one to be selected, it is added to the string of the {_lootslots}
variable as the index of the {SB::crates::%{_tier}%::loot::*}
list.
if {_p} is offline:
execute console command "/givelootbox %{_tier}% %{_p}% 1 true"
stop
If the player is offline for some reason, give the player the loot box back and stop the process we're doing right now. This might not happen that much but can be very helpful if a player has a bad internet connection and would have lost his loot box while opening.
set {_luck} to false
Because this is a while loop, we need the {_luck}
variable set back to false for the next loop.
set {_luckitems::*} to {_lootslots} split at "||"
Now, the {_loopslots}
variable is split into a list, then, the slot is defined depending on the predefined direction option.
if "{@direction}" is "ltr":
set {_slot} to 9
delete {_luckitems::10}
else:
set {_slot} to 17
delete {_luckitems::10}
The last entry is getting deleted. It is always the 10th list entry which has to be deleted, since we have always 9 slots in a chest inventory in each row.
set {_start} to true
loop {_luckitems::*}:
if {_start} is true:
set {_lootslots} to loop-value
set {_start} to false
else:
set {_lootslots} to "%{_lootslots}%||%loop-value%"
set {_item} to {SB::crates::%{_tier}%::loot::%loop-value%}
set slot {_slot} of {_p}'s current inventory to {_item}
if "{@direction}" is "ltr":
add 1 to {_slot}
else:
remove 1 from {_slot}
With this loop, the numbers, which have been separated above are now set to items in the loot box menu.
if {_wait} is 10 ticks:
cratereward({_p},{SB::crates::%{_tier}%::loot::%{_luckitems::5}%})
set {_done} to true
stop
If the loop already waits 10 ticks at the beginning, stop here at the end, since we're done! The 5th slot of the loot box menu is the reward item the player gets. Which we can get through the {_luckitems::5}
variable.
With that, the server operator can now create some custom items to give away with this add-on.
Pull request: https://github.com/Abwasserrohr/SKYBLOCK.SK/pull/112
4. Pull requests
https://github.com/Abwasserrohr/SKYBLOCK.SK/pull/112
5. GitHub Account
https://github.com/Abwasserrohr
6. How to contribute
You're into Minecraft and you like the kind of stuff I posted and want to try it out yourself? Meet me on Discord on the link below. :) I'm Abwasserrohr there.
Discord: https://discord.gg/FRuK5BC
Thank you for looking into and also reading my contribution post. I'm currently asking users who test SKYBLOCK.SK to give ideas what should be added next to the game. Some of them suggested that loot boxes are a must-have. And here it is. Server operators can give the items if a player votes through dedicated plugins, which only execute the /givelootbox
from the console, which are quite commonly used.
You have some feedback about this post, the new loot boxes or SKYBLOCK.SK? Feel free to leave a command, I'm also looking forward to see new feature ideas and there is a high chance that ideas are being added fast. =) Thank you for your time and effort.
Keep on steeming
Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.
To view those questions and the relevant answers related to your post, click here.
Need help? Chat with us on Discord.
[utopian-moderator]
Thank you for the suggestion to use carbon tool, @helo / @raycoms. I'll try carbon on my next contribution. =)
EDIT: I tried it, really not that bad. But the Skript syntax is big and regex stuff is very painful for me.. =D
I think, it wont get better than this for now:
![](https://steemitimages.com/640x0/https://cdn.steemitimages.com/DQmTPxmFuxcRJEQreVqCyeft7hTSxcDQB9fN7KQtiJAJ4bJ/2.png)
Going to use it in new contribution posts but I think it's not good enough for a pull request on carbon itself. :3
Thank you for reviewing my contribution post and for the feedback, @helo. =)
Thank you for your review, @helo! Keep up the good work!
Congratulations @immanuel94! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :
Click here to view your Board
If you no longer want to receive notifications, reply to this comment with the word
STOP
This post has received a 3.13 % upvote from @drotto thanks to: @sbi-booster.
Hi @immanuel94!
Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server
Hey, @immanuel94!
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!
Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).
Want to chat? Join us on Discord https://discord.gg/h52nFrV.
Vote for Utopian Witness!