This commit is contained in:
paisc 2025-04-03 15:25:27 +02:00
parent 9ee9f9b9ed
commit 71670f0d50
14 changed files with 514 additions and 1 deletions

View File

@ -12,6 +12,7 @@ import net.voltexstudios.applicationLobby.listener.PlayerListener;
import net.voltexstudios.applicationLobby.util.EyeTrace;
import net.voltexstudios.applicationLobby.util.SimpleLocation;
import net.voltexstudios.applicationLobby.util.SpawnUtil;
import net.voltexstudios.applicationLobby.util.item.InteractListener;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
@ -61,6 +62,7 @@ public final class ApplicationLobby extends JavaPlugin {
private void registerListeners() {
Bukkit.getPluginManager().registerEvents(new PlayerListener(), this);
Bukkit.getPluginManager().registerEvents(new InteractListener(), this);
}
private void registerCommands() {

View File

@ -102,7 +102,7 @@ public class HologramCommand implements CommandExecutor, TabCompleter {
return Arrays.stream(HologramType.values()).toList().stream().map(Enum::name).toList();
}
else if (strings[0].equalsIgnoreCase("delete")) {
List<String> hologramNames = HologramService.getInstance().getHolograms().stream().map(Hologram::getName).toList();
List<String> hologramNames = new java.util.ArrayList<>(HologramService.getInstance().getHolograms().stream().map(Hologram::getName).toList());
hologramNames.add("all");
return hologramNames;
}

View File

@ -0,0 +1,29 @@
package net.voltexstudios.applicationLobby.phone;
import org.bukkit.Material;
import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
import xyz.xenondevs.invui.item.ItemProvider;
import xyz.xenondevs.invui.item.builder.ItemBuilder;
import xyz.xenondevs.invui.item.impl.AbstractItem;
import java.util.List;
public abstract class AppItem extends AbstractItem {
private final ComponentWrapper name;
private final List<ComponentWrapper> lore;
public AppItem(ComponentWrapper name, ComponentWrapper... lore) {
this.name = name;
this.lore = List.of(lore);
}
@Override
public ItemProvider getItemProvider() {
return new ItemBuilder(Material.DIAMOND)
.setDisplayName(name)
.setLore(lore)
.setCustomModelData(1);
}
}

View File

@ -0,0 +1,19 @@
package net.voltexstudios.applicationLobby.phone;
import net.voltexstudios.applicationLobby.util.item.InteractableItem;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
public class PhoneItem extends InteractableItem {
public PhoneItem(ItemStack itemStack) {
super(itemStack);
}
@Override
public void onAction(Player player, PlayerInteractEvent event) {
PhoneManager.getInstance().openGUI(player);
}
}

View File

@ -0,0 +1,164 @@
package net.voltexstudios.applicationLobby.phone;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.voltexstudios.applicationLobby.phone.items.CommandAppItem;
import net.voltexstudios.applicationLobby.phone.items.EmptyAppItem;
import net.voltexstudios.applicationLobby.phone.items.LinkAppItem;
import net.voltexstudios.applicationLobby.util.CharRepo;
import net.voltexstudios.applicationLobby.util.item.InteractableItem;
import net.voltexstudios.applicationLobby.util.item.ItemRegistry;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import xyz.xenondevs.inventoryaccess.component.AdventureComponentWrapper;
import xyz.xenondevs.invui.gui.Gui;
import xyz.xenondevs.invui.item.ItemProvider;
import xyz.xenondevs.invui.item.builder.ItemBuilder;
import xyz.xenondevs.invui.window.Window;
public class PhoneManager {
private static PhoneManager instance;
private final PhoneItem phoneItem;
private PhoneManager() {
phoneItem = new PhoneItem(
new ItemBuilder(Material.PAPER)
.setDisplayName(new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<color:#7d7d7d>[</color><color:#00ebeb>Handy</color><color:#7d7d7d>]</color>")))
.setCustomModelData(37).get()
);
ItemRegistry.registerItem(phoneItem);
}
public InteractableItem getPhoneItem() {
return phoneItem;
}
public void openGUI(Player player) {
Window window = Window.split()
.setTitle(CharRepo.getNeg(48) + "§f" + CharRepo.PHONE_GUI)
.setUpperGui(getUpperGui())
.setLowerGui(getLowerGui())
.setViewer(player)
.build();
window.open();
}
private Gui getUpperGui() {
AppItem applicationPlotItem = new CommandAppItem(
"APPLICATION PLOT COMMAND",
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<color:#66b525>ᴘʟᴏᴛ</color>")),
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<color:#c98600>Phase I</color>")),
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<color:#8f8f8f>Bewirb Dich , Lerne Tips und Tricks,</color>")),
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<color:#8f8f8f>Verbessere Dich</color>")),
new AdventureComponentWrapper(Component.empty()),
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<color:#8f8f8f>Klicke um zu Starten</color>"))
);
AppItem trialPlotItem = new CommandAppItem(
"TRIAL PLOT COMMAND",
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<color:#fcb92a>ᴛʀɪᴀʟ</color>")),
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<color:#c98600>Phase II</color>")),
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<gray>Suche dir eines von 3 Themen aus und</gray>")),
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<gray>setze dieses in 7 Tagen um!</gray>")),
new AdventureComponentWrapper(Component.empty()),
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<gray>Klicke zum Starten</gray>"))
);
AppItem tutorialItem = new EmptyAppItem(
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<color:#9359e9>ᴛᴜᴛᴏʀɪᴀʟ</color>")),
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<gray>Hier lernst du alle wichtigen Schritte </gray>")),
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<gray>zum Bauen eines Plots kennen!</gray>")),
new AdventureComponentWrapper(Component.empty()),
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<dark_red>Coming Soon!</dark_red>"))
);
AppItem mailItem = new CommandAppItem(
"MAIL COMMAND",
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<color:#03a99f>ᴍᴀɪʟ</color>")),
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<gray>Hier erhältst du deine Bewertungen und Tipps!</gray>")),
new AdventureComponentWrapper(Component.empty()),
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<gray>Klicke um dein Postfach zu öffnen</gray>"))
);
return Gui.normal()
.setStructure(
"x x x x x x x x x",
"x o o o x y y y x",
"x o o o x y y y x",
"x x x x x x x x x",
"x z z z x s s s x",
"x z z z x s s s x"
)
.addIngredient('o', applicationPlotItem)
.addIngredient('y', trialPlotItem)
.addIngredient('z', tutorialItem)
.addIngredient('s', mailItem)
.build();
}
private Gui getLowerGui() {
AppItem gamesItem = new EmptyAppItem(
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<color:#d261cc>ɢᴀᴍᴇѕ</color>")),
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<gray>Überbrücke Wartezeit und spiele MiniGames</gray>")),
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<gray>mit deinen Freunden!</gray>")),
new AdventureComponentWrapper(Component.empty()),
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<dark_red>Coming Soon!</dark_red>"))
);
AppItem settingsItem = new EmptyAppItem(
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<color:#4cb6db>ѕᴇᴛᴛɪɴɢѕ</color>")),
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<gray>Hier kannst du deine Settings umstellen!</gray>")),
new AdventureComponentWrapper(Component.empty()),
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<dark_red>Coming Soon!</dark_red>"))
);
AppItem twitterItem = new LinkAppItem(
"https://x.com/Voltexstudio",
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<color:#00bcf7>ᴛᴡɪᴛᴛᴇʀ</color>"))
);
AppItem instagramItem = new LinkAppItem(
"https://www.instagram.com/voltex.studios/",
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<color:#f73a5a>ɪɴѕᴛᴀɢʀᴀᴍ</color>"))
);
AppItem tiktokItem = new LinkAppItem(
"https://www.tiktok.com/@voltexstudiosofficial",
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<color:#b6c1cc>ᴛɪᴋᴛᴏᴋ</color>"))
);
AppItem youtubeItem = new LinkAppItem(
"https://www.youtube.com/@VoltexStudio",
new AdventureComponentWrapper(MiniMessage.miniMessage().deserialize("<color:#de3a24>ʏᴏᴜᴛᴜʙᴇ</color>"))
);
return Gui.normal()
.setStructure(
"x f f f x g g g x",
"x f f f x g g g x",
"x x x x x x x x x",
"x a x b x c x d x"
)
.addIngredient('f', gamesItem)
.addIngredient('g', settingsItem)
.addIngredient('a', twitterItem)
.addIngredient('b', instagramItem)
.addIngredient('c', tiktokItem)
.addIngredient('d', youtubeItem)
.build();
}
public static PhoneManager getInstance() {
if(instance == null) {
instance = new PhoneManager();
}
return instance;
}
}

View File

@ -0,0 +1,25 @@
package net.voltexstudios.applicationLobby.phone.items;
import net.voltexstudios.applicationLobby.phone.AppItem;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
public class CommandAppItem extends AppItem {
private final String command;
public CommandAppItem(String command, ComponentWrapper name, ComponentWrapper... lore) {
super(name, lore);
this.command = command;
}
@Override
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent inventoryClickEvent) {
//TODO: Implement command execution
player.sendMessage(command);
player.closeInventory();
}
}

View File

@ -0,0 +1,20 @@
package net.voltexstudios.applicationLobby.phone.items;
import net.voltexstudios.applicationLobby.phone.AppItem;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
public class EmptyAppItem extends AppItem {
public EmptyAppItem(ComponentWrapper name, ComponentWrapper... lore) {
super(name, lore);
}
@Override
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent inventoryClickEvent) {
// Do nothing
}
}

View File

@ -0,0 +1,24 @@
package net.voltexstudios.applicationLobby.phone.items;
import net.voltexstudios.applicationLobby.phone.AppItem;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
public class FunctionAppItem extends AppItem {
private final Runnable function;
public FunctionAppItem(Runnable function, ComponentWrapper name, ComponentWrapper... lore) {
super(name, lore);
this.function = function;
}
@Override
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent inventoryClickEvent) {
this.function.run();
player.closeInventory();
}
}

