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
6 changes: 5 additions & 1 deletion src/main/java/fr/antidino/smp/CorePlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import fr.antidino.smp.core.manager.perk.PerkEffectListener;
import fr.antidino.smp.core.manager.perk.PerkManager;
import fr.antidino.smp.core.manager.perk.PerkTasks;
import fr.antidino.smp.core.manager.rarity.RarityManager;
import fr.antidino.smp.librairie.PDCBuilder;
import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
Expand All @@ -34,6 +35,7 @@ public final class CorePlugin extends JavaPlugin {
public CodexMenu codexMenu;
public PerkTasks perkTasks;
public SlotExpander slotExpander;
public RarityManager rarityManager;

private DatabaseManager databaseManager;
public DatabaseProvider databaseProvider;
Expand All @@ -49,6 +51,7 @@ public void onEnable() {
getServer().getPluginManager().registerEvents(new PlayerJoinListener(this), this);
getServer().getPluginManager().registerEvents(new SavingPerkListeners(this), this);

rarityManager = new RarityManager(this);
pdcBuilder = new PDCBuilder(this);

PDCBuilder.init(this);
Expand Down Expand Up @@ -92,6 +95,7 @@ public int fullReload() {
reloadConfig();
configPerkManager.LoadConfigAtStart();
perkManager.reload();
if (rarityManager != null) rarityManager.reload();
if (slotExpander != null) slotExpander.reload();

List<NamespacedKey> keys = perkManager.getPerks().stream().map(AbstractPerk::getKey).toList();
Expand All @@ -110,4 +114,4 @@ public void onDisable() {
databaseManager.close();
}
}
}
}
108 changes: 52 additions & 56 deletions src/main/java/fr/antidino/smp/core/manager/codex/CodexMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import fr.antidino.smp.core.manager.perk.AbstractPerk;
import fr.antidino.smp.librairie.ItemBuilder;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.bukkit.Bukkit;
import org.bukkit.Material;
Expand All @@ -17,16 +16,13 @@

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Menus du /perks codex :
* - LIST : tous les perks actifs du serveur (paginé) + item d'extension de slots
* - LIST : tous les perks actifs du serveur (paginé) + item d'extension de slots
* - DETAIL : craft + description (+ niveaux) d'un perk ou de l'item de slots

