Skip to content
Closed
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 @@ -59,6 +59,7 @@ public void onCraftingEvent(CraftItemEvent event) {
}
cooldownManager.setCooldown(playerId,0.3);
Bukkit.getScheduler().runTaskAsynchronously(plugin,()->{
plugin.rarityManager.onCraft(player, perk, plugin.pdcBuilder.getPerkLevel(resultType));
plugin.databaseProvider.InsertPerkCraftSQL(id,playerId.toString());
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public void onPrepareSmithing(PrepareSmithingEvent event) {
String perk_id = pdc.get(PDCBuilder.PERK_ID, PersistentDataType.STRING);
AbstractPerk perk = plugin.perkManager.getPerk(perk_id);
if (perk == null) return;
if (!plugin.rarityManager.canApply((org.bukkit.entity.Player) event.getView().getPlayer(), equip, perk)) return;
int level = Math.min(plugin.pdcBuilder.getPerkLevel(mineral), perk.getMaxLevel());
apply_perk(event,equip,perk_id,level);

Expand Down
13 changes: 9 additions & 4 deletions src/main/java/fr/antidino/smp/modules/perk/rarity/Rarity.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,20 @@
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) {
public record Rarity(String id, String displayName, String color, String symbol, boolean colorName,
int maxPerItem, String announce, String sound, int order) {

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

public String labelMini() {
return color + (symbol.isEmpty() ? "" : symbol + " ") + displayName;
}

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

public String labelMini() {
return color + displayName;
public boolean hasLimit() {
return maxPerItem >= 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@
import fr.antidino.smp.modules.perk.AbstractPerk;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;

import java.io.File;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

Expand All @@ -27,8 +33,10 @@ public class RarityManager {
private final Map<String, Rarity> perkRarity = new LinkedHashMap<>();
private Rarity defaultRarity;
private boolean colorPerkName = true;
private boolean symbolInName = false;
private boolean sortCodex = true;
private String rarityLine = "<gray>Rareté : %rarity%";
private String limitMessage = "<red>Cet équipement a déjà %max% perk(s) %rarity%<red> !";

public RarityManager(CorePlugin plugin) {
this.plugin = plugin;
Expand All @@ -45,8 +53,11 @@ public void reload() {
defaultRarity = null;

colorPerkName = config.getBoolean("color_perk_name", true);
symbolInName = config.getBoolean("symbol_in_name", false);
sortCodex = config.getBoolean("sort_codex_by_rarity", true);
rarityLine = config.getString("rarity_line", "<gray>Rareté : %rarity%");
limitMessage = config.getString("limit_message",
"<red>Cet équipement a déjà %max% perk(s) %rarity%<red> !");

ConfigurationSection sec = config.getConfigurationSection("rarities");
if (sec != null) {
Expand All @@ -58,7 +69,11 @@ public void reload() {
id,
r.getString("display_name", id),
r.getString("color", "<white>"),
r.getString("symbol", ""),
r.getBoolean("color_name", colorPerkName),
r.getInt("max_per_item", -1),
r.getString("craft_announce", ""),
r.getString("craft_sound", ""),
order++);
rarities.put(id.toLowerCase(Locale.ROOT), rarity);

Expand All @@ -82,13 +97,36 @@ public void reload() {
plugin.getLogger().warning("[rarity] default_rarity '" + def + "' n'existe pas.");
}
}

// Vérification des ids une fois tous les perks chargés (au prochain tick)
Bukkit.getScheduler().runTask(plugin, this::validate);
}

/** Avertit dans la console si rarity.yml cite un perk qui n'existe pas. */
private void validate() {
if (plugin.perkManager == null) return;
for (String key : perkRarity.keySet()) {
boolean found = plugin.perkManager.getPerks().stream()
.anyMatch(p -> normalize(p.getId()).equals(key));
if (!found) {
plugin.getLogger().warning("[rarity] perk inconnu dans rarity.yml : '" + key
+ "' (voir les ids avec /perk give)");
}
}
}

private static String normalize(String id) {
String s = id == null ? "" : id.trim().toLowerCase(Locale.ROOT);
return s.endsWith("_perk") ? s.substring(0, s.length() - 5) : s;
}

// ------------------------------------------------------------ LECTURE

public Collection<Rarity> getRarities() {
return Collections.unmodifiableCollection(rarities.values());
}

/** Rareté d'une perk (celle par défaut s'il n'est listé nulle part, null si aucune). */
public Rarity getRarity(String perkId) {
Rarity r = perkRarity.get(normalize(perkId));
return r != null ? r : defaultRarity;
Expand All @@ -98,15 +136,18 @@ public Rarity getRarity(AbstractPerk perk) {
return perk == null ? null : getRarity(perk.getId());
}

/** Nom du perk (sans italique), coloré selon sa rareté si activé dans rarity.yml. */
public Component styledName(AbstractPerk perk) {
Rarity rarity = getRarity(perk);
if (rarity == null || !rarity.colorName()) {
return MM.deserialize("<!italic>" + perk.getDisplayName());
}
String symbol = symbolInName && !rarity.symbol().isEmpty() ? rarity.symbol() + " " : "";
String plain = MM.stripTags(perk.getDisplayName());
return MM.deserialize("<!italic>" + rarity.color() + plain);
return MM.deserialize("<!italic>" + rarity.color() + symbol + plain);
}

/** Ligne "Rareté : X" pour le codex, ou null si le perk n'a pas de rareté. */
public Component rarityLine(AbstractPerk perk) {
Rarity rarity = getRarity(perk);
if (rarity == null) return null;
Expand All @@ -117,8 +158,56 @@ public boolean sortCodexByRarity() {
return sortCodex;
}

/** Ordre de tri : plus la rareté est haute, plus le nombre est grand (sans rareté = -1). */
public int order(AbstractPerk perk) {
Rarity r = getRarity(perk);
return r == null ? -1 : r.order();
}

// ------------------------------------------------------------ LIMITES

/**
* Vérifie la limite "max_per_item" de la rareté du perk sur cet équipement.
* Envoie le message "limit_message" au joueur (si non null) quand c'est refusé.
*/
public boolean canApply(Player viewer, ItemStack equipment, AbstractPerk perk) {
Rarity rarity = getRarity(perk);
if (rarity == null || !rarity.hasLimit()) return true;

int count = 0;
List<String> applied = plugin.pdcBuilder.getAppliedPerks(equipment);
for (String raw : applied) {
AbstractPerk other = plugin.perkManager.getPerk(PerkEntry.parse(raw).id());
if (other != null && getRarity(other) == rarity) count++;
}
if (count < rarity.maxPerItem()) return true;

if (viewer != null) {
viewer.sendMessage(MM.deserialize(limitMessage
.replace("%max%", String.valueOf(rarity.maxPerItem()))
.replace("%rarity%", rarity.labelMini())));
}
return false;
}

// ------------------------------------------------------------ CRAFT

/** Annonce + son quand un joueur craft un perk dont la rareté en définit un. */
public void onCraft(Player player, AbstractPerk perk, int level) {
Rarity rarity = getRarity(perk);
if (rarity == null) return;

if (!rarity.announce().isBlank()) {
String plain = MM.stripTags(perk.getDisplayName());
String text = rarity.announce()
.replace("%player%", player.getName())
.replace("%perk%", rarity.color() + plain)
.replace("%level%", AbstractPerk.roman(Math.max(1, level)))
.replace("%rarity%", rarity.labelMini());
Bukkit.broadcast(MM.deserialize(text));
}
if (!rarity.sound().isBlank()) {
player.playSound(player.getLocation(), rarity.sound(), 1.0f, 1.0f);
}
}
}
52 changes: 50 additions & 2 deletions src/main/resources/rarity.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,63 @@
# ============================================================================
# RARETÉS DES PERKS (plugins/SMPplugin/rarity.yml)
# Tout le texte et toutes les couleurs sont en MiniMessage uniquement.
# Rechargement à chaud : /perk reload
# ============================================================================
#
# Exemples de couleurs valides pour "color" :
# "<gray>" couleur simple
# "<#ff8800>" couleur hexadécimale
# "<gradient:#ff512f:#f09819>" dégradé 2 couleurs
# "<gradient:#00c6ff:#0072ff:#00c6ff>" dégradé multi-couleurs
# ============================================================================

# Rareté donnée aux perks qui ne sont listés dans aucune rareté.
# Mettre "" (vide) pour ne rien afficher pour ces perks.
default_rarity: "common"

# true = le nom du perk prend la couleur / le dégradé de sa rareté
# (dans le lore des équipements et dans le codex)
# false = le nom garde la couleur définie dans son propre fichier
color_perk_name: true

# Ligne affichée dans le codex
# true = le symbole de la rareté est aussi affiché devant le nom du perk
symbol_in_name: false

# Ligne affichée dans le codex (liste + détail). %rarity% = symbole + nom coloré.
rarity_line: "<gray>Rareté : %rarity%"

# true = le codex trie les perks de la plus commune à la plus rare (puis par id)
sort_codex_by_rarity: true

# Message envoyé quand la limite "max_per_item" d'une rareté est atteinte.
# Variables : %max% (limite), %rarity% (nom coloré de la rareté)
limit_message: "<red>Cet équipement a déjà %max% perk(s) %rarity%<red> !"

# Les raretés sont classées dans l'ordre du fichier : la première est la plus commune.
#
# Options d'une rareté :
# display_name nom affiché
# color couleur / dégradé (voir plus haut)
# symbol (optionnel) symbole devant le nom, ex: "✦"
# color_name (optionnel) surcharge "color_perk_name" pour cette rareté
# max_per_item (optionnel) nombre max de perks de cette rareté par équipement, -1 = illimité
# craft_announce (optionnel) message diffusé à tout le serveur quand un perk est crafté
# variables : %player% %perk% %level% %rarity%
# craft_sound (optionnel) son joué au joueur qui craft, ex: "entity.player.levelup"
# perks ids des perks (ceux de /perk give). Le suffixe "_perk" est facultatif.
rarities:
common:
display_name: "Commun"
color: "<gray>"
perks: # ids des perks
symbol: "•"
perks:
- "sprinter_perk"
- "night_vision_perk"

uncommon:
display_name: "Peu commun"
color: "<green>"
symbol: "◆"
perks:
- "health_perk"
- "speed_perk"
Expand All @@ -29,6 +68,7 @@ rarities:
rare:
display_name: "Rare"
color: "<gradient:#00c6ff:#0072ff>"
symbol: "✦"
perks:
- "attack_damage_perk"
- "attack_speed_perk"
Expand All @@ -39,12 +79,20 @@ rarities:
epic:
display_name: "Épique"
color: "<gradient:#c471f5:#fa71cd>"
symbol: "✷"
max_per_item: 2
craft_sound: "entity.player.levelup"
craft_announce: "<dark_gray>[<light_purple>★<dark_gray>] <white>%player% <gray>a créé %perk% <gray>(%rarity%<gray>) !"
perks:
- "lifesteal_perk"
- "glass_cannon_perk"

legendary:
display_name: "Légendaire"
color: "<bold><gradient:#ff512f:#f09819:#ffe259>"
symbol: "✪"
max_per_item: 1
craft_sound: "ui.toast.challenge_complete"
craft_announce: "<dark_gray>[<gold>★<dark_gray>] <white>%player% <gray>vient de créer %perk% <gray>(%rarity%<gray>) !"
perks:
- "warden_perk"
Loading