View File

@ -0,0 +1,35 @@
package net.voltexstudios.applicationLobby.phone.items;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.voltexstudios.applicationLobby.ApplicationLobby;
import net.voltexstudios.applicationLobby.phone.AppItem;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
public class LinkAppItem extends AppItem {
private final String link;
public LinkAppItem(String link, ComponentWrapper name, ComponentWrapper... lore) {
super(name, lore);
this.link = link;
}
@Override
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent inventoryClickEvent) {
Component clickableMessage = ApplicationLobby.PREFIX.append(
Component.text("Klicke hier, um die Webseite zu öffnen!")
.color(NamedTextColor.RED)
.clickEvent(ClickEvent.openUrl(link))
.hoverEvent(Component.text("Öffne die Webseite im Browser"))
);
player.sendMessage(clickableMessage);
player.closeInventory();
}
}

View File

@ -0,0 +1,116 @@
package net.voltexstudios.applicationLobby.util;
public enum CharRepo {
//Spacing Characters
NEG1("\uF801"),
NEG2("\uF802"),
NEG4("\uF804"),
NEG8("\uF808"),
NEG16("\uF809"),
NEG32("\uF80A"),
NEG64("\uF80B"),
NEG128("\uF80C"),
NEG256("\uF80D"),
NEG512("\uF80E"),
NEG1024("\uF80F"),
POS1("\uF821"),
POS2("\uF822"),
POS4("\uF824"),
POS8("\uF828"),
POS16("\uF829"),
POS32("\uF82A"),
POS64("\uF82B"),
POS128("\uF82C"),
POS256("\uF82D"),
POS512("\uF82E"),
POS1024("\uF82F"),
/**
* GUI
*/
PHONE_GUI("\uE20A");
public final String literal;
CharRepo(String literal){
this.literal = literal;
}
@Override
public String toString(){
return this.literal;
}
private enum SpacingCharacters{
NEG1(-1, CharRepo.NEG1),
NEG2(-2, CharRepo.NEG2),
NEG4(-4, CharRepo.NEG4),
NEG8(-8, CharRepo.NEG8),
NEG16(-16, CharRepo.NEG16),
NEG32(-32, CharRepo.NEG32),
NEG64(-64, CharRepo.NEG64),
NEG128(-128, CharRepo.NEG128),
NEG256(-256, CharRepo.NEG256),
NEG512(-512, CharRepo.NEG512),
NEG1024(-1024, CharRepo.NEG1024),
POS1(1, CharRepo.POS1),
POS2(2, CharRepo.POS2),
POS4(4, CharRepo.POS4),
POS8(8, CharRepo.POS8),
POS16(16, CharRepo.POS16),
POS32(32, CharRepo.POS32),
POS64(64, CharRepo.POS64),
POS128(128, CharRepo.POS128),
POS256(256, CharRepo.POS256),
POS512(512, CharRepo.POS512),
POS1024(1024, CharRepo.POS1024);
private final int weight;
private final CharRepo charRef;
SpacingCharacters(int weight, CharRepo charRef){
this.weight = weight;
this.charRef = charRef;
}
}
public static CharRepo getCharacterByWeight(int weight){
for(SpacingCharacters ch : SpacingCharacters.values()){
if(ch.weight == weight)
return ch.charRef;
}
return null;
}
public static String getSpacing(int pixelAmount){
//convert amount to binary string
String binary = new StringBuilder(Integer.toBinaryString(Math.abs(pixelAmount))).reverse().toString();
StringBuilder sb = new StringBuilder();
char[] chArr = binary.toCharArray();
for(int index = 0; index < chArr.length; index++){
char ch = chArr[index];
if(ch == '0') continue;
int weight = (int)Math.pow(2, index);
//if we are getting negative, flip weight
weight = pixelAmount < 0 ? -weight : weight;
CharRepo ref = getCharacterByWeight(weight);
if(ref != null)
sb.append(ref.literal);
}
return sb.toString();
}
public static String getNeg(int pixelAmount){
return getSpacing(-Math.abs(pixelAmount));
}
public static String getPos(int pixelAmount){
return getSpacing(Math.abs(pixelAmount));
}
}