* Tous les textes affichés passent par le MessageManager (fichiers de langue).
*/
public class CodexMenu {

Expand All @@ -47,6 +43,8 @@ public class CodexMenu {

public static final String EXPANDER_ID = "__slot_expander__";



public enum Type { LIST, DETAIL }

public static class CodexHolder implements InventoryHolder {
Expand Down Expand Up @@ -82,7 +80,11 @@ public CodexMenu(CorePlugin plugin) {
/** Liste triée de façon stable (même ordre à l'ouverture et au clic). */
public List<AbstractPerk> getSortedPerks() {
List<AbstractPerk> perks = plugin.perkManager.getPerks();
perks.sort(Comparator.comparing(AbstractPerk::getId));
if (plugin.rarityManager != null && plugin.rarityManager.sortCodexByRarity()) {
perks.sort(Comparator.<AbstractPerk>comparingInt(plugin.rarityManager::order).thenComparing(AbstractPerk::getId));
} else {
perks.sort(Comparator.comparing(AbstractPerk::getId));
}
return perks;
}

Expand All @@ -93,12 +95,11 @@ public void openList(Player player, int page) {
int maxPage = Math.max(0, (perks.size() - 1) / PERKS_PER_PAGE);
page = Math.clamp(page, 0, maxPage);

Component title = maxPage > 0
? msg("codex_title_paged", "page", String.valueOf(page + 1), "max", String.valueOf(maxPage + 1))
: msg("codex_title");
String title = "<dark_gray>Codex des perks";
if (maxPage > 0) title += " <gray>(" + (page + 1) + "/" + (maxPage + 1) + ")";

CodexHolder holder = new CodexHolder(Type.LIST, page, null);
Inventory inv = Bukkit.createInventory(holder, 54, title);
Inventory inv = Bukkit.createInventory(holder, 54, mm(title));
holder.setInventory(inv);

int start = page * PERKS_PER_PAGE;
Expand All @@ -108,10 +109,10 @@ public void openList(Player player, int page) {

ItemStack filler = filler();
for (int s = 45; s < 54; s++) inv.setItem(s, filler);
if (page > 0) inv.setItem(PREV_SLOT, button(Material.ARROW, msg("codex_prev_page")));
if (page < maxPage) inv.setItem(NEXT_SLOT, button(Material.ARROW, msg("codex_next_page")));
if (page > 0) inv.setItem(PREV_SLOT, button(Material.ARROW, "<yellow>← Page précédente"));
if (page < maxPage) inv.setItem(NEXT_SLOT, button(Material.ARROW, "<yellow>Page suivante →"));
if (plugin.slotExpander != null) inv.setItem(EXPANDER_SLOT, expanderListItem());
inv.setItem(CLOSE_SLOT, button(Material.BARRIER, msg("codex_close")));
inv.setItem(CLOSE_SLOT, button(Material.BARRIER, "<red>Fermer"));

player.openInventory(inv);
}
Expand All @@ -122,14 +123,16 @@ private ItemStack listItem(AbstractPerk perk) {
if (meta == null) return item;

List<Component> lore = new ArrayList<>();
Component rarityLine = rarityLine(perk);
if (rarityLine != null) lore.add(rarityLine);
lore.add(Component.empty());
lore.addAll(descriptionLines(perk.getDescription()));
if (perk.getMaxLevel() > 1) {
lore.add(Component.empty());
lore.add(msg("codex_max_level", "level", AbstractPerk.roman(perk.getMaxLevel())));
lore.add(mm("<gray>Niveau max : <white>" + AbstractPerk.roman(perk.getMaxLevel())));
}
lore.add(Component.empty());
lore.add(msg("codex_click_craft"));
lore.add(mm("<yellow>▶ Clic pour voir le craft"));
meta.lore(lore);
item.setItemMeta(meta);
return item;
Expand All @@ -144,7 +147,7 @@ private ItemStack expanderListItem() {
lore.add(Component.empty());
lore.addAll(descriptionLines(plugin.slotExpander.getDescription()));
lore.add(Component.empty());
lore.add(msg("codex_click_craft"));
lore.add(mm("<yellow>▶ Clic pour voir le craft"));
meta.lore(lore);
item.setItemMeta(meta);
return item;
Expand All @@ -153,27 +156,34 @@ private ItemStack expanderListItem() {
// ----------------------------------------------------------------- DETAIL

public void openDetail(Player player, AbstractPerk perk, int fromPage) {
List<Component> description = new ArrayList<>(descriptionLines(perk.getDescription()));
List<Component> description = new ArrayList<>();
Component rarityLine = rarityLine(perk);
if (rarityLine != null) {
description.add(rarityLine);
description.add(Component.empty());
}
description.addAll(descriptionLines(perk.getDescription()));
if (perk.getMaxLevel() > 1) {
description.add(Component.empty());
description.add(msg("codex_levels", "max", AbstractPerk.roman(perk.getMaxLevel())));
description.add(msg("codex_upgrade_cost", "cost", String.valueOf(perk.getUpgradeCost())));
description.add(msg("codex_upgrade_hint"));
description.add(mm("<gray>Niveaux : <white>I <gray>→ <white>" + AbstractPerk.roman(perk.getMaxLevel())));
description.add(mm("<gray>Amélioration : <white>" + perk.getUpgradeCost() + " perks <gray>de même niveau"));
description.add(mm("<gray>en table de craft = niveau suivant"));
}
openRecipeView(player, perk.getId(), fromPage,
msg("codex_craft_title").append(mm(perk.getDisplayName())),
mm("<dark_gray>Craft : ").append(plugin.rarityManager != null
? plugin.rarityManager.styledName(perk) : mm(perk.getDisplayName())),
perk.getItem().clone(), perk.getCraftShape(), perk.getCraftIngredients(), description);
}

public void openExpanderDetail(Player player, int fromPage) {
if (plugin.slotExpander == null) return;
List<Component> description = new ArrayList<>(descriptionLines(plugin.slotExpander.getDescription()));
description.add(Component.empty());
description.add(msg("codex_expander_usage"));
description.add(msg("codex_expander_added", "added", String.valueOf(plugin.slotExpander.getAdded())));
description.add(msg("codex_expander_max", "max", String.valueOf(plugin.slotExpander.getMax())));
description.add(mm("<gray>Utilisation : <white>table de forge"));
description.add(mm("<gray>Ajoute <white>+" + plugin.slotExpander.getAdded() + " <gray>emplacement(s)"));
description.add(mm("<gray>Maximum : <white>" + plugin.slotExpander.getMax() + " <gray>par équipement"));
openRecipeView(player, EXPANDER_ID, fromPage,
msg("codex_craft_title").append(mm(plugin.slotExpander.getDisplayName())),
mm("<dark_gray>Craft : ").append(mm(plugin.slotExpander.getDisplayName())),
plugin.slotExpander.getItem(), plugin.slotExpander.getCraftShape(),
plugin.slotExpander.getCraftIngredients(), description);
}
Expand Down Expand Up @@ -201,42 +211,44 @@ private void openRecipeView(Player player, String id, int fromPage, Component ti
}
}

inv.setItem(ARROW_SLOT, button(Material.ARROW, mm("<gray>→")));
inv.setItem(ARROW_SLOT, button(Material.ARROW, "<gray>→"));
inv.setItem(RESULT_SLOT, result);

if (player.hasPermission("smp.perks.codex.give")) {
ItemStack give_button = new ItemBuilder(Material.BARRIER, plugin)
.setName(msg("codex_give_button"))
.build();
if (player.hasPermission("smp.perks.codex.give")){
ItemStack give_button = new ItemBuilder(Material.BARRIER,plugin).setName(mm("<red>GIVE ITEM")).build();
inv.setItem(GIVE_SLOT, give_button);
}
ItemStack book = new ItemBuilder(Material.BOOK, plugin)
.setLore(description)
.setName(msg("codex_description_title"))
.build();
ItemStack book =
new ItemBuilder(Material.BOOK,plugin)
.setLore(description)
.setName(mm("<gold>Description"))
.build();

inv.setItem(DESCRIPTION_SLOT, book);
inv.setItem(BACK_SLOT, button(Material.ARROW, msg("codex_back")));
inv.setItem(BACK_SLOT, button(Material.ARROW, "<yellow>← Retour"));
player.openInventory(inv);
}

// ---------------------------------------------------------------- HELPERS

private Component rarityLine(AbstractPerk perk) {
return plugin.rarityManager == null ? null : plugin.rarityManager.rarityLine(perk);
}

private List<Component> descriptionLines(List<String> lines) {
List<Component> out = new ArrayList<>();
if (lines.isEmpty()) {
out.add(msg("codex_no_description"));
out.add(mm("<dark_gray>Aucune description configurée."));
} else {
// Descriptions définies dans la config des perks (pas dans les fichiers de langue)
for (String line : lines) out.add(mm(line));
}
return out;
}

private ItemStack button(Material material, Component name) {
private ItemStack button(Material material, String name) {
ItemStack item = new ItemStack(material);
ItemMeta meta = item.getItemMeta();
meta.displayName(name);
meta.displayName(mm(name));
item.setItemMeta(meta);
return item;
}
Expand All @@ -249,24 +261,8 @@ private ItemStack filler() {
return item;
}

/**
* Récupère un message traduit, sans italique par défaut.
* Les variables sont passées par paires clé/valeur : msg("key", "count", "5", "max", "10")
*/
private Component msg(String key, String... vars) {
Component component;
if (vars.length == 0) {
component = plugin.messageManager.get(key);
} else {
Map<String, String> map = new HashMap<>();
for (int i = 0; i + 1 < vars.length; i += 2) map.put(vars[i], vars[i + 1]);
component = plugin.messageManager.get(key, map);
}
return component.decorationIfAbsent(TextDecoration.ITALIC, TextDecoration.State.FALSE);
}

/** MiniMessage sans italique par défaut (pour les textes venant de la config des perks). */
private static Component mm(String text) {
return MiniMessage.miniMessage().deserialize("<!italic>" + text);
}
}
}
17 changes: 17 additions & 0 deletions src/main/java/fr/antidino/smp/core/manager/rarity/Rarity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package fr.antidino.smp.core.manager.rarity;

import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;

public record Rarity(String id, String displayName, String color, boolean colorName, int order) {

private static final MiniMessage MM = MiniMessage.miniMessage();

public Component label() {
return MM.deserialize("<!italic>" + color + displayName);
}

public String labelMini() {
return color + displayName;
}
}
Loading
Loading