Major Rework

- GUI reworked so now there are less bugs when setting up a Minigame. Testing is still required.
- Force-Item Team variant is now in a working state but some features are still missing or simplified.
- Inventories etc. are now correctly restored after a minigame ends.
- Reconnection is now handled more robust meaning no data loss SHOULD occur.
- On-screen texts now look a bit more fancy, desing isnt complete yet tho.
- README updated
This commit is contained in:
jakob 2026-05-14 16:16:50 +02:00
parent 60b9d40468
commit 4e7f7701d4
41 changed files with 1008 additions and 946 deletions

17
.gitignore vendored
View File

@ -1,4 +1,17 @@
# Project exclude paths
# Gradle
/.gradle/
/build/
/build/classes/java/main/
# IntelliJ IDEA
/.idea/
# Eclipse
/.classpath
/.project
/.settings/
# Compiled output
/bin/
# macOS
.DS_Store

View File

@ -13,7 +13,7 @@
<h3 align="center">Randomized Minigames</h3>
<p align="center">
This spigot plugin adds a couple of Minigames to Minecraft all based on some sort of randomization. Currently working are two different types of Force Item Battles, a type of minigame where each player has to aquire an item faster than the others.
This spigot plugin adds a couple of Minigames to Minecraft all based on some sort of randomization. Currently working are five different Minigames, including three variants of Force Item Battle, a type of minigame where each player has to aquire an item faster than the others.
<br />
<a><strong>Explore the docs »</strong> <italic>There, sadly, are no docs yet.</italic></a>
<br />
@ -39,7 +39,13 @@
<li><a href="#installation">Installation</a></li>
</ul>
</li>
<li><a href="#usage">Usage</a></li>
<li>
<a href="#usage">Usage</a>
<ul>
<li><a href="#minigames">Minigames</a></li>
<li><a href="#setup">Setup</a></li>
</ul>
</li>
<li><a href="#roadmap">Roadmap</a></li>
<li><a href="#contributing">Contributing</a></li>
<li><a href="#license">License</a></li>
@ -77,13 +83,41 @@ As every Spigot Plugin
`/minigames` - Opens a GUI of all available Minigames.<br>
`/minigames killall`- Kills all minigames currently running, will be removed in the future since it shouldn't be necessary<br>
### Minigames
| Name | Description |
|---|---|
| **Force Item Battle** | Each player is assigned a random item and has to obtain it first. Items are assigned individually, so everyone is hunting something different. |
| **Force Item Battle (Same Items)** | Same as above, but all players share the same target item at any given time. |
| **Force Item Battle (Teams)** | The team variant. Players are split into teams of 26, and teammates share a target item. First team to reach the win limit wins. |
| **Block Randomizer** | Block drops are randomized per player — breaking any block gives you a random item instead of the usual drop. |
| **Only Chests** | Mob drops and block drops are disabled. The only way to get items is from chests. |
### Setup
After selecting a minigame, you get a setup screen with the following options:
- **Select Players** — pick who participates
- **Win Limit** — set the number of items a player (or team) needs to collect to win. Shows the current limit in green when active, red "Off" when disabled.
- **Timer** — set a time limit after which the game ends and the player with the highest score wins. Shows the remaining time in green when active, red "Off" when disabled.
Win Limit and Timer are mutually exclusive — enabling one disables the other.
For **Force Item Battle Teams**, there's an extra step before the setup screen where you choose the number of teams and assign players to each one.
**After every minigame**, all players are restored to their pre-game state: inventory, armor, offhand, XP level, health, food, and position are all put back. There's a 10-second countdown on the action bar before the reset happens.
If a player **disconnects mid-game**, they can rejoin and be put back into the running game with their score intact. If the game has already ended by the time they reconnect, their inventory is restored then instead.
<p align="right">(<a href="#readme-top">back to top</a>)</p>
<!-- ROADMAP -->
## Roadmap
- [ ] Fully implementing Force-Item-Battle Team variant
- [x] Fully implementing Force-Item-Battle Team variant
- [x] Make the GUI easier to work with
- [ ] Add another minigame, not sure which atm
- [ ] Make the GUI easier to work with
- [ ] Adding usefull JavaDocs
- [ ] probably other stuff I currently dont think about.
@ -127,4 +161,3 @@ Distributed under the GPL v3 License. See `LICENSE.md` for more information.
<p align="right">(<a href="#readme-top">back to top</a>)</p>

View File

@ -0,0 +1 @@
org.gradle.java.home=/usr/lib/jvm/java-21-openjdk

View File

