Easter/src/main/java/com/alttd/easter/gui/TurnInGuiManager.java

162 lines
6.4 KiB
Java

package com.alttd.easter.gui;
import com.alttd.easter.config.Config;
import com.alttd.easter.config.Messages;
import com.alttd.easter.data.DataManager;
import com.alttd.easter.egg.EggType;
import com.alttd.easter.util.ItemUtils;
import lombok.extern.slf4j.Slf4j;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.JoinConfiguration;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import java.util.*;
@Slf4j
public class TurnInGuiManager implements Listener {
private final DataManager dataManager;
private final Map<UUID, Inventory> openInventories = new HashMap<>();
public TurnInGuiManager(DataManager dataManager) {
this.dataManager = dataManager;
}
private Component title() {
return MiniMessage.miniMessage().deserialize(Messages.RABBIT.GUI_TITLE);
}
public void open(Player player) {
Inventory inv = Bukkit.createInventory(player, 27, title());
openInventories.put(player.getUniqueId(), inv);
player.openInventory(inv);
}
@EventHandler
public void onClick(InventoryClickEvent event) {
if (!(event.getWhoClicked() instanceof Player player)) {
return;
}
Inventory top = openInventories.get(player.getUniqueId());
if (top == null) {
return;
}
if (!event.getView().getTopInventory().equals(top)) {
return;
}
// If clicking in player inventory with shift-click, prevent moving non-egg items into GUI
if (event.isShiftClick() && event.getClickedInventory() != null && event.getClickedInventory().equals(player.getInventory())) {
ItemStack stack = event.getCurrentItem();
if (stack != null && !stack.getType().isAir() && !ItemUtils.isEggItem(stack)) {
event.setCancelled(true);
return;
}
}
// If placing an item into the GUI (cursor over top inventory), only allow egg items
boolean inTop = event.getRawSlot() < top.getSize() && event.getRawSlot() >= 0;
if (inTop) {
ItemStack cursor = event.getCursor();
if (!cursor.getType().isAir() && !ItemUtils.isEggItem(cursor)) {
event.setCancelled(true);
}
}
}
@EventHandler
public void onClose(InventoryCloseEvent event) {
Player player = (Player) event.getPlayer();
Inventory top = openInventories.get(player.getUniqueId());
if (top == null) {
return;
}
if (!event.getView().getTopInventory().equals(top)) {
return;
}
openInventories.remove(player.getUniqueId());
// collect egg items for submission and then clear GUI so eggs don't drop
Set<EggType> submitted = new HashSet<>();
for (ItemStack item : top.getContents()) {
if (ItemUtils.isEggItem(item)) {
EggType type = ItemUtils.getEggType(item);
if (type != null) {
submitted.add(type);
}
}
}
top.clear();
if (submitted.isEmpty()) {
player.sendRichMessage(Messages.RABBIT.NO_EGGS);
return;
}
// determine how many new unique egg types were added so we can award correct number of prizes
int prevTotal = dataManager.getPlayerEggs(player.getUniqueId()).size();
int newlyAdded = dataManager.addEggs(player.getUniqueId(), submitted);
dataManager.save();
// Dialog formatting for submission summary
List<Component> eggComponents = new ArrayList<>();
for (EggType type : submitted) {
eggComponents.add(Component.text(ItemUtils.colorName(type)));
}
if (eggComponents.size() == 1) {
player.sendRichMessage(Messages.RABBIT.ONE_EGG,
Placeholder.parsed("player", player.getName()),
Placeholder.component("egg1", eggComponents.getFirst())
);
} else {
Component eggsJoined;
if (eggComponents.size() == 2) {
eggsJoined = Component.join(
JoinConfiguration.builder()
.lastSeparator(Component.text(" and "))
.build(),
eggComponents
);
} else {
eggsJoined = Component.join(
JoinConfiguration.builder()
.separator(Component.text(", "))
.lastSeparator(Component.text(", and "))
.build(),
eggComponents
);
}
player.sendRichMessage(Messages.RABBIT.MULTI_EGGS,
Placeholder.parsed("player", player.getName()),
Placeholder.component("eggs", eggsJoined)
);
}
int newTotal = prevTotal + newlyAdded;
int prevMilestones = prevTotal / 4;
int newMilestones = newTotal / 4;
int prizesToGive = Math.max(0, newMilestones - prevMilestones);
List<ItemStack> prizeList = Config.PRIZES.LIST;
for (int i = 0; i < prizesToGive; i++) {
int intendedIndex = prevMilestones + i;
if (prizeList.isEmpty()) {
log.warn("No prizes configured. Tried to give prize for intended index {}. Staff should configure prizes using /easter setprize.", intendedIndex);
} else {
int wrappedIndex = intendedIndex % prizeList.size();
if (intendedIndex >= prizeList.size() || intendedIndex < 0) {
log.warn("Prize index overflow: intended index {} -> wrapped to {} (prize list size {}).", intendedIndex, wrappedIndex, prizeList.size());
}
ItemStack prize = prizeList.get(wrappedIndex).clone();
player.getInventory().addItem(prize);
}
player.sendRichMessage(Messages.RABBIT.REWARD);
}
}
}