11package net .swofty .type .lobby .gui ;
22
3+ import net .kyori .adventure .text .Component ;
34import net .minestom .server .event .inventory .InventoryPreClickEvent ;
45import net .minestom .server .inventory .InventoryType ;
56import net .minestom .server .item .ItemStack ;
7+ import net .minestom .server .item .Material ;
8+ import net .minestom .server .component .DataComponents ;
9+ import net .minestom .server .network .player .ResolvableProfile ;
610import net .swofty .commons .StringUtility ;
711import net .swofty .type .generic .gui .inventory .HypixelInventoryGUI ;
812import net .swofty .type .generic .gui .inventory .ItemStackCreator ;
13+ import net .swofty .type .generic .gui .inventory .RefreshingGUI ;
914import net .swofty .type .generic .gui .inventory .item .GUIClickableItem ;
1015import net .swofty .type .generic .user .HypixelPlayer ;
1116import net .swofty .type .lobby .ServerInfoCache ;
1419import java .util .ArrayList ;
1520import java .util .Arrays ;
1621import java .util .List ;
22+ import java .util .concurrent .ThreadLocalRandom ;
1723
18- public class GUIGameMenu extends HypixelInventoryGUI {
24+ public class GUIGameMenu extends HypixelInventoryGUI implements RefreshingGUI {
1925
2026 private static final int [] GAME_SLOTS = {
2127 10 , 11 , 12 , 13 , 14 , 15 , 16 ,
@@ -24,22 +30,39 @@ public class GUIGameMenu extends HypixelInventoryGUI {
2430 37 , 38 , 39 , 40 , 41 , 42 , 43
2531 };
2632
33+ private int cycleIndex = 0 ;
34+
2735 public GUIGameMenu () {
28- super ("Game Menu" , InventoryType .CHEST_5_ROW );
36+ super ("Game Menu" , InventoryType .CHEST_6_ROW );
2937 }
3038
3139 @ Override
3240 public void onOpen (InventoryGUIOpenEvent e ) {
3341 HypixelPlayer player = e .player ();
3442
43+ set (new GUIClickableItem (4 ) {
44+ @ Override
45+ public void run (InventoryPreClickEvent e , HypixelPlayer player ) {
46+
47+ }
48+
49+ @ Override
50+ public ItemStack .Builder getItem (HypixelPlayer player ) {
51+ return ItemStackCreator .getStack ("§aMain Lobby" ,
52+ Material .BOOKSHELF , 1 ,
53+ "" ,
54+ "§7Return to the Main Lobby." );
55+ }
56+ });
57+
3558 // Refresh cache, then populate
3659 ServerInfoCache .getServers ().thenAccept (servers -> {
3760 int i = 0 ;
3861 for (GameType game : GameType .values ()) {
3962 if (i >= GAME_SLOTS .length ) break ;
4063 set (createGameItem (game , GAME_SLOTS [i ++]));
4164 }
42- set (GUIClickableItem . getCloseItem ( 40 ));
65+ set (createRandomGameItem ( 49 ));
4366 updateItemStacks (getInventory (), player );
4467 });
4568
@@ -51,19 +74,25 @@ private GUIClickableItem createGameItem(GameType game, int slot) {
5174 @ Override
5275 public ItemStack .Builder getItem (HypixelPlayer player ) {
5376 String playerCount = StringUtility .commaify (game .getPlayerCount ());
54- String titleColor = game .isImplemented () ? "§a" : "§c" ;
77+ ItemStack . Builder itemBuilder = ItemStackCreator . getFromStack ( game .getItem (). build ()) ;
5578
5679 List <String > lore = new ArrayList <>();
80+ lore .add ("§8" + StringUtility .toNormalCase (game .getCategory ().name ()));
81+ lore .add ("" );
5782 lore .addAll (Arrays .asList (game .getLore ()));
5883 lore .add ("" );
5984 if (game .isImplemented ()) {
60- lore .add ("§e" + playerCount + " playing" );
61- lore .add ("" );
62- lore .add ("§eClick to play!" );
85+ if (cycleIndex % 2 == 0 ) {
86+ lore .add ("§a Click to Connect!" );
87+ } else {
88+ lore .add ("§a▶ Click to Connect!" );
89+ }
90+ lore .add ("§7" + playerCount + " currently playing!" );
6391 }
6492
65- return ItemStackCreator .getStack (titleColor + game .getDisplayName (),
66- game .getMaterial (), 1 , lore .toArray (new String [0 ]));
93+ return ItemStackCreator .appendLore (itemBuilder , lore ).customName (
94+ Component .text ("§a" + game .getDisplayName ())
95+ );
6796 }
6897
6998 @ Override
@@ -78,6 +107,59 @@ public void run(InventoryPreClickEvent e, HypixelPlayer player) {
78107 };
79108 }
80109
110+ private GUIClickableItem createRandomGameItem (int slot ) {
111+ GameType displayGame = GameType .values ()[cycleIndex % GameType .values ().length ];
112+ return new GUIClickableItem (slot ) {
113+ @ Override
114+ public ItemStack .Builder getItem (HypixelPlayer player ) {
115+ ItemStack base = displayGame .getItem ().build ();
116+ ItemStack .Builder builder = ItemStack .builder (base .material ())
117+ .amount (1 )
118+ .customName (Component .text ("§aRandom Game" ))
119+ .lore (
120+ Component .text ("§7Join a random game." ),
121+ Component .empty (),
122+ Component .text ("§eClick to Play" )
123+ );
124+
125+ // Copy head texture if present
126+ ResolvableProfile profile = base .get (DataComponents .PROFILE );
127+ if (profile != null ) {
128+ builder .set (DataComponents .PROFILE , profile );
129+ }
130+
131+ return builder ;
132+ }
133+
134+ @ Override
135+ public void run (InventoryPreClickEvent e , HypixelPlayer player ) {
136+ List <GameType > implemented = Arrays .stream (GameType .values ())
137+ .filter (GameType ::isImplemented )
138+ .toList ();
139+ if (implemented .isEmpty ()) {
140+ player .sendMessage ("§cNo games available!" );
141+ return ;
142+ }
143+ GameType random = implemented .get (
144+ ThreadLocalRandom .current ().nextInt (implemented .size ())
145+ );
146+ player .closeInventory ();
147+ player .sendTo (random .getLobbyType ());
148+ }
149+ };
150+ }
151+
152+ @ Override
153+ public void refreshItems (HypixelPlayer player ) {
154+ cycleIndex ++;
155+ set (createRandomGameItem (49 ));
156+ }
157+
158+ @ Override
159+ public int refreshRate () {
160+ return 10 ; // 0.5 seconds
161+ }
162+
81163 @ Override
82164 public boolean allowHotkeying () {
83165 return false ;
0 commit comments