@ -1,6 +1,7 @@
package de.ventority.randomizedminigames.Minigames;
import de.ventority.randomizedminigames.misc.Timer.Timer;
import de.ventority.randomizedminigames.util.MinigameHandler;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.EnderDragon;
@ -70,12 +71,14 @@ public class BlockRandomizer implements MinigameBase {
@Override
public void killGame() {
timer.stopCounter();
MinigameHandler.resetSettings(owner);
MinigameHandler.deleteGame(this);
}
@Override
public void stopGame() {
killGame();
}
@Override

View File

@ -1,17 +1,20 @@
package de.ventority.randomizedminigames.Minigames;
import de.ventority.randomizedminigames.RandomizedMinigames;
import de.ventority.randomizedminigames.gui.InGame.GamesScoreboardManager;
import de.ventority.randomizedminigames.misc.ColorCycler;
import de.ventority.randomizedminigames.misc.Timer.Timer;
import de.ventority.randomizedminigames.util.MinigameHandler;
import de.ventority.randomizedminigames.util.PlayerBackupHandler;
import de.ventority.randomizedminigames.util.Settings;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarStyle;
import org.bukkit.boss.BossBar;
import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@ -25,10 +28,12 @@ import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.awt.Color;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import java.util.UUID;
public class ForceItemBattle implements MinigameBase, Listener {
protected final HashMap<Player, ItemStack> currentItems;
@ -41,8 +46,24 @@ public class ForceItemBattle implements MinigameBase, Listener {
private final Player owner;
protected Settings settings;
private final Timer timer;
private final List<Player> disconnected = new ArrayList<>();
private final HashMap<UUID, DisconnectedState> disconnectedStates = new HashMap<>();
private final HashMap<Player, Integer> skips = new HashMap<>();
private boolean isActive = true;
private static class DisconnectedState {
final ItemStack currentItem;
final int score;
final int skipsLeft;
DisconnectedState(ItemStack currentItem, int score, int skipsLeft) {
this.currentItem = currentItem;
this.score = score;
this.skipsLeft = skipsLeft;
}
}
private final ColorCycler bossBarColors = new ColorCycler(
new Color(130, 50, 170), new Color(160, 50, 190), 0.2);
private int bossBarTick = 0;
private org.bukkit.scheduler.BukkitTask bossBarTask;
private final List<Material> SURVIVAL_ITEMS = loadMaterials();
@ -81,6 +102,20 @@ public class ForceItemBattle implements MinigameBase, Listener {
player.getInventory().addItem(skip);
}
timer.startCounter();
bossBarTask = Bukkit.getScheduler().runTaskTimer(
RandomizedMinigames.serverSettingsHandler.getPlugin(),
() -> {
String color = ChatColor.of(bossBarColors.getColor(bossBarTick++)).toString();
for (Map.Entry<Player, BossBar> entry : new HashMap<>(itemDisplays).entrySet()) {
ItemStack item = currentItems.get(entry.getKey());
if (item == null) continue;
String name = item.getType().getTranslationKey()
.replace("block.minecraft.", "")
.replace("_", " ")
.replace("item.minecraft.", "");
entry.getValue().setTitle(color + ChatColor.BOLD + name);
}
}, 0L, 1L);
}
@Override
@ -121,11 +156,6 @@ public class ForceItemBattle implements MinigameBase, Listener {
protected void updatePlayerItem(Player player, ItemStack item) {
currentItems.replace(player, item);
String key = currentItems.get(player).getType().getTranslationKey();
String displayName = key.replace("block.minecraft.", "")
.replace("_", " ")
.replace("item.minecraft.", "");
itemDisplays.get(player).setTitle(displayName);
ItemStack[] contents = player.getInventory().getContents();
for (ItemStack i : contents)
checkItem(player, i);
@ -163,6 +193,7 @@ public class ForceItemBattle implements MinigameBase, Listener {
timer.pauseCounter();
Timer t = new Timer(contestants, this, this::killGame, "Resetting game in: ");
t.setStopTime(10);
t.setReversed(true);
t.startCounter();
}
@ -181,22 +212,28 @@ public class ForceItemBattle implements MinigameBase, Listener {
}
public void killGame() {
backups.restoreAll();
for (Player p : itemDisplays.keySet()) {
itemDisplays.get(p).setVisible(false);
itemDisplays.get(p).removePlayer(p);
isActive = false;
timer.stopCounter();
if (bossBarTask != null) bossBarTask.cancel();
for (BossBar bar : itemDisplays.values()) {
bar.setVisible(false);
bar.removeAll();
}
itemDisplays.clear();
if (settings.getScoreboardStatus()) {
if (scoreboardManager != null) {
scoreboardManager.removeScoreboard();
scoreboardManager = null;
}
if (settings.getScoreboardStatus())
for (Player player : contestants)
player.setScoreboard(Objects.requireNonNull(Bukkit.getScoreboardManager()).getMainScoreboard());
itemDisplays.clear();
Scoreboard main = Objects.requireNonNull(Bukkit.getScoreboardManager()).getMainScoreboard();
for (Player player : contestants) {
if (player.isOnline())
player.setScoreboard(main);
}
backups.restoreAll();
MinigameHandler.resetSettings(owner);
MinigameHandler.deleteGame(this);
}
@ -261,16 +298,50 @@ public class ForceItemBattle implements MinigameBase, Listener {
@EventHandler
public void onPlayerLeave(PlayerQuitEvent e) {
if (contestants.contains(e.getPlayer())) {
disconnected.add(e.getPlayer());
removePlayer(e.getPlayer());
}
Player p = e.getPlayer();
if (!contestants.contains(p)) return;
disconnectedStates.put(p.getUniqueId(), new DisconnectedState(
currentItems.get(p),
currentScores.getOrDefault(p, 0),
skips.getOrDefault(p, 0)
));
currentItems.remove(p);
currentScores.remove(p);
skips.remove(p);
removePlayer(p);
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent e) {
if (disconnected.contains(e.getPlayer())) {
Player p = e.getPlayer();
UUID uuid = p.getUniqueId();
DisconnectedState state = disconnectedStates.remove(uuid);
if (state == null) return;
if (isActive) {
// Re-add player to the running game
contestants.add(p);
currentItems.put(p, state.currentItem);
currentScores.put(p, state.score);
skips.put(p, state.skipsLeft);
BossBar bar = Bukkit.createBossBar("", BarColor.PURPLE, BarStyle.SOLID);
bar.addPlayer(p);
bar.setVisible(true);
itemDisplays.put(p, bar);
if (settings.getScoreboardStatus() && scoreboardManager != null)
p.setScoreboard(scoreboardManager.getScoreboard());
p.getInventory().clear();
ItemStack skipItem = new ItemStack(Material.BARRIER, state.skipsLeft);
org.bukkit.inventory.meta.ItemMeta meta = skipItem.getItemMeta();
if (meta != null) { meta.setDisplayName(org.bukkit.ChatColor.RED + "Skip"); skipItem.setItemMeta(meta); }
if (state.skipsLeft > 0) p.getInventory().addItem(skipItem);
} else {
// Game already ended restore their pre-game backup
PlayerBackupHandler.restoreIfPending(p);
}
}
@EventHandler

View File

@ -1,16 +1,17 @@
package de.ventority.randomizedminigames.Minigames;
import de.ventority.randomizedminigames.util.Team;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.List;
public class ForceItemBattleTeams extends ForceItemBattle{
public class ForceItemBattleTeams extends ForceItemBattle {
private final List<Team> teams;
public ForceItemBattleTeams(List<Player> players, Player owner, List<Team> teams) {
super(players, owner);
this.teams = teams;
@ -18,27 +19,40 @@ public class ForceItemBattleTeams extends ForceItemBattle{
@Override
protected void updatePlayerItem(Player p, ItemStack item) {
// teams is null while super() is still running, fall back to per-player assignment
if (teams == null) {
super.updatePlayerItem(p, item);
return;
}
for (Team team : teams) {
for (Player curPlayer : team.getPlayers()) {
super.updatePlayerItem(curPlayer, item);
if (team.getPlayers().contains(p)) {
for (Player teammate : team.getPlayers()) {
super.updatePlayerItem(teammate, item);
}
return;
}
}
}
@Override
protected void showEndMessage(Player winner) {
Team winningTeam = null;
for (Team team : teams) {
if (team.getPlayers().contains(winner)) {
winningTeam = team;
break;
}
}
String title = winningTeam != null
? winningTeam.getColor() + winningTeam.getColor().name() + " Team" + ChatColor.RESET + " won!"
: winner.getName() + " won!";
for (Player player : contestants) {
player.teleport(winner);
if (player != winner)
player.setGameMode(GameMode.SPECTATOR);
Team winningTeam = new Team(null, null);
for (Team team : teams)
if (team.getPlayers().contains(player)) winningTeam = team;
player.sendTitle(winningTeam.getColor() + winningTeam.getColor().name() + "Team " + ChatColor.RESET + " won!",
"Resetting players...", 10, 70, 20);
player.sendTitle(title, "Resetting players...", 10, 70, 20);
player.setScoreboard(Bukkit.getScoreboardManager().getMainScoreboard());
}
}
}

View File

@ -1,6 +1,7 @@
package de.ventority.randomizedminigames.Minigames;
import de.ventority.randomizedminigames.misc.Timer.Timer;
import de.ventority.randomizedminigames.util.MinigameHandler;
import org.bukkit.Material;
import org.bukkit.entity.EnderDragon;
import org.bukkit.entity.EntityType;
@ -47,17 +48,19 @@ public class OnlyChests implements MinigameBase{
@Override
public void killGame() {
timer.stopCounter();
MinigameHandler.resetSettings(owner);
MinigameHandler.deleteGame(this);
}
@Override
public void stopGame() {
killGame();
}
@Override
public Player getOwner() {
return null;
return owner;
}
@EventHandler
@ -73,8 +76,7 @@ public class OnlyChests implements MinigameBase{
timer.pauseCounter();
}
if (event.getDamageSource().getCausingEntity() instanceof Player && contestants.contains((Player) event.getDamageSource().getCausingEntity()))
if (event.getEntity().getType() != EntityType.BLAZE) {
if (event.getEntity().getType() != EntityType.BLAZE)
event.getDrops().clear();
}
}
}

View File

@ -2,7 +2,10 @@ package de.ventority.randomizedminigames;
import de.ventority.randomizedminigames.gui.GUIClickEvent;
import de.ventority.randomizedminigames.util.MinigameHandler;
import de.ventority.randomizedminigames.util.PlayerBackupHandler;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.java.JavaPlugin;
public final class RandomizedMinigames extends JavaPlugin implements Listener {
@ -21,6 +24,11 @@ public final class RandomizedMinigames extends JavaPlugin implements Listener {
MinigameHandler.killAll();
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent e) {
PlayerBackupHandler.restoreIfPending(e.getPlayer());
}
private void init() {
serverSettingsHandler.setPlugin(this);
}

View File

@ -4,101 +4,73 @@ import de.ventority.randomizedminigames.RandomizedMinigames;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import java.util.Objects;
public abstract class BaseWindow {
protected final Player p;
protected final Inventory gui;
public BaseWindow(Player p) {
protected BaseWindow(Player p) {
this.p = p;
gui = Bukkit.createInventory(p, 54, RandomizedMinigames.serverSettingsHandler.getServerName()
+ ChatColor.RESET + ChatColor.DARK_GRAY);
gui = Bukkit.createInventory(null, 54,
RandomizedMinigames.serverSettingsHandler.getServerName() + ChatColor.RESET + ChatColor.DARK_GRAY);
}
protected void fillBorder() {
ItemStack stack;
for (int i = 0; i < 9; i++) {
stack = new ItemStack(Material.BLACK_STAINED_GLASS_PANE, 1);
addNBT(stack, "Action", "none");
setItemName(stack, " ");
addItemToGUI(i, stack);
}
for (int i = 1; i < 5; i++) {
stack = new ItemStack(Material.BLACK_STAINED_GLASS_PANE, 1);
addNBT(stack, "Action", "none");
setItemName(stack, " ");
addItemToGUI(9 * i, stack);
stack = new ItemStack(Material.BLACK_STAINED_GLASS_PANE, 1);
addNBT(stack, "Action", "none");
setItemName(stack, " ");
addItemToGUI(8 + 9 * i, stack);
}
for (int i = 0; i < 9; i++) {
stack = new ItemStack(Material.BLACK_STAINED_GLASS_PANE, 1);
setItemName(stack, " ");
addNBT(stack, "Action", "none");
addItemToGUI(i + 5 * 9, stack);
for (int i = 0; i < 9; i++) placeBorderPane(i);
for (int row = 1; row < 5; row++) {
placeBorderPane(9 * row);
placeBorderPane(8 + 9 * row);
}
for (int i = 0; i < 9; i++) placeBorderPane(45 + i);
}
private void placeBorderPane(int slot) {
ItemStack pane = new ItemStack(Material.BLACK_STAINED_GLASS_PANE);
setName(pane, " ");
NBTHelper.set(pane, "Action", "none");
gui.setItem(slot, pane);
}
protected abstract void fillGUI();
public abstract void handleClick(String action, InventoryClickEvent event);
public void buildWindow() {
fillBorder();
fillGUI();
addNBT(Objects.requireNonNull(gui.getItem(0)), "ItemMiniGame", "true");
GUIClickEvent.register(p, this);
p.openInventory(gui);
}
protected void addNBT(ItemStack item, String key, String value) {
ItemMeta meta = item.getItemMeta();
NamespacedKey key1 = new NamespacedKey(RandomizedMinigames.serverSettingsHandler.getPlugin(), key);
if (meta == null) return;
PersistentDataContainer data = meta.getPersistentDataContainer();
data.set(key1, PersistentDataType.STRING, value);
item.setItemMeta(meta);
protected ItemStack makeItem(Material material, String name) {
ItemStack item = new ItemStack(material);
setName(item, name);
return item;
}
protected void setItemName(ItemStack item, String name) {
protected void setName(ItemStack item, String name) {
ItemMeta meta = item.getItemMeta();
if (meta == null) return;
meta.setDisplayName(name);
item.setItemMeta(meta);
}
protected void addItemToGUI(int index, ItemStack item) {
addNBT(item, "ItemMiniGame", "true");
gui.setItem(index, item);
// Place an item at a specific slot, overwriting whatever is there (including border).
protected void place(int slot, ItemStack item) {
gui.setItem(slot, item);
}
protected void addItemToGUI(ItemStack item) {
addNBT(item, "ItemMiniGame", "true");
// Add an item to the next available inner slot.
protected void add(ItemStack item) {
gui.addItem(item);
}
public Inventory getGUI() {
return gui;
}
private Player getPlayer() {
return p;
}
protected String getNBT(ItemStack item, String key) {
if (item == null) return "ItemIsNull";
ItemMeta meta = item.getItemMeta();
NamespacedKey nsKey = new NamespacedKey(RandomizedMinigames.serverSettingsHandler.getPlugin(), key);
if (meta == null) return "NoItemMeta";
PersistentDataContainer data = meta.getPersistentDataContainer();
return data.get(nsKey, PersistentDataType.STRING);
}
}

View File

@ -1,49 +1,54 @@
package de.ventority.randomizedminigames.gui;
import de.ventority.randomizedminigames.gui.handlers.MinigameSelectHandler;
import de.ventority.randomizedminigames.gui.handlers.MinigameSetupHandler;
import de.ventority.randomizedminigames.gui.handlers.SettingsHandler;
import de.ventority.randomizedminigames.RandomizedMinigames;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class GUIClickEvent implements Listener {
private static final Map<UUID, BaseWindow> openWindows = new HashMap<>();
public static void register(Player p, BaseWindow window) {
openWindows.put(p.getUniqueId(), window);
}
@EventHandler
public void onClickEvent(InventoryClickEvent event) {
Inventory inventory = event.getClickedInventory();
if (event.getCurrentItem() == null) return;
if (inventory == null) return;
if (inventory.getItem(0) == null) return;
if (isMinigamePlugin(inventory.getItem(0))) {
event.setCancelled(true);
if (event.getCurrentItem().getType() == (Material.BLACK_STAINED_GLASS_PANE)) return;
switch (getNBT(event.getCurrentItem(), "Type")) {
case "none": return;
case "MinigameSelect": new MinigameSelectHandler(event, getNBT(event.getCurrentItem(), "Action")).handle();
case "MinigameSetup": new MinigameSetupHandler(event, getNBT(event.getCurrentItem(), "Action")).handle();
case "Misc": new SettingsHandler(event, getNBT(event.getCurrentItem(), "Action")).handle();
}
public void onClose(InventoryCloseEvent event) {
if (!(event.getPlayer() instanceof Player)) return;
Player p = (Player) event.getPlayer();
BaseWindow window = openWindows.get(p.getUniqueId());
// Only unregister if the closing inventory is the one we track.
// When a new window opens, register() is called before p.openInventory() fires this
// event, so the map already holds the new window and won't be removed here.
if (window != null && window.getGUI().equals(event.getInventory())) {
openWindows.remove(p.getUniqueId());
}
}
private String getNBT(ItemStack item, String key) {
if (item == null) return "ItemIsNull";
ItemMeta meta = item.getItemMeta();
NamespacedKey nsKey = new NamespacedKey(RandomizedMinigames.serverSettingsHandler.getPlugin(), key);
if (meta == null) return "NoItemMeta";
PersistentDataContainer data = meta.getPersistentDataContainer();
return data.get(nsKey, PersistentDataType.STRING);
}
@EventHandler
public void onClickEvent(InventoryClickEvent event) {
if (!(event.getWhoClicked() instanceof Player)) return;
Player p = (Player) event.getWhoClicked();
BaseWindow window = openWindows.get(p.getUniqueId());
if (window == null) return;
if (!window.getGUI().equals(event.getClickedInventory())) return;
private boolean isMinigamePlugin(ItemStack item) {
return getNBT(item, "ItemMiniGame") != null && getNBT(item, "ItemMiniGame").equals("true");
event.setCancelled(true);
ItemStack item = event.getCurrentItem();
if (item == null || item.getType() == Material.AIR) return;
if (item.getType() == Material.BLACK_STAINED_GLASS_PANE) return;
String action = NBTHelper.get(item, "Action");
if (action == null || action.equals("none")) return;
window.handleClick(action, event);
}
}

View File

@ -1,89 +0,0 @@
package de.ventority.randomizedminigames.gui;
import com.google.gson.Gson;
import de.ventority.randomizedminigames.util.MinigameHandler;
import de.ventority.randomizedminigames.util.Settings;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class GUICreator extends BaseWindow {
private final String path;
// DTOs als statische Klassen
private static class GUIItem {
int slot;
String material;
String name;
Map<String, String> nbt;
}
private static class GUIConfig {
String title;
int rows;
List<GUIItem> items;
}
public GUICreator(Player p, String path) {
super(p);
this.path = path;
}
@Override
protected void fillGUI() {
Settings playerSettings = MinigameHandler.getSettings(p);
Gson gson = new Gson();
GUIConfig config;
try (InputStream in = Objects.requireNonNull(
getClass().getClassLoader().getResourceAsStream(path),
"Resource not found: " + path
);
Reader reader = new InputStreamReader(in, StandardCharsets.UTF_8)) {
config = gson.fromJson(reader, GUIConfig.class);
if (config == null) {
throw new IllegalStateException("Parsed GUI config is null; is the file empty? Path: " + path);
}
if (config.items == null) {
throw new IllegalStateException("'items' is null in GUI config. Path: " + path);
}
} catch (Exception e) {
System.out.println("Error loading " + path + ". Check that the file is packaged under src/main/resources and not empty.");
return;
}
for (GUIItem guiItem : config.items) {
Material mat = Material.valueOf(guiItem.material.toUpperCase());
ItemStack item = new ItemStack(mat);
if (guiItem.nbt != null) {
for (Map.Entry<String, String> entry : guiItem.nbt.entrySet()) {
addNBT(item, entry.getKey(), entry.getValue());
}
}
String displayName = guiItem.name
.replace("%scoreboard%", playerSettings.getScoreboardStatus() ? ChatColor.GREEN + "On" : ChatColor.RED + "Off")
.replace("%scoreboardState%", playerSettings.getScoreboardStatus() ? ChatColor.GREEN + "On" : ChatColor.RED + "Off")
.replace("%timer%", playerSettings.isTimed ? ChatColor.GREEN + "On" : ChatColor.RED + "Off");
setItemName(item, displayName);
if (guiItem.slot == -1) {
addItemToGUI(item);
} else {
addItemToGUI(guiItem.slot, item);
}
}
}
}

View File

@ -1,62 +0,0 @@
package de.ventority.randomizedminigames.gui.MinigameSetups;
import de.ventority.randomizedminigames.gui.BaseWindow;
import de.ventority.randomizedminigames.util.MinigameHandler;
import de.ventority.randomizedminigames.util.Settings;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
public class MinigameSetup extends BaseWindow {
public MinigameSetup(Player p) {
super(p);
}
@Override
protected void fillGUI() {
ItemStack playerSelect = new ItemStack(Material.PLAYER_HEAD);
addNBT(playerSelect, "Type", "MinigameSetup");
addNBT(playerSelect, "Action", "startPlayerSelection");
setItemName(playerSelect, "Select Players");
addItemToGUI(playerSelect);
ItemStack setLimit = new ItemStack(Material.BOOK);
addNBT(setLimit, "Type", "MinigameSetup");
addNBT(setLimit, "Action", "startLimitSelection");
setItemName(setLimit, "Set win limit");
addItemToGUI(setLimit);
Settings playerSettings = MinigameHandler.getSettings(p);
ItemStack scoreboard = new ItemStack(Material.EMERALD);
addNBT(scoreboard, "Type", "MinigameSetup");
addNBT(scoreboard, "Action", "switchScoreboard");
setItemName(scoreboard, "Scoreboard: " + (playerSettings.getScoreboardStatus() ? (ChatColor.GREEN + "On") : ChatColor.RED + "Off"));
addItemToGUI(scoreboard);
ItemStack start = new ItemStack(Material.GREEN_DYE);
addNBT(start, "Type", "MinigameSetup");
addNBT(start, "Action", "startGame");
setItemName(start, "Start");
addItemToGUI(50, start);
ItemStack timer = new ItemStack(Material.CLOCK);
addNBT(timer, "Type", "MinigameSetup");
addNBT(timer, "Action", "startTimerSetup");
setItemName(timer, "Set Timer");
addItemToGUI(timer);
ItemStack enableTimer = new ItemStack(Material.TARGET);
addNBT(enableTimer, "Type", "MinigameSetup");
addNBT(enableTimer, "Action", "toggleTimer");
setItemName(enableTimer, "Timer: " + (playerSettings.isTimed ? (ChatColor.GREEN + "On") : ChatColor.RED + "Off"));
addItemToGUI(enableTimer);
ItemStack back = new ItemStack(Material.ARROW);
addNBT(back, "Type", "MinigameSelect");
addNBT(back, "Action", "homeMenu");
setItemName(back, "Back");
addItemToGUI(49, back);
}
}

View File

@ -1,48 +0,0 @@
package de.ventority.randomizedminigames.gui.MinigameSetups;
import de.ventority.randomizedminigames.gui.BaseWindow;
import de.ventority.randomizedminigames.util.MinigameHandler;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
public class PlayerSelection extends BaseWindow {
public PlayerSelection(Player p) {
super(p);
}
@Override
protected void fillGUI() {
for (Player player : Bukkit.getOnlinePlayers()) {
if (!MinigameHandler.getOccupiedPlayers().contains(player)) {
ItemStack item = getPlayerHead(player);
addNBT(item, "Type", "MinigameSetup");
addNBT(item, "Action", "clickedPlayer");
addNBT(item, "Player", player.getDisplayName());
addItemToGUI(item);
}
}
ItemStack back = new ItemStack(Material.ARROW);
addNBT(back, "Type", "MinigameSetup");
addNBT(back, "Action", "homeMenu");
setItemName(back, "Back");
addItemToGUI(49, back);
}
private ItemStack getPlayerHead(Player player) {
ItemStack head = new ItemStack(Material.PLAYER_HEAD);
SkullMeta meta = (SkullMeta) head.getItemMeta();
if (meta != null) {
meta.setOwningPlayer(player);
meta.setDisplayName((MinigameHandler.getSettings(p).getSelectedPlayers().contains(player) ?
ChatColor.GREEN : ChatColor.RED) + player.getName());
head.setItemMeta(meta);
}
return head;
}
}

View File

@ -1,40 +0,0 @@
package de.ventority.randomizedminigames.gui.MinigameSetups;
import de.ventority.randomizedminigames.gui.BaseWindow;
import de.ventority.randomizedminigames.util.MinigameHandler;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
public class SetLimit extends BaseWindow {
public SetLimit(Player p) {
super(p);
}
@Override
protected void fillGUI() {
ItemStack add = new ItemStack(Material.RED_DYE);
addNBT(add, "Type", "MinigameSetup");
addNBT(add, "Action", "addToLimit");
setItemName(add, "Add");
addItemToGUI(14, add);
ItemStack sub = new ItemStack(Material.GREEN_DYE);
addNBT(sub, "Type", "MinigameSetup");
addNBT(sub, "Action", "subFromLimit");
setItemName(sub, "Sub");
addItemToGUI(12, sub);
ItemStack display = new ItemStack(Material.PAPER);
addNBT(display, "Type", "MinigameSetup");
addNBT(display, "Action", "none");
setItemName(display, "" + MinigameHandler.getSettings(p).getSelectedLimit());
addItemToGUI(13, display);
ItemStack back = new ItemStack(Material.ARROW);
addNBT(back, "Type", "MinigameSetup");
addNBT(back, "Action", "homeMenu");
setItemName(back, "Back");
addItemToGUI(49, back);
}
}

View File

@ -1,75 +0,0 @@
package de.ventority.randomizedminigames.gui.MinigameSetups;
import de.ventority.randomizedminigames.gui.BaseWindow;
import de.ventority.randomizedminigames.util.MinigameHandler;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
public class SetTimeLimit extends BaseWindow {
public SetTimeLimit(Player p) {
super(p);
}
@Override
protected void fillGUI() {
ItemStack add30 = new ItemStack(Material.RED_DYE);
addNBT(add30, "Type", "MinigameSetup");
addNBT(add30, "Action", "add30ToTimeLimit");
setItemName(add30, "+30min");
addItemToGUI(16, add30);
ItemStack add10 = new ItemStack(Material.RED_DYE);
addNBT(add10, "Type", "MinigameSetup");
addNBT(add10, "Action", "add10ToTimeLimit");
setItemName(add10, "+10min");
addItemToGUI(15, add10);
ItemStack add1 = new ItemStack(Material.RED_DYE);
addNBT(add1, "Type", "MinigameSetup");
addNBT(add1, "Action", "add1ToTimeLimit");
setItemName(add1, "+1min");
addItemToGUI(14, add1);
ItemStack sub30 = new ItemStack(Material.GREEN_DYE);
addNBT(sub30, "Type", "MinigameSetup");
addNBT(sub30, "Action", "sub30FromTimeLimit");
setItemName(sub30, "-30min");
addItemToGUI(10, sub30);
ItemStack sub10 = new ItemStack(Material.GREEN_DYE);
addNBT(sub10, "Type", "MinigameSetup");
addNBT(sub10, "Action", "sub10FromTimeLimit");
setItemName(sub10, "-10min");
addItemToGUI(11, sub10);
ItemStack sub1 = new ItemStack(Material.GREEN_DYE);
addNBT(sub1, "Type", "MinigameSetup");
addNBT(sub1, "Action", "sub1FromTimeLimit");
setItemName(sub1, "-1min");
addItemToGUI(12, sub1);
ItemStack display = new ItemStack(Material.PAPER);
addNBT(display, "Type", "MinigameSetup");
addNBT(display, "Action", "none");
setItemName(display, formattedTime(MinigameHandler.getSettings(p).getTimeLimit()));
addItemToGUI(13, display);
ItemStack back = new ItemStack(Material.ARROW);
addNBT(back, "Type", "MinigameSetup");
addNBT(back, "Action", "homeMenu");
setItemName(back, "Back");
addItemToGUI(49, back);
}
private String formattedTime(int time) {
int minutes = (int)Math.floor((double) time / 60);
int seconds = time % 60;
StringBuilder sb = new StringBuilder();
if (minutes != 0) {
sb.append(minutes).append(":");
}
sb.append(seconds);
return sb.toString();
}
}

View File

@ -1,41 +0,0 @@
package de.ventority.randomizedminigames.gui.MinigameSetups;
import de.ventority.randomizedminigames.gui.BaseWindow;
import de.ventority.randomizedminigames.util.MinigameHandler;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
public class TeamCountSelection extends BaseWindow {
public TeamCountSelection(Player p) {
super(p);
}
@Override
protected void fillGUI() {
ItemStack add = new ItemStack(Material.RED_DYE);
addNBT(add, "Type", "MinigameSetup");
addNBT(add, "Action", "addTeamCount");
setItemName(add, "Add");
addItemToGUI(14, add);
ItemStack sub = new ItemStack(Material.GREEN_DYE);
addNBT(sub, "Type", "MinigameSetup");
addNBT(sub, "Action", "subTeamCount");
setItemName(sub, "Sub");
addItemToGUI(12, sub);
ItemStack display = new ItemStack(Material.PAPER);
addNBT(display, "Type", "MinigameSetup");
addNBT(display, "Action", "none");
setItemName(display, "" + MinigameHandler.getSettings(p).getTeamCount());
addItemToGUI(13, display);
ItemStack next = new ItemStack(Material.ARROW);
addNBT(next, "Type", "MinigameSetup");
addNBT(next, "Action", "TeamSetupSelection");
setItemName(next, "Next");
addItemToGUI(49, next);
}
}

View File

@ -1,16 +0,0 @@
package de.ventority.randomizedminigames.gui.MinigameSetups;
import de.ventority.randomizedminigames.gui.BaseWindow;
import org.bukkit.entity.Player;
public class TeamOverview extends BaseWindow {
public TeamOverview(Player p) {
super(p);
}
@Override
protected void fillGUI() {
}
}

View File

@ -1,58 +0,0 @@
package de.ventority.randomizedminigames.gui.MinigameSetups;
import de.ventority.randomizedminigames.gui.BaseWindow;
import de.ventority.randomizedminigames.util.MinigameHandler;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
public class TeamPlayerSelection extends BaseWindow {
public TeamPlayerSelection(Player p) {
super(p);
}
@Override
protected void fillGUI() {
for (Player player : Bukkit.getOnlinePlayers()) {
if (!MinigameHandler.getOccupiedPlayers().contains(player)) {
ItemStack item = getPlayerHead(player);
addNBT(item, "Type", "MinigameSetup");
addNBT(item, "Action", "clickedPlayerInTeams");
addNBT(item, "Player", player.getDisplayName());
addItemToGUI(item);
}
}
final ChatColor[] colors = new ChatColor[]{ChatColor.GREEN,
ChatColor.RED, ChatColor.BLUE, ChatColor.DARK_PURPLE,
ChatColor.BLACK, ChatColor.DARK_GREEN};
final Material[] material = new Material[]{Material.GREEN_WOOL, Material.RED_WOOL,
Material.BLUE_WOOL, Material.PURPLE_WOOL, Material.BLACK_WOOL, Material.GREEN_WOOL};
ItemStack selectedTeam = new ItemStack(material[MinigameHandler.getSettings(p).getSelectedTeamIndex()], 1);
setItemName(selectedTeam, colors[MinigameHandler.getSettings(p).getSelectedTeamIndex()] + "Team #" + (MinigameHandler.getSettings(p).getSelectedTeamIndex() + 1));
addNBT(selectedTeam, "Team", Integer.toString(MinigameHandler.getSettings(p).getSelectedTeamIndex()));
addItemToGUI(4, selectedTeam);
ItemStack back = new ItemStack(Material.ARROW);
addNBT(back, "Type", "MinigameSetup");
addNBT(back, "Action", "homeMenu");
setItemName(back, "Back");
addItemToGUI(49, back);
}
private ItemStack getPlayerHead(Player player) {
ItemStack head = new ItemStack(Material.PLAYER_HEAD);
SkullMeta meta = (SkullMeta) head.getItemMeta();
if (meta != null) {
meta.setOwningPlayer(player);
meta.setDisplayName((MinigameHandler.getSettings(p).getSelectedPlayers().contains(player) ?
ChatColor.GREEN : ChatColor.RED) + player.getName());
head.setItemMeta(meta);
}
return head;
}
}

View File

@ -1,30 +0,0 @@
package de.ventority.randomizedminigames.gui.MinigameSetups;
import de.ventority.randomizedminigames.gui.BaseWindow;
import de.ventority.randomizedminigames.util.MinigameHandler;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
public class TeamSetupSelection extends BaseWindow {
private final ChatColor[] colors = new ChatColor[]{ChatColor.GREEN, ChatColor.RED, ChatColor.BLUE, ChatColor.DARK_PURPLE, ChatColor.BLACK, ChatColor.DARK_GREEN};
private final Material[] material = new Material[]{Material.GREEN_WOOL, Material.RED_WOOL, Material.BLUE_WOOL, Material.PURPLE_WOOL, Material.BLACK_WOOL, Material.GREEN_WOOL};
public TeamSetupSelection(Player p) {
super(p);
}
@Override
protected void fillGUI() {
for (int i = 0; i < MinigameHandler.getSettings(p).getTeamCount(); i++) {
ItemStack item = new ItemStack(material[i], 1);
setItemName(item, colors[i] + "Team #" + (i + 1));
addNBT(item, "Type", "MinigameSetup");
addNBT(item, "Action", "selectTeam");
addNBT(item, "selectedTeam", Integer.toString(i));
addItemToGUI(item);
}
}
}

View File

@ -0,0 +1,27 @@
package de.ventority.randomizedminigames.gui;
import de.ventority.randomizedminigames.RandomizedMinigames;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
public final class NBTHelper {
private NBTHelper() {}
public static void set(ItemStack item, String key, String value) {
ItemMeta meta = item.getItemMeta();
if (meta == null) return;
NamespacedKey nsKey = new NamespacedKey(RandomizedMinigames.serverSettingsHandler.getPlugin(), key);
meta.getPersistentDataContainer().set(nsKey, PersistentDataType.STRING, value);
item.setItemMeta(meta);
}
public static String get(ItemStack item, String key) {
if (item == null) return null;
ItemMeta meta = item.getItemMeta();
if (meta == null) return null;
NamespacedKey nsKey = new NamespacedKey(RandomizedMinigames.serverSettingsHandler.getPlugin(), key);
return meta.getPersistentDataContainer().get(nsKey, PersistentDataType.STRING);
}
}

View File

@ -1,20 +0,0 @@
package de.ventority.randomizedminigames.gui;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
public class SettingsWindow extends BaseWindow{
public SettingsWindow(Player p) {
super(p);
}
@Override
public void fillGUI() {
ItemStack setContestants = new ItemStack(Material.ZOMBIE_HEAD, 1);
setItemName(setContestants, "Add Contestants");
addNBT(setContestants, "Status", "addContestants");
gui.addItem(setContestants);
}
}

View File

@ -1,30 +0,0 @@
package de.ventority.randomizedminigames.gui.handlers;
import de.ventority.randomizedminigames.RandomizedMinigames;
import org.bukkit.NamespacedKey;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
public abstract class GUIHandler {
protected final InventoryClickEvent event;
protected final String action;
public GUIHandler(InventoryClickEvent event, String action) {
this.event = event;
this.action = action;
}
public abstract void handle();
protected String getNBT(ItemStack item, String key) {
if (item == null) return "ItemIsNull";
ItemMeta meta = item.getItemMeta();
NamespacedKey nsKey = new NamespacedKey(RandomizedMinigames.serverSettingsHandler.getPlugin(), key);
if (meta == null) return "NoItemMeta";
PersistentDataContainer data = meta.getPersistentDataContainer();
return data.get(nsKey, PersistentDataType.STRING);
}
}

View File

@ -1,30 +0,0 @@
package de.ventority.randomizedminigames.gui.handlers;
import de.ventority.randomizedminigames.gui.MinigameSetups.MinigameSetup;
import de.ventority.randomizedminigames.gui.MinigameSetups.TeamCountSelection;
import de.ventority.randomizedminigames.util.MinigameHandler;
import de.ventority.randomizedminigames.util.Settings;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
public class MinigameSelectHandler extends GUIHandler{
public MinigameSelectHandler(InventoryClickEvent event, String action) {
super(event, action);
}
@Override
public void handle() {
Settings settings = MinigameHandler.getSettings((Player) event.getWhoClicked());
if (action.equals("startForceItem") || action.equals("startForceItemSameItem") || action.equals("startBlockRandomizer") || action.equals("startOnlyChests")) {
settings.selectMinigame(Integer.parseInt(getNBT(event.getCurrentItem(), "selectedMinigame")));
new MinigameSetup((Player) event.getWhoClicked()).buildWindow();
}
if (action.equals("startForceItemTeams")) {
settings.selectMinigame(Integer.parseInt(getNBT(event.getCurrentItem(), "selectedMinigame")));
new TeamCountSelection((Player)event.getWhoClicked()).buildWindow();
}
if (action.equals("homeMenu")) {
new MinigameSetup((Player) event.getWhoClicked()).buildWindow();
}
}
}

View File

@ -1,116 +0,0 @@
package de.ventority.randomizedminigames.gui.handlers;
import de.ventority.randomizedminigames.gui.MinigameSetups.*;
import de.ventority.randomizedminigames.util.Team;
import de.ventority.randomizedminigames.util.MinigameHandler;
import de.ventority.randomizedminigames.util.Settings;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
public class MinigameSetupHandler extends GUIHandler {
public MinigameSetupHandler(InventoryClickEvent event, String action) {
super(event, action);
}
@Override
public void handle() {
if (action.equals("homeMenu")) {
new MinigameSetup((Player) event.getWhoClicked()).buildWindow();
}
Settings playerSettings = MinigameHandler.getSettings(((Player) event.getWhoClicked()).getPlayer());
if (action.equals("clickedPlayer")) {
Player toWork = Bukkit.getPlayer(getNBT(event.getCurrentItem(), "Player"));
if (playerSettings.getSelectedPlayers().contains(toWork)) {
playerSettings.removePlayersFromSelection(toWork);
} else {
playerSettings.addPlayersToSelection(toWork);
}
new PlayerSelection((Player)event.getWhoClicked()).buildWindow();
}
if (action.equals("subFromLimit")) {
playerSettings.subFromWinLimit();
new SetLimit((Player)event.getWhoClicked()).buildWindow();
}
if (action.equals("addToLimit")) {
playerSettings.addToWinLimit();
new SetLimit((Player)event.getWhoClicked()).buildWindow();
}
if (action.equals("addTeamCount")) {
playerSettings.addTeamCount();
new TeamCountSelection((Player)event.getWhoClicked()).buildWindow();
}
if (action.equals("subTeamCount")) {
playerSettings.subTeamCount();
new TeamCountSelection((Player)event.getWhoClicked()).buildWindow();
}
if (action.equals("startPlayerSelection")) {
new PlayerSelection((Player)event.getWhoClicked()).buildWindow();
}
if (action.equals("startLimitSelection")) {
new SetLimit((Player)event.getWhoClicked()).buildWindow();
}
if (action.equals("switchScoreboard")) {
playerSettings.switchScoreboard();
new MinigameSetup((Player) event.getWhoClicked()).buildWindow();
}
if (action.equals("toggleTimer")) {
playerSettings.isTimed = !playerSettings.isTimed;
new MinigameSetup((Player) event.getWhoClicked()).buildWindow();
}
if (action.equals("startGame")) {
MinigameHandler.createMinigame(playerSettings.getSelectedMinigame(), (Player) event.getWhoClicked());
event.getWhoClicked().closeInventory();
}
if (action.equals("TeamSetupSelection")) {
new TeamSetupSelection((Player)event.getWhoClicked()).buildWindow();
}
if (action.equals("selectTeam")) {
MinigameHandler.getSettings(((Player) event.getWhoClicked()).getPlayer()).setSelectedTeamIndex(Integer.parseInt(getNBT(event.getCurrentItem(), "selectedTeam")));
new TeamPlayerSelection((Player)event.getWhoClicked()).buildWindow();
}
if (action.equals("clickedPlayerInTeams")) {
Player toWork = Bukkit.getPlayer(getNBT(event.getCurrentItem(), "Player"));
int teamNumber = Integer.parseInt(getNBT(event.getClickedInventory().getItem(4), "Team"));
Team team = playerSettings.getTeam(teamNumber - 1);
if (playerSettings.getSelectedPlayers().contains(toWork)) {
team.removePlayer(toWork);
playerSettings.removePlayersFromSelection(toWork);
} else {
team.addPlayer(toWork);
playerSettings.addPlayersToSelection(toWork);
}
return;
}
if (action.equals("startTimerSetup")) {
new SetTimeLimit((Player)event.getWhoClicked()).buildWindow();
}
if (action.contains("FromTimeLimit") || action.contains("ToTimeLimit")) {
switch (action) {
case "add30ToTimeLimit": playerSettings.setTimeLimit(playerSettings.getTimeLimit() + 30*60); break;
case "add10ToTimeLimit": playerSettings.setTimeLimit(playerSettings.getTimeLimit() + 10*60); break;
case "add1ToTimeLimit": playerSettings.setTimeLimit(playerSettings.getTimeLimit() + 60); break;
case "sub30FromTimeLimit": playerSettings.setTimeLimit(playerSettings.getTimeLimit() - 30*60); break;
case "sub10FromTimeLimit": playerSettings.setTimeLimit(playerSettings.getTimeLimit() - 10*60); break;
case "sub1FromTimeLimit": playerSettings.setTimeLimit(playerSettings.getTimeLimit() - 60); break;
}
new SetTimeLimit((Player)event.getWhoClicked()).buildWindow();
}
}
}

View File

@ -1,18 +0,0 @@
package de.ventority.randomizedminigames.gui.handlers;
import de.ventority.randomizedminigames.gui.SettingsWindow;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
public class SettingsHandler extends GUIHandler {
public SettingsHandler(InventoryClickEvent event, String action) {
super(event, action);
}
@Override
public void handle() {
if (action.equals("selectSettings")) {
new SettingsWindow((Player)event.getWhoClicked());
}
}
}

View File

@ -0,0 +1,88 @@
package de.ventority.randomizedminigames.gui.windows;
import de.ventority.randomizedminigames.gui.BaseWindow;
import de.ventority.randomizedminigames.gui.NBTHelper;
import de.ventority.randomizedminigames.util.MinigameHandler;
import de.ventority.randomizedminigames.util.Settings;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
public class MinigameSetupWindow extends BaseWindow {
public MinigameSetupWindow(Player p) {
super(p);
}
@Override
protected void fillGUI() {
Settings settings = MinigameHandler.getSettings(p);
ItemStack playerSelect = makeItem(Material.PLAYER_HEAD, "Select Players");
NBTHelper.set(playerSelect, "Action", "startPlayerSelection");
add(playerSelect);
String limitLabel = !settings.isTimed
? ChatColor.GREEN + String.valueOf(settings.getSelectedLimit())
: ChatColor.RED + "Off";
ItemStack setLimit = makeItem(Material.BOOK, "Win Limit: " + limitLabel);
NBTHelper.set(setLimit, "Action", "startLimitSelection");
add(setLimit);
ItemStack scoreboard = makeItem(Material.EMERALD,
"Scoreboard: " + (settings.getScoreboardStatus() ? ChatColor.GREEN + "On" : ChatColor.RED + "Off"));
NBTHelper.set(scoreboard, "Action", "switchScoreboard");
add(scoreboard);
String timerLabel = settings.isTimed
? ChatColor.GREEN + formatTime(settings.getTimeLimit())
: ChatColor.RED + "Off";
ItemStack timer = makeItem(Material.CLOCK, "Timer: " + timerLabel);
NBTHelper.set(timer, "Action", "startTimerSetup");
add(timer);
ItemStack start = makeItem(Material.GREEN_DYE, "Start");
NBTHelper.set(start, "Action", "startGame");
place(50, start);
ItemStack back = makeItem(Material.ARROW, "Back");
NBTHelper.set(back, "Action", "back");
place(49, back);
}
private String formatTime(int totalSeconds) {
int minutes = totalSeconds / 60;
int seconds = totalSeconds % 60;
if (minutes == 0) return String.valueOf(seconds);
return minutes + ":" + String.format("%02d", seconds);
}
@Override
public void handleClick(String action, InventoryClickEvent event) {
Settings settings = MinigameHandler.getSettings(p);
switch (action) {
case "startPlayerSelection":
new PlayerSelectionWindow(p).buildWindow();
break;
case "startLimitSelection":
new SetLimitWindow(p).buildWindow();
break;
case "switchScoreboard":
settings.switchScoreboard();
new MinigameSetupWindow(p).buildWindow();
break;
case "startTimerSetup":
new SetTimeLimitWindow(p).buildWindow();
break;
case "startGame":
MinigameHandler.createMinigame(settings.getSelectedMinigame(), p);
p.closeInventory();
break;
case "back":
new MinigamesDisplayWindow(p).buildWindow();
break;
}
}
}

View File

@ -1,8 +1,11 @@
package de.ventority.randomizedminigames.gui.windows;
import de.ventority.randomizedminigames.gui.BaseWindow;
import de.ventority.randomizedminigames.Minigames.Minigame;
import de.ventority.randomizedminigames.gui.BaseWindow;
import de.ventority.randomizedminigames.gui.NBTHelper;
import de.ventority.randomizedminigames.util.MinigameHandler;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
public class MinigamesDisplayWindow extends BaseWindow {
@ -14,12 +17,23 @@ public class MinigamesDisplayWindow extends BaseWindow {
@Override
protected void fillGUI() {
for (Minigame minigame : Minigame.values()) {
ItemStack item = new ItemStack(minigame.getMaterial(), 1);
setItemName(item, minigame.getName());
addNBT(item, "Type", "MinigameSelect");
addNBT(item, "Action", minigame.getAction());
addNBT(item, "selectedMinigame", Integer.toString(minigame.getNumber()));
addItemToGUI(item);
ItemStack item = makeItem(minigame.getMaterial(), minigame.getName());
NBTHelper.set(item, "Action", minigame.getAction());
NBTHelper.set(item, "selectedMinigame", Integer.toString(minigame.getNumber()));
add(item);
}
}
@Override
public void handleClick(String action, InventoryClickEvent event) {
String selectedMinigame = NBTHelper.get(event.getCurrentItem(), "selectedMinigame");
if (selectedMinigame != null) {
MinigameHandler.getSettings(p).selectMinigame(Integer.parseInt(selectedMinigame));
}
if (action.equals("startForceItemTeams")) {
new TeamCountSelectionWindow(p).buildWindow();
} else {
new MinigameSetupWindow(p).buildWindow();
}
}
}

View File

@ -0,0 +1,69 @@
package de.ventority.randomizedminigames.gui.windows;
import de.ventority.randomizedminigames.gui.BaseWindow;
import de.ventority.randomizedminigames.gui.NBTHelper;
import de.ventority.randomizedminigames.util.MinigameHandler;
import de.ventority.randomizedminigames.util.Settings;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
public class PlayerSelectionWindow extends BaseWindow {
public PlayerSelectionWindow(Player p) {
super(p);
}
@Override
protected void fillGUI() {
Settings settings = MinigameHandler.getSettings(p);
for (Player online : Bukkit.getOnlinePlayers()) {
if (!MinigameHandler.getOccupiedPlayers().contains(online)) {
boolean selected = settings.getSelectedPlayers().contains(online);
ItemStack head = makePlayerHead(online, selected);
NBTHelper.set(head, "Action", "clickedPlayer");
NBTHelper.set(head, "Player", online.getName());
add(head);
}
}
ItemStack back = makeItem(Material.ARROW, "Back");
NBTHelper.set(back, "Action", "back");
place(49, back);
}
@Override
public void handleClick(String action, InventoryClickEvent event) {
if (action.equals("back")) {
new MinigameSetupWindow(p).buildWindow();
return;
}
if (action.equals("clickedPlayer")) {
String playerName = NBTHelper.get(event.getCurrentItem(), "Player");
Player target = Bukkit.getPlayer(playerName);
if (target == null) return;
Settings settings = MinigameHandler.getSettings(p);
if (settings.getSelectedPlayers().contains(target)) {
settings.removePlayersFromSelection(target);
} else {
settings.addPlayersToSelection(target);
}
new PlayerSelectionWindow(p).buildWindow();
}
}
private ItemStack makePlayerHead(Player target, boolean selected) {
ItemStack head = new ItemStack(Material.PLAYER_HEAD);
SkullMeta meta = (SkullMeta) head.getItemMeta();
if (meta != null) {
meta.setOwningPlayer(target);
meta.setDisplayName((selected ? ChatColor.GREEN : ChatColor.RED) + target.getName());
head.setItemMeta(meta);
}
return head;
}
}

View File

@ -0,0 +1,67 @@
package de.ventority.randomizedminigames.gui.windows;
import de.ventority.randomizedminigames.gui.BaseWindow;
import de.ventority.randomizedminigames.gui.NBTHelper;
import de.ventority.randomizedminigames.util.MinigameHandler;
import de.ventority.randomizedminigames.util.Settings;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
public class SetLimitWindow extends BaseWindow {
public SetLimitWindow(Player p) {
super(p);
}
@Override
protected void fillGUI() {
Settings settings = MinigameHandler.getSettings(p);
ItemStack sub = makeItem(Material.GREEN_DYE, "Sub");
NBTHelper.set(sub, "Action", "subFromLimit");
place(12, sub);
ItemStack display = makeItem(Material.PAPER, String.valueOf(settings.getSelectedLimit()));
NBTHelper.set(display, "Action", "none");
place(13, display);
ItemStack add = makeItem(Material.RED_DYE, "Add");
NBTHelper.set(add, "Action", "addToLimit");
place(14, add);
ItemStack toggle = !settings.isTimed
? makeItem(Material.LIME_DYE, ChatColor.GREEN + "Enabled - click to disable")
: makeItem(Material.GRAY_DYE, ChatColor.RED + "Disabled - click to enable");
NBTHelper.set(toggle, "Action", "toggleWinLimit");
place(22, toggle);
ItemStack back = makeItem(Material.ARROW, "Back");
NBTHelper.set(back, "Action", "back");
place(49, back);
}
@Override
public void handleClick(String action, InventoryClickEvent event) {
Settings settings = MinigameHandler.getSettings(p);
switch (action) {
case "addToLimit":
settings.addToWinLimit();
new SetLimitWindow(p).buildWindow();
break;
case "subFromLimit":
settings.subFromWinLimit();
new SetLimitWindow(p).buildWindow();
break;
case "toggleWinLimit":
settings.isTimed = !settings.isTimed;
new SetLimitWindow(p).buildWindow();
break;
case "back":
new MinigameSetupWindow(p).buildWindow();
break;
}
}
}

View File

@ -0,0 +1,84 @@
package de.ventority.randomizedminigames.gui.windows;
import de.ventority.randomizedminigames.gui.BaseWindow;
import de.ventority.randomizedminigames.gui.NBTHelper;
import de.ventority.randomizedminigames.util.MinigameHandler;
import de.ventority.randomizedminigames.util.Settings;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
public class SetTimeLimitWindow extends BaseWindow {
public SetTimeLimitWindow(Player p) {
super(p);
}
@Override
protected void fillGUI() {
Settings settings = MinigameHandler.getSettings(p);
ItemStack sub30 = makeItem(Material.GREEN_DYE, "-30min");
NBTHelper.set(sub30, "Action", "sub30");
place(10, sub30);
ItemStack sub10 = makeItem(Material.GREEN_DYE, "-10min");
NBTHelper.set(sub10, "Action", "sub10");
place(11, sub10);
ItemStack sub1 = makeItem(Material.GREEN_DYE, "-1min");
NBTHelper.set(sub1, "Action", "sub1");
place(12, sub1);
ItemStack display = makeItem(Material.PAPER, formatTime(settings.getTimeLimit()));
NBTHelper.set(display, "Action", "none");
place(13, display);
ItemStack add1 = makeItem(Material.RED_DYE, "+1min");
NBTHelper.set(add1, "Action", "add1");
place(14, add1);
ItemStack add10 = makeItem(Material.RED_DYE, "+10min");
NBTHelper.set(add10, "Action", "add10");
place(15, add10);
ItemStack add30 = makeItem(Material.RED_DYE, "+30min");
NBTHelper.set(add30, "Action", "add30");
place(16, add30);
ItemStack toggle = settings.isTimed
? makeItem(Material.LIME_DYE, ChatColor.GREEN + "Enabled - click to disable")
: makeItem(Material.GRAY_DYE, ChatColor.RED + "Disabled - click to enable");
NBTHelper.set(toggle, "Action", "toggleTimer");
place(22, toggle);
ItemStack back = makeItem(Material.ARROW, "Back");
NBTHelper.set(back, "Action", "back");
place(49, back);
}
@Override
public void handleClick(String action, InventoryClickEvent event) {
Settings settings = MinigameHandler.getSettings(p);
switch (action) {
case "add30": settings.setTimeLimit(settings.getTimeLimit() + 30 * 60); break;
case "add10": settings.setTimeLimit(settings.getTimeLimit() + 10 * 60); break;
case "add1": settings.setTimeLimit(settings.getTimeLimit() + 60); break;
case "sub30": settings.setTimeLimit(settings.getTimeLimit() - 30 * 60); break;
case "sub10": settings.setTimeLimit(settings.getTimeLimit() - 10 * 60); break;
case "sub1": settings.setTimeLimit(settings.getTimeLimit() - 60); break;
case "toggleTimer": settings.isTimed = !settings.isTimed; break;
case "back": new MinigameSetupWindow(p).buildWindow(); return;
}
new SetTimeLimitWindow(p).buildWindow();
}
private String formatTime(int totalSeconds) {
int minutes = totalSeconds / 60;
int seconds = totalSeconds % 60;
if (minutes == 0) return String.valueOf(seconds);
return minutes + ":" + String.format("%02d", seconds);
}
}

View File

@ -0,0 +1,27 @@
package de.ventority.randomizedminigames.gui.windows;
import de.ventority.randomizedminigames.gui.BaseWindow;
import de.ventority.randomizedminigames.gui.NBTHelper;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
public class SettingsWindow extends BaseWindow {
public SettingsWindow(Player p) {
super(p);
}
@Override
protected void fillGUI() {
ItemStack setContestants = makeItem(Material.ZOMBIE_HEAD, "Add Contestants");
NBTHelper.set(setContestants, "Action", "addContestants");
add(setContestants);
}
@Override
public void handleClick(String action, InventoryClickEvent event) {
// Not yet implemented
}
}

View File

@ -0,0 +1,57 @@
package de.ventority.randomizedminigames.gui.windows;
import de.ventority.randomizedminigames.gui.BaseWindow;
import de.ventority.randomizedminigames.gui.NBTHelper;
import de.ventority.randomizedminigames.util.MinigameHandler;
import de.ventority.randomizedminigames.util.Settings;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
public class TeamCountSelectionWindow extends BaseWindow {
public TeamCountSelectionWindow(Player p) {
super(p);
}
@Override
protected void fillGUI() {
Settings settings = MinigameHandler.getSettings(p);
ItemStack sub = makeItem(Material.GREEN_DYE, "Sub");
NBTHelper.set(sub, "Action", "subTeamCount");
place(12, sub);
ItemStack display = makeItem(Material.PAPER, String.valueOf(settings.getTeamCount()));
NBTHelper.set(display, "Action", "none");
place(13, display);
ItemStack add = makeItem(Material.RED_DYE, "Add");
NBTHelper.set(add, "Action", "addTeamCount");
place(14, add);
ItemStack next = makeItem(Material.ARROW, "Next");
NBTHelper.set(next, "Action", "next");
place(49, next);
}
@Override
public void handleClick(String action, InventoryClickEvent event) {
Settings settings = MinigameHandler.getSettings(p);
switch (action) {
case "addTeamCount":
settings.addTeamCount();
new TeamCountSelectionWindow(p).buildWindow();
break;
case "subTeamCount":
settings.subTeamCount();
new TeamCountSelectionWindow(p).buildWindow();
break;
case "next":
MinigameHandler.getSettings(p).initTeams();
new TeamSetupSelectionWindow(p).buildWindow();
break;
}
}
}

View File

@ -0,0 +1,93 @@
package de.ventority.randomizedminigames.gui.windows;
import de.ventority.randomizedminigames.gui.BaseWindow;
import de.ventority.randomizedminigames.gui.NBTHelper;
import de.ventority.randomizedminigames.util.MinigameHandler;
import de.ventority.randomizedminigames.util.Settings;
import de.ventority.randomizedminigames.util.Team;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
public class TeamPlayerSelectionWindow extends BaseWindow {
private static final ChatColor[] TEAM_COLORS = {
ChatColor.GREEN, ChatColor.RED, ChatColor.BLUE,
ChatColor.DARK_PURPLE, ChatColor.BLACK, ChatColor.DARK_GREEN
};
private static final Material[] TEAM_MATERIALS = {
Material.GREEN_WOOL, Material.RED_WOOL, Material.BLUE_WOOL,
Material.PURPLE_WOOL, Material.BLACK_WOOL, Material.GREEN_WOOL
};
public TeamPlayerSelectionWindow(Player p) {
super(p);
}
@Override
protected void fillGUI() {
Settings settings = MinigameHandler.getSettings(p);
int teamIndex = settings.getSelectedTeamIndex();
Team currentTeam = settings.getTeam(teamIndex);
for (Player online : Bukkit.getOnlinePlayers()) {
if (MinigameHandler.getOccupiedPlayers().contains(online)) continue;
boolean inCurrentTeam = currentTeam.getPlayers().contains(online);
// Hide players already assigned to a different team
boolean inOtherTeam = settings.getSelectedPlayers().contains(online) && !inCurrentTeam;
if (inOtherTeam) continue;
ItemStack head = makePlayerHead(online, inCurrentTeam);
NBTHelper.set(head, "Action", "clickedPlayerInTeams");
NBTHelper.set(head, "Player", online.getName());
add(head);
}
ItemStack teamIndicator = makeItem(TEAM_MATERIALS[teamIndex],
TEAM_COLORS[teamIndex] + "Team #" + (teamIndex + 1));
NBTHelper.set(teamIndicator, "Action", "none");
place(4, teamIndicator);
ItemStack back = makeItem(Material.ARROW, "Back");
NBTHelper.set(back, "Action", "back");
place(49, back);
}
@Override
public void handleClick(String action, InventoryClickEvent event) {
if (action.equals("back")) {
new TeamSetupSelectionWindow(p).buildWindow();
return;
}
if (action.equals("clickedPlayerInTeams")) {
String playerName = NBTHelper.get(event.getCurrentItem(), "Player");
Player target = Bukkit.getPlayer(playerName);
if (target == null) return;
Settings settings = MinigameHandler.getSettings(p);
Team team = settings.getTeam(settings.getSelectedTeamIndex());
if (team.getPlayers().contains(target)) {
team.removePlayer(target);
settings.removePlayersFromSelection(target);
} else {
team.addPlayer(target);
settings.addPlayersToSelection(target);
}
new TeamPlayerSelectionWindow(p).buildWindow();
}
}
private ItemStack makePlayerHead(Player target, boolean inCurrentTeam) {
ItemStack head = new ItemStack(Material.PLAYER_HEAD);
SkullMeta meta = (SkullMeta) head.getItemMeta();
if (meta != null) {
meta.setOwningPlayer(target);
meta.setDisplayName((inCurrentTeam ? ChatColor.GREEN : ChatColor.RED) + target.getName());
head.setItemMeta(meta);
}
return head;
}
}

View File

@ -0,0 +1,56 @@
package de.ventority.randomizedminigames.gui.windows;
import de.ventority.randomizedminigames.gui.BaseWindow;
import de.ventority.randomizedminigames.gui.NBTHelper;
import de.ventority.randomizedminigames.util.MinigameHandler;
import de.ventority.randomizedminigames.util.Settings;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
public class TeamSetupSelectionWindow extends BaseWindow {
private static final ChatColor[] TEAM_COLORS = {
ChatColor.GREEN, ChatColor.RED, ChatColor.BLUE,
ChatColor.DARK_PURPLE, ChatColor.BLACK, ChatColor.DARK_GREEN
};
private static final Material[] TEAM_MATERIALS = {
Material.GREEN_WOOL, Material.RED_WOOL, Material.BLUE_WOOL,
Material.PURPLE_WOOL, Material.BLACK_WOOL, Material.GREEN_WOOL
};
public TeamSetupSelectionWindow(Player p) {
super(p);
}
@Override
protected void fillGUI() {
Settings settings = MinigameHandler.getSettings(p);
for (int i = 0; i < settings.getTeamCount(); i++) {
int playerCount = settings.getTeam(i).getPlayers().size();
String name = TEAM_COLORS[i] + "Team #" + (i + 1) + ChatColor.GRAY + " (" + playerCount + " players)";
ItemStack item = makeItem(TEAM_MATERIALS[i], name);
NBTHelper.set(item, "Action", "selectTeam");
NBTHelper.set(item, "selectedTeam", Integer.toString(i));
add(item);
}
ItemStack start = makeItem(Material.GREEN_DYE, "Start Game");
NBTHelper.set(start, "Action", "startGame");
place(50, start);
}
@Override
public void handleClick(String action, InventoryClickEvent event) {
if (action.equals("selectTeam")) {
String teamIndex = NBTHelper.get(event.getCurrentItem(), "selectedTeam");
if (teamIndex == null) return;
MinigameHandler.getSettings(p).setSelectedTeamIndex(Integer.parseInt(teamIndex));
new TeamPlayerSelectionWindow(p).buildWindow();
} else if (action.equals("startGame")) {
MinigameHandler.createMinigame(3, p);
p.closeInventory();
}
}
}

View File

@ -1,4 +1,37 @@
package de.ventority.randomizedminigames.misc;
import java.awt.Color;
public class ColorCycler {
private final Color from;
private final Color to;
private final double cyclesPerSecond;
/**
* @param from start color of the pulse
* @param to end color of the pulse
* @param cyclesPerSecond how many full darklightdark cycles per second
*/
public ColorCycler(Color from, Color to, double cyclesPerSecond) {
this.from = from;
this.to = to;
this.cyclesPerSecond = cyclesPerSecond;
}
/**
* Returns the interpolated color for a given tick (20 ticks = 1 second).
* Uses a sine wave so the transition is smooth in both directions.
*/
public Color getColor(int tick) {
double t = (Math.sin(tick * (2 * Math.PI * cyclesPerSecond / 20.0)) + 1.0) / 2.0;
return new Color(
lerp(from.getRed(), to.getRed(), t),
lerp(from.getGreen(), to.getGreen(), t),
lerp(from.getBlue(), to.getBlue(), t)
);
}
private static int lerp(int a, int b, double t) {
return (int) Math.round(a + (b - a) * t);
}
}

View File

@ -2,13 +2,16 @@ package de.ventority.randomizedminigames.misc.Timer;
import de.ventority.randomizedminigames.Minigames.MinigameBase;
import de.ventority.randomizedminigames.RandomizedMinigames;
import de.ventority.randomizedminigames.misc.ColorCycler;
import de.ventority.randomizedminigames.util.MinigameHandler;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask;
import java.awt.Color;
import java.util.List;
@ -23,7 +26,11 @@ public class Timer {
private boolean isReversed = false;
private String customText;
private int countedSeconds = 0;
private String defaultText;
private final ColorCycler colorCycler = new ColorCycler(
new Color(110, 0, 145),
new Color(130, 50, 170),
0.2
);
public Timer(List<Player> players, MinigameBase minigame, String text) {
this.players = players;
@ -49,14 +56,13 @@ public class Timer {
counterTask = Bukkit.getScheduler().runTaskTimer(RandomizedMinigames.serverSettingsHandler.getPlugin(), () -> {
countedSeconds = counter / 20;
updateText();
updatePlayers();
if (!isPaused) {
counter++;
if (countedSeconds == stopTime && MinigameHandler.getSettings(minigame.getOwner()).isTimed) {
if (countedSeconds == stopTime) {
if (methodToCall != null)
methodToCall.run();
else
else if (MinigameHandler.getSettings(minigame.getOwner()).isTimed)
minigame.stopGame();
stopCounter();
}
@ -104,30 +110,11 @@ public class Timer {
}
private void updatePlayers() {
// int amplitude = 40;
//
// int step = counter % (amplitude * 2);
// int brightness = step <= amplitude ? step : (amplitude * 2 - step);
//
// int baseRed = 125;
// int baseGreen = 0;
// int baseBlue = 130;
//
//
// Color c = new Color(
// baseRed + 2*brightness,
// baseGreen,
// baseBlue + 2*brightness
// );
//
TextComponent msg = new TextComponent(defaultText);
// msg.setColor(ChatColor.of(c));
msg.setBold(true);
TextComponent msg = new TextComponent("§l" + updateText());
msg.setColor(ChatColor.of(colorCycler.getColor(counter)));
for (Player player : players) {
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, msg);
}
}
public void setStopTime(int seconds) {

View File

@ -16,13 +16,18 @@ public class MinigameHandler {
public static void createMinigame(int gameNumber, Player caller) {
List<Player> players = settings.get(caller).getSelectedPlayers();
MinigameBase newGame = null;
switch (gameNumber) {
case 0: minigames.add(new ForceItemBattle(players, caller)); break;
case 1: minigames.add(new ForceItemBattleSameItems(players, caller)); break;
case 2: minigames.add(new BlockRandomizer(players, caller)); break;
case 4: minigames.add(new OnlyChests(players, caller)); break;
case 0: newGame = new ForceItemBattle(players, caller); break;
case 1: newGame = new ForceItemBattleSameItems(players, caller); break;
case 2: newGame = new BlockRandomizer(players, caller); break;
case 3: newGame = new ForceItemBattleTeams(players, caller, settings.get(caller).getTeams()); break;
case 4: newGame = new OnlyChests(players, caller); break;
}
if (newGame != null) {
minigames.add(newGame);
getServer().getPluginManager().registerEvents(newGame, RandomizedMinigames.serverSettingsHandler.getPlugin());
}
getServer().getPluginManager().registerEvents(minigames.getFirst(), RandomizedMinigames.serverSettingsHandler.getPlugin());
}
public static List<MinigameBase> getMinigames() {
@ -45,7 +50,7 @@ public class MinigameHandler {
}
public static void killAll() {
for (MinigameBase minigame : minigames)
for (MinigameBase minigame : new ArrayList<>(minigames))
minigame.killGame();
}

View File

@ -7,36 +7,35 @@ import org.bukkit.inventory.ItemStack;
public class PlayerBackup {
private final ItemStack[] inventory;
private final ItemStack[] armor;
private final ItemStack offhand;
private final float exp;
private final int level;
private final Location location;
private GameMode gamemode;
private final GameMode gamemode;
private final double health;
private final int foodLevel;
public PlayerBackup(ItemStack[] inventory, ItemStack[] armor, float exp, Location location, GameMode gamemode) {
public PlayerBackup(ItemStack[] inventory, ItemStack[] armor, ItemStack offhand,
float exp, int level, Location location, GameMode gamemode,
double health, int foodLevel) {
this.inventory = inventory;
this.armor = armor;
this.offhand = offhand;
this.exp = exp;
this.level = level;
this.location = location;
this.gamemode = gamemode;
this.health = health;
this.foodLevel = foodLevel;
}
public ItemStack[] getInventory() {
return inventory;
}
public ItemStack[] getArmor() {
return armor;
}
public float getExp() {
return exp;
}
public Location getLocation() {
return location;
}
public GameMode getGamemode() {
return gamemode;
}
public ItemStack[] getInventory() { return inventory; }
public ItemStack[] getArmor() { return armor; }
public ItemStack getOffhand() { return offhand; }
public float getExp() { return exp; }
public int getLevel() { return level; }
public Location getLocation() { return location; }
public GameMode getGamemode() { return gamemode; }
public double getHealth() { return health; }
public int getFoodLevel() { return foodLevel; }
}

View File

@ -1,32 +1,91 @@
package de.ventority.randomizedminigames.util;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
public class PlayerBackupHandler {
private HashMap<Player, PlayerBackup> playerBackups = new HashMap<>();
// Backups for players currently in a minigame, keyed by UUID so they survive reconnects.
private final HashMap<UUID, PlayerBackup> playerBackups = new HashMap<>();
// Players who were offline when killGame() ran restored the next time they join.
private static final HashMap<UUID, PlayerBackup> pendingRestores = new HashMap<>();
public PlayerBackupHandler(List<Player> players) {
for (Player player : players) {
PlayerBackup backup = new PlayerBackup(player.getInventory().getContents(), player.getInventory().getArmorContents(), player.getExp(), player.getLocation(), player.getGameMode());
playerBackups.put(player, backup);
playerBackups.put(player.getUniqueId(), new PlayerBackup(
clone(player.getInventory().getContents()),
clone(player.getInventory().getArmorContents()),
cloneItem(player.getInventory().getItemInOffHand()),
player.getExp(),
player.getLevel(),
player.getLocation(),
player.getGameMode(),
player.getHealth(),
player.getFoodLevel()
));
}
}
public void restorePlayerBackup(Player player) {
PlayerBackup backup = playerBackups.get(player);
PlayerBackup backup = playerBackups.get(player.getUniqueId());
if (backup == null) return;
applyBackup(player, backup);
}
/**
* Restores online players immediately.
* Players who are currently offline are queued in pendingRestores
* and will be restored the next time they join.
*/
public void restoreAll() {
for (UUID uuid : playerBackups.keySet()) {
Player player = Bukkit.getPlayer(uuid);
if (player != null && player.isOnline()) {
applyBackup(player, playerBackups.get(uuid));
} else {
pendingRestores.put(uuid, playerBackups.get(uuid));
}
}
}
/** Called on every PlayerJoinEvent — restores any backup queued while the player was offline. */
public static void restoreIfPending(Player player) {
PlayerBackup backup = pendingRestores.remove(player.getUniqueId());
if (backup != null) applyBackup(player, backup);
}
private static void applyBackup(Player player, PlayerBackup backup) {
player.getInventory().clear();
player.getInventory().setArmorContents(null);
Collection<PotionEffect> effects = player.getActivePotionEffects();
for (PotionEffect effect : effects)
player.removePotionEffect(effect.getType());
player.getInventory().setContents(backup.getInventory());
player.getInventory().setArmorContents(backup.getArmor());
player.getInventory().setItemInOffHand(backup.getOffhand());
player.setExp(backup.getExp());
player.setLevel(backup.getLevel());
player.setHealth(backup.getHealth());
player.setFoodLevel(backup.getFoodLevel());
player.teleport(backup.getLocation());
player.setGameMode(backup.getGamemode());
}
public void restoreAll() {
for (Player player : playerBackups.keySet()) {
restorePlayerBackup(player);
}
private static org.bukkit.inventory.ItemStack[] clone(org.bukkit.inventory.ItemStack[] source) {
org.bukkit.inventory.ItemStack[] copy = new org.bukkit.inventory.ItemStack[source.length];
for (int i = 0; i < source.length; i++)
copy[i] = source[i] != null ? source[i].clone() : null;
return copy;
}
private static org.bukkit.inventory.ItemStack cloneItem(org.bukkit.inventory.ItemStack item) {
return item != null ? item.clone() : null;
}
}

View File

@ -1,5 +1,6 @@
package de.ventority.randomizedminigames.util;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import java.util.ArrayList;
@ -88,6 +89,22 @@ public class Settings {
this.timeLimit = timeLimit;
}
public void initTeams() {
teams.clear();
selectedPlayers.clear();
ChatColor[] colors = {
ChatColor.GREEN, ChatColor.RED, ChatColor.BLUE,
ChatColor.DARK_PURPLE, ChatColor.BLACK, ChatColor.DARK_GREEN
};
for (int i = 0; i < selectedTeamCount; i++) {
teams.add(new Team(new ArrayList<>(), colors[i]));
}
}
public List<Team> getTeams() {
return teams;
}
public Team getTeam(int i) {
return teams.get(i);
}

View File

@ -1,69 +0,0 @@
{
"title": "Minigame Setup",
"rows": 6,
"items": [
{
"slot": -1,
"material": "PLAYER_HEAD",
"name": "Select Players",
"nbt": {
"Type": "MinigameSetup",
"Action": "startPlayerSelection"
}
},
{
"slot": -1,
"material": "BOOK",
"name": "Set win limit",
"nbt": {
"Type": "MinigameSetup",
"Action": "startLimitSelection"
}
},
{
"slot": -1,
"material": "EMERALD",
"name": "Scoreboard: %scoreboardState%",
"nbt": {
"Type": "MinigameSetup",
"Action": "switchScoreboard"
}
},
{
"slot": 50,
"material": "GREEN_DYE",
"name": "Start",
"nbt": {
"Type": "MinigameSetup",
"Action": "startGame"
}
},
{
"slot": -1,
"material": "CLOCK",
"name": "Set Timer",
"nbt": {
"Type": "MinigameSetup",
"Action": "startTimerSetup"
}
},
{
"slot": -1,
"material": "TARGET",
"name": "Timer: %timer%",
"nbt": {
"Type": "MinigameSetup",
"Action": "toggleTimer"
}
},
{
"slot": 49,
"material": "ARROW",
"name": "Back",
"nbt": {
"Type": "MinigameSelect",
"Action": "homeMenu"
}
}
]
}