Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,34 @@

import lombok.Getter;
import org.bukkit.Material;
import org.bukkit.Sound;

import java.util.Map;

@Getter
public class GuiButton {
private final String buttonType;
private final int slot;
private final Material material;
private final boolean enabled;
private final Sound sound;
private final Map<String, Object> conditions;

public GuiButton(String buttonType, int slot, Material material, boolean enabled) {
public GuiButton(String buttonType, int slot, Material material, boolean enabled, Sound sound, Map<String, Object> conditions) {
this.buttonType = buttonType;
this.slot = slot;
this.material = material;
this.enabled = enabled;
this.sound = sound;
this.conditions = conditions;
}

public boolean hasSound() {
return sound != null;
}

public boolean hasConditions() {
return conditions != null && !conditions.isEmpty();
}

@Override
Expand All @@ -24,6 +39,8 @@ public String toString() {
", slot=" + slot +
", material=" + material +
", enabled=" + enabled +
", sound=" + sound +
", conditions=" + conditions +
'}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,14 @@ public class GuiLayout {
private final Map<Integer, String> slotToButtonType = new HashMap<>();

public void addButton(String buttonType, GuiButton button) {
// Remove old button if it exists
// Check if slot is already occupied by another button
String existingButtonType = slotToButtonType.get(button.getSlot());
if (existingButtonType != null && !existingButtonType.equals(buttonType)) {
// Remove the existing button to replace it with the new one
buttons.remove(existingButtonType);
}

// Remove old button if this buttonType already exists in a different slot
GuiButton oldButton = buttons.get(buttonType);
if (oldButton != null) {
slotToButtonType.remove(oldButton.getSlot());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package github.nighter.smartspawner.spawner.gui.layout;

import github.nighter.smartspawner.SmartSpawner;
import github.nighter.smartspawner.updates.GuiLayoutUpdater;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;

public class GuiLayoutConfig {
Expand All @@ -18,12 +23,14 @@ public class GuiLayoutConfig {

private final SmartSpawner plugin;
private final File layoutsDir;
private final GuiLayoutUpdater guiLayoutUpdater;
private String currentLayout;
private GuiLayout currentGuiLayout;

public GuiLayoutConfig(SmartSpawner plugin) {
this.plugin = plugin;
this.layoutsDir = new File(plugin.getDataFolder(), GUI_LAYOUTS_DIR);
this.guiLayoutUpdater = new GuiLayoutUpdater(plugin);
loadLayout();
}

Expand All @@ -38,6 +45,9 @@ private void initializeLayoutsDirectory() {
layoutsDir.mkdirs();
}
autoSaveLayoutFiles();

// Update GUI layouts using the new updater system
guiLayoutUpdater.checkAndUpdateGuiLayouts();
}

private void autoSaveLayoutFiles() {
Expand Down Expand Up @@ -128,8 +138,16 @@ private boolean loadButton(FileConfiguration config, GuiLayout layout, String bu
return false;
}

// Check conditions first
Map<String, Object> conditions = loadConditions(config, path);
if (!evaluateConditions(conditions)) {
plugin.debug("Button '" + buttonKey + "' skipped due to failed conditions: " + conditions);
return false;
}

int slot = config.getInt(path + ".slot", -1);
String materialName = config.getString(path + ".material", "STONE");
String soundName = config.getString(path + ".sound", null);

if (!isValidSlot(slot)) {
plugin.getLogger().warning(String.format(
Expand All @@ -139,13 +157,56 @@ private boolean loadButton(FileConfiguration config, GuiLayout layout, String bu
}

Material material = parseMaterial(materialName, buttonKey);
Sound sound = parseSound(soundName, buttonKey);
int actualSlot = SLOT_OFFSET + slot;

GuiButton button = new GuiButton(buttonKey, actualSlot, material, true);
GuiButton button = new GuiButton(buttonKey, actualSlot, material, true, sound, conditions);
layout.addButton(buttonKey, button);
return true;
}

private Map<String, Object> loadConditions(FileConfiguration config, String path) {
Map<String, Object> conditions = new HashMap<>();
ConfigurationSection conditionsSection = config.getConfigurationSection(path + ".conditions");
if (conditionsSection != null) {
for (String key : conditionsSection.getKeys(false)) {
conditions.put(key, conditionsSection.get(key));
}
}
return conditions;
}

private boolean evaluateConditions(Map<String, Object> conditions) {
if (conditions.isEmpty()) {
return true; // No conditions means always show
}

for (Map.Entry<String, Object> condition : conditions.entrySet()) {
String conditionKey = condition.getKey();
Object expectedValue = condition.getValue();

if (!evaluateCondition(conditionKey, expectedValue)) {
return false; // If any condition fails, don't show button
}
}

return true; // All conditions passed
}

private boolean evaluateCondition(String conditionKey, Object expectedValue) {
switch (conditionKey.toLowerCase()) {
case "shopintegration":
// Check if shop integration is enabled in the plugin
boolean shopEnabled = plugin.getConfig().getBoolean("custom_economy.shop_integration.enabled", false);
return shopEnabled == (Boolean) expectedValue;

// Add more condition types here as needed
default:
plugin.getLogger().warning("Unknown condition type: " + conditionKey);
return true; // Unknown conditions default to true to avoid breaking configs
}
}

private boolean isValidSlot(int slot) {
return slot >= MIN_SLOT && slot <= MAX_SLOT;
}
Expand All @@ -161,6 +222,21 @@ private Material parseMaterial(String materialName, String buttonKey) {
}
}

private Sound parseSound(String soundName, String buttonKey) {
if (soundName == null || soundName.trim().isEmpty()) {
return null; // No sound specified
}

try {
return Sound.valueOf(soundName.toUpperCase());
} catch (IllegalArgumentException e) {
plugin.getLogger().warning(String.format(
"Invalid sound %s for button %s. No sound will be played.",
soundName, buttonKey));
return null;
}
}

public GuiLayout getCurrentLayout() {
return currentGuiLayout;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import github.nighter.smartspawner.spawner.gui.main.SpawnerMenuUI;
import github.nighter.smartspawner.spawner.gui.synchronization.SpawnerGuiViewManager;
import github.nighter.smartspawner.spawner.gui.layout.GuiLayout;
import github.nighter.smartspawner.spawner.gui.layout.GuiButton;
import github.nighter.smartspawner.spawner.properties.SpawnerManager;
import github.nighter.smartspawner.spawner.properties.VirtualInventory;
import github.nighter.smartspawner.language.LanguageManager;
Expand Down Expand Up @@ -155,21 +156,24 @@ private void handleControlSlotClick(Player player, int slot, StoragePageHolder h
break;
case "previous_page":
if (holder.getCurrentPage() > 1) {
updatePageContent(player, spawner, holder.getCurrentPage() - 1, inventory, true);
playButtonSound(player, buttonType);
updatePageContent(player, spawner, holder.getCurrentPage() - 1, inventory, false);
}
break;
case "take_all":
handleTakeAllItems(player, inventory);
break;
case "next_page":
if (holder.getCurrentPage() < holder.getTotalPages()) {
updatePageContent(player, spawner, holder.getCurrentPage() + 1, inventory, true);
playButtonSound(player, buttonType);
updatePageContent(player, spawner, holder.getCurrentPage() + 1, inventory, false);
}
break;
case "drop_page":
handleDropPageItems(player, spawner, inventory);
break;
case "shop_indicator":
case "sell":
if (plugin.hasSellIntegration()) {
if (!player.hasPermission("smartspawner.sellall")) {
messageService.sendMessage(player, "no_permission");
Expand All @@ -178,7 +182,7 @@ private void handleControlSlotClick(Player player, int slot, StoragePageHolder h
if (isClickTooFrequent(player)) {
return;
}
player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1.0f, 1.0f);
playButtonSound(player, buttonType);
spawnerSellManager.sellAllItems(player, spawner);
}
break;
Expand Down Expand Up @@ -313,7 +317,7 @@ private void handleDropPageItems(Player player, SpawnerData spawner, Inventory i
}

updatePageContent(player, spawner, holder.getCurrentPage(), inventory, false);
player.playSound(player.getLocation(), Sound.ENTITY_ITEM_PICKUP, 0.8f, 0.8f);
playButtonSound(player, "drop_page");
}

private void dropItemsInDirection(Player player, List<ItemStack> items) {
Expand Down Expand Up @@ -357,6 +361,7 @@ private void openFilterConfig(Player player, SpawnerData spawner) {
if (isClickTooFrequent(player)) {
return;
}
playButtonSound(player, "item_filter");
filterConfigUI.openFilterConfigGUI(player, spawner);
}

Expand Down Expand Up @@ -417,9 +422,8 @@ private void updatePageContent(Player player, SpawnerData spawner, int newPage,

updateInventoryTitle(player, inventory, spawner, newPage, totalPages);

if (uiClickSound) {
player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1.0f, 1.0f);
}
// Note: Sound is now handled by playButtonSound in the calling method
// This method no longer plays sounds directly
}

private int calculateTotalPages(SpawnerData spawner) {
Expand Down Expand Up @@ -452,7 +456,7 @@ public void onPlayerQuit(PlayerQuitEvent event) {
}

private void openMainMenu(Player player, SpawnerData spawner) {
player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1.0f, 1.0f);
playButtonSound(player, "return");
if (spawner.isInteracted()){
spawnerManager.markSpawnerModified(spawner.getSpawnerId());
spawner.clearInteracted();
Expand Down Expand Up @@ -512,6 +516,7 @@ private void handleDiscardAllItems(Player player, SpawnerData spawner, Inventory
Map<String, String> placeholders = new HashMap<>();
placeholders.put("amount", languageManager.formatNumber(totalItems));
messageService.sendMessage(player, "discard_all_success", placeholders);
playButtonSound(player, "discard_all");
if (!spawner.isInteracted()) {
spawner.markInteracted();
}
Expand Down Expand Up @@ -668,6 +673,27 @@ private void sendTransferMessage(Player player, TransferResult result) {
Map<String, String> placeholders = new HashMap<>();
placeholders.put("amount", String.valueOf(result.totalMoved));
messageService.sendMessage(player, "take_all_items", placeholders);
playButtonSound(player, "take_all");
}
}

/**
* Plays the configured sound for a specific button type
*/
private void playButtonSound(Player player, String buttonType) {
GuiLayout layout = guiLayoutConfig.getCurrentLayout();
if (layout == null) {
return;
}

GuiButton button = layout.getButton(buttonType);
if (button != null && button.hasSound()) {
try {
player.playSound(player.getLocation(), button.getSound(), 1.0f, 1.0f);
} catch (Exception e) {
// Log and continue gracefully if sound playback fails
plugin.getLogger().warning("Failed to play sound for button '" + buttonType + "': " + e.getMessage());
}
}
}

Expand Down
Loading