View File

@ -2,6 +2,7 @@ package net.voltexstudios.applicationLobby.util;
import net.voltexstudios.applicationLobby.ApplicationLobby;
import net.voltexstudios.applicationLobby.holograms.HologramService;
import net.voltexstudios.applicationLobby.phone.PhoneManager;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
@ -44,6 +45,7 @@ public final class PlayerUtil {
}
private static void giveLobbyItems(Player player) {
player.getInventory().clear();
//give invisible offhand item
ItemStack offHand = new ItemStack(Material.DIAMOND);
@ -52,6 +54,9 @@ public final class PlayerUtil {
offHand.setItemMeta(meta);
player.getInventory().setItem(EquipmentSlot.OFF_HAND, offHand);
//give phone
player.getInventory().setItem(0, PhoneManager.getInstance().getPhoneItem().getItemStack());
player.updateInventory();
}

View File

@ -0,0 +1,33 @@
package net.voltexstudios.applicationLobby.util.item;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerSwapHandItemsEvent;
public class InteractListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST)
public void onInteract(PlayerInteractEvent event) {
Player player = event.getPlayer();
InteractableItem item = ItemRegistry.getItem(event.getItem());
if(item != null) {
item.onAction(player, event);
event.setCancelled(true);
}
}
@EventHandler
public void onSwitchHand(PlayerSwapHandItemsEvent event) {
Player player = event.getPlayer();
InteractableItem mainItem = ItemRegistry.getItem(event.getMainHandItem());
if(mainItem != null) {
event.setCancelled(true);
}
}
}

View File

@ -0,0 +1,21 @@
package net.voltexstudios.applicationLobby.util.item;
import lombok.Getter;
import lombok.Setter;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
@Getter
@Setter
public abstract class InteractableItem {
public ItemStack itemStack;
public InteractableItem(ItemStack itemStack) {
this.itemStack = itemStack;
}
public abstract void onAction(Player player, PlayerInteractEvent event);
}

View File

@ -0,0 +1,20 @@
package net.voltexstudios.applicationLobby.util.item;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
public class ItemRegistry {
private static final List<InteractableItem> items = new ArrayList<>();
public static InteractableItem getItem(ItemStack itemStack) {
return items.stream().filter(item -> item.getItemStack().equals(itemStack)).findFirst().orElse(null);
}
public static void registerItem(InteractableItem item) {
items.add(item);
}
}