diff --git a/README.md b/README.md
index 2fc152f..5c47765 100644
--- a/README.md
+++ b/README.md
@@ -19,18 +19,6 @@ Plugin **Paper** pour serveur SMP qui ajoute un système de **perks** : des item
Menu Principal • Interface de Craft
-
-
-
-
-
-
-
-
-
-
-
Affichage du Lore • Description de l'Item
-
## Sommaire
1. [Fonctionnalités](#fonctionnalités)
diff --git a/src/main/java/fr/antidino/smp/CorePlugin.java b/src/main/java/fr/antidino/smp/CorePlugin.java
index 031f3c0..f74469e 100644
--- a/src/main/java/fr/antidino/smp/CorePlugin.java
+++ b/src/main/java/fr/antidino/smp/CorePlugin.java
@@ -1,5 +1,6 @@
package fr.antidino.smp;
+import fr.antidino.smp.core.listeners.*;
import fr.antidino.smp.core.manager.SlotExpander;
import fr.antidino.smp.core.manager.SlotManager;
import fr.antidino.smp.core.manager.codex.CodexListener;
@@ -8,10 +9,6 @@
import fr.antidino.smp.core.commands.PerksCommand;
import fr.antidino.smp.core.manager.database.DatabaseManager;
import fr.antidino.smp.core.manager.database.DatabaseProvider;
-import fr.antidino.smp.core.listeners.CraftingListener;
-import fr.antidino.smp.core.listeners.ItemBreakListener;
-import fr.antidino.smp.core.listeners.PlayerJoinListener;
-import fr.antidino.smp.core.listeners.SmithingListener;
import fr.antidino.smp.core.SmithingRegisterAllItem;
import fr.antidino.smp.core.manager.perk.config.ConfigPerkManager;
import fr.antidino.smp.core.manager.perk.AbstractPerk;
@@ -50,6 +47,7 @@ public void onEnable() {
getServer().getPluginManager().registerEvents(new SmithingListener(this), this);
getServer().getPluginManager().registerEvents(new ItemBreakListener(this), this);
getServer().getPluginManager().registerEvents(new PlayerJoinListener(this), this);
+ getServer().getPluginManager().registerEvents(new SavingPerkListeners(this), this);
pdcBuilder = new PDCBuilder(this);
diff --git a/src/main/java/fr/antidino/smp/core/SmithingRegisterAllItem.java b/src/main/java/fr/antidino/smp/core/SmithingRegisterAllItem.java
index 10c7e04..dc59c89 100644
--- a/src/main/java/fr/antidino/smp/core/SmithingRegisterAllItem.java
+++ b/src/main/java/fr/antidino/smp/core/SmithingRegisterAllItem.java
@@ -42,14 +42,14 @@ public static Map> getCategorizedMaterials() {
String name = mat.name();
- // Catégorie Armures
+
if (name.endsWith("_HELMET") ||
name.endsWith("_CHESTPLATE") ||
name.endsWith("_LEGGINGS") ||
name.endsWith("_BOOTS")) {
armors.add(mat);
}
- // Catégorie Outils & Armes
+
else if (name.endsWith("_SWORD") ||
name.endsWith("_AXE") ||
name.endsWith("_PICKAXE") ||
@@ -59,14 +59,14 @@ else if (name.endsWith("_SWORD") ||
}
}
- // Remplissage de la Map des catégories
+
categories.put("Armures", armors);
categories.put("Outils & Armes", toolsAndWeapons);
return categories;
}
- // Si tu as toujours besoin d'une liste plate globale (pour tes anciens checks par exemple)
+
public static List getAllMaterials() {
List allItems = new ArrayList<>();
getCategorizedMaterials().values().forEach(allItems::addAll);
diff --git a/src/main/java/fr/antidino/smp/core/listeners/CraftingListener.java b/src/main/java/fr/antidino/smp/core/listeners/CraftingListener.java
index 0b2a622..ef765d0 100644
--- a/src/main/java/fr/antidino/smp/core/listeners/CraftingListener.java
+++ b/src/main/java/fr/antidino/smp/core/listeners/CraftingListener.java
@@ -1,27 +1,33 @@
package fr.antidino.smp.core.listeners;
import fr.antidino.smp.CorePlugin;
+
import fr.antidino.smp.core.SmithingRegisterAllItem;
import fr.antidino.smp.core.manager.CooldownManager;
import fr.antidino.smp.core.manager.SlotManager;
+import fr.antidino.smp.core.manager.perk.AbstractPerk;
import net.kyori.adventure.text.minimessage.MiniMessage;
+import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.CraftItemEvent;
import org.bukkit.inventory.ItemStack;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.util.UUID;
public class CraftingListener implements Listener {
- private final CorePlugin corePlugin;
+ private static final Logger log = LoggerFactory.getLogger(CraftingListener.class);
+ private final CorePlugin plugin;
private final SlotManager slotManager;
private final CooldownManager cooldownManager;
private final MiniMessage mm = MiniMessage.miniMessage();
public CraftingListener(CorePlugin plugin) {
- this.corePlugin = plugin;
+ this.plugin = plugin;
this.slotManager = new SlotManager(plugin);
this.cooldownManager = new CooldownManager();
}
@@ -35,18 +41,26 @@ public void onCraftingEvent(CraftItemEvent event) {
if (resultType == null || !resultType.hasItemMeta()) return;
- String id = corePlugin.perkManager.getPerkId(resultType);
- if (id != null && !event.isCancelled()) {
-
- UUID playerId = player.getUniqueId();
-
+ String id = plugin.perkManager.getPerkId(resultType);
+ UUID playerId = player.getUniqueId();
+ if (id == null) return;
+ int number_of_perk = plugin.databaseProvider.NumberOfPerkCrafted(id);
+ AbstractPerk perk = plugin.perkManager.getPerk(id);
+ if (perk.getMaxPossibleCraft() <= number_of_perk && perk.getMaxPossibleCraft() != -1) {
+ event.setCancelled(true);
+ player.sendMessage(mm.deserialize(" You can't craft this item!"));
+ }
+
+ if (!event.isCancelled()) {
if (cooldownManager.hasCooldown(playerId)) {
event.setCancelled(true);
player.sendMessage(mm.deserialize("Please wait before crafting this item again!"));
return;
}
cooldownManager.setCooldown(playerId,0.3);
- corePlugin.databaseProvider.InsertPerkCraftSQL(id, playerId.toString());
+ Bukkit.getScheduler().runTaskAsynchronously(plugin,()->{
+ plugin.databaseProvider.InsertPerkCraftSQL(id,playerId.toString());
+ });
}
diff --git a/src/main/java/fr/antidino/smp/core/listeners/SavingPerkListeners.java b/src/main/java/fr/antidino/smp/core/listeners/SavingPerkListeners.java
new file mode 100644
index 0000000..4e7e1f0
--- /dev/null
+++ b/src/main/java/fr/antidino/smp/core/listeners/SavingPerkListeners.java
@@ -0,0 +1,75 @@
+package fr.antidino.smp.core.listeners;
+
+import com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent;
+import fr.antidino.smp.CorePlugin;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.World;
+import org.bukkit.block.Block;
+import org.bukkit.block.Chest;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.Item;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.entity.EntityDamageEvent;
+import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
+import org.bukkit.event.entity.ItemDespawnEvent;
+import org.bukkit.inventory.ItemStack;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SavingPerkListeners implements Listener {
+ private static final Logger log = LoggerFactory.getLogger(SavingPerkListeners.class);
+ CorePlugin plugin;
+ private static final double SAFE_Y = 64.0;
+
+ public SavingPerkListeners(CorePlugin plugin) {
+ this.plugin = plugin;
+
+
+ }
+
+ @EventHandler
+ public void onEntityDamage(EntityDamageEvent event) {
+ if (!(event.getEntity() instanceof Item item))return;
+ if (isAPerkItem(item.getItemStack())){
+ event.setCancelled(true);
+ item.setFireTicks(0);
+ }
+
+ }
+ @EventHandler
+ public void onEntityRemove(EntityRemoveFromWorldEvent event) {
+ if (!(event.getEntity() instanceof Item item)) return;
+ if (!isAPerkItem(item.getItemStack()))return;
+ Location loc = item.getLocation();
+ World world = loc.getWorld();
+ Location chestLoc = new Location(world, loc.getBlockX(), SAFE_Y, loc.getBlockZ());
+ Bukkit.getScheduler().runTask(plugin, () -> placeChestWithItem(chestLoc, item.getItemStack()));
+ }
+ @EventHandler
+ public void onItemDespawn(ItemDespawnEvent event) {
+ Item victim = event.getEntity();
+ World world = victim.getWorld();
+ ItemStack itemStack = victim.getItemStack();
+ if (victim.getLocation().getY() < world.getMinHeight()) {
+ event.setCancelled(true);
+ }
+ event.setCancelled(isAPerkItem(itemStack));
+ }
+
+ private boolean isAPerkItem(ItemStack itemStack) {
+ String perk_id = plugin.perkManager.getPerkId(itemStack);
+ return perk_id != null;
+ }
+ private static void placeChestWithItem(Location location, ItemStack itemStack) {
+ Block block = location.getBlock();
+ block.setType(Material.CHEST);
+
+ if (block.getState() instanceof Chest chest) {
+ chest.getInventory().addItem(itemStack);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/fr/antidino/smp/core/listeners/SmithingListener.java b/src/main/java/fr/antidino/smp/core/listeners/SmithingListener.java
index 68826fe..6e64648 100644
--- a/src/main/java/fr/antidino/smp/core/listeners/SmithingListener.java
+++ b/src/main/java/fr/antidino/smp/core/listeners/SmithingListener.java
@@ -28,7 +28,7 @@ public void onPrepareSmithing(PrepareSmithingEvent event) {
if (mineralMeta == null) return;
PersistentDataContainer pdc = mineralMeta.getPersistentDataContainer();
- // Item d'extension de slots : équipement + item en forge => +1 emplacement
+
if (pdc.has(PDCBuilder.SLOT_EXPANDER, PersistentDataType.STRING)) {
applyExpander(event, equip);
return;
@@ -40,6 +40,7 @@ public void onPrepareSmithing(PrepareSmithingEvent event) {
if (perk == null) return;
int level = Math.min(plugin.pdcBuilder.getPerkLevel(mineral), perk.getMaxLevel());
apply_perk(event,equip,perk_id,level);
+
}
private void apply_perk(PrepareSmithingEvent event,ItemStack equip ,String perk_id,int level){
ItemStack resultItem = equip.clone();
diff --git a/src/main/java/fr/antidino/smp/core/listeners/VoidItemSaver.java b/src/main/java/fr/antidino/smp/core/listeners/VoidItemSaver.java
new file mode 100644
index 0000000..b354d03
--- /dev/null
+++ b/src/main/java/fr/antidino/smp/core/listeners/VoidItemSaver.java
@@ -0,0 +1,53 @@
+package fr.antidino.smp.core.listeners;
+
+import fr.antidino.smp.CorePlugin;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.World;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.Item;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.scheduler.BukkitRunnable;
+
+public class VoidItemSaver extends BukkitRunnable {
+
+ private final CorePlugin plugin;
+ private static final double SAFE_Y = 64.0; // Y de téléportation
+
+ public VoidItemSaver(CorePlugin plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public void run() {
+ for (World world : Bukkit.getWorlds()) {
+ int minY = world.getMinHeight(); // -64 pour les mondes 1.18+
+
+ for (Entity entity : world.getEntities()) {
+ if (entity.getType() != EntityType.ITEM) continue;
+
+ Item item = (Item) entity;
+ if (!isAPerkItem(item.getItemStack())) return;
+ if (item.getLocation().getY() < minY + 5) {
+
+ Location safeLoc = item.getLocation().clone();
+ safeLoc.setY(SAFE_Y);
+ item.teleport(safeLoc);
+
+
+ // item.remove();
+ }
+ }
+ }
+ }
+
+ public void start() {
+ // Toutes les 10 ticks (0.5 seconde)
+ this.runTaskTimer(plugin, 0L, 10L);
+ }
+ private boolean isAPerkItem(ItemStack itemStack) {
+ String perk_id = plugin.perkManager.getPerkId(itemStack);
+ return perk_id != null;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/fr/antidino/smp/core/manager/database/DatabaseProvider.java b/src/main/java/fr/antidino/smp/core/manager/database/DatabaseProvider.java
index 48438bf..659e30a 100644
--- a/src/main/java/fr/antidino/smp/core/manager/database/DatabaseProvider.java
+++ b/src/main/java/fr/antidino/smp/core/manager/database/DatabaseProvider.java
@@ -22,6 +22,10 @@ INSERT OR IGNORE INTO smp_players (uuid, username) VALUES (?, ?)
private static final String INSERT_PERK_CRAFT_SQL = """
INSERT INTO smp_player_perks (uuid, perk_id, created_at) VALUES (?, ?, ?);
""";
+
+ private static String GET_PERK_CRAFT_SQL = """
+ SELECT * FROM smp_player_perks WHERE perk_id=?
+ """;
public DatabaseProvider(CorePlugin plugin) {
this.plugin = plugin;
}
@@ -47,7 +51,6 @@ public void insertPlayerSQL(Player player) {
log.info(" Error as {}", String.valueOf(e));
}
}
-
public void InsertPerkCraftSQL(String perk_id,String uuid){
try (Connection conn = plugin.getConnexion();
PreparedStatement ps = conn.prepareStatement(INSERT_PERK_CRAFT_SQL)) {
@@ -59,4 +62,20 @@ public void InsertPerkCraftSQL(String perk_id,String uuid){
log.info(" Error as {}", String.valueOf(e));
}
}
+
+ public int NumberOfPerkCrafted(String perk_id){
+ try (Connection connection = plugin.getConnexion()){
+ PreparedStatement ps = connection.prepareStatement(GET_PERK_CRAFT_SQL);
+ ps.setString(1, perk_id);
+ ResultSet rs = ps.executeQuery();
+ int count = 0;
+ while (rs.next()) {
+ count++;
+ }
+ return count;
+ }catch (SQLException e){
+ log.info(" Error as {}", String.valueOf(e));
+ }
+ return 3;
+ };
}
diff --git a/src/main/java/fr/antidino/smp/core/manager/perk/AbstractPerk.java b/src/main/java/fr/antidino/smp/core/manager/perk/AbstractPerk.java
index d6a9b87..8697d4d 100644
--- a/src/main/java/fr/antidino/smp/core/manager/perk/AbstractPerk.java
+++ b/src/main/java/fr/antidino/smp/core/manager/perk/AbstractPerk.java
@@ -115,7 +115,13 @@ public double getMultiplier(int level) {
double bonus = config.getDouble("level.bonus_per_level", 0.5);
return 1.0 + bonus * (Math.max(1, level) - 1);
}
+ /*
+ Get Number of craft in world
+ */
+ public int getMaxPossibleCraft() {
+ return config.getInt("craft.number");
+ }
/**
* Valeur configurable par niveau dans la section "values" du yml.
* Liste : [niv1, niv2, niv3] (le dernier est réutilisé au-delà). Nombre seul : même valeur partout.
diff --git a/src/main/resources/perks/armor.yml b/src/main/resources/perks/armor.yml
index 6c9146d..a2d85bf 100644
--- a/src/main/resources/perks/armor.yml
+++ b/src/main/resources/perks/armor.yml
@@ -3,6 +3,7 @@ item:
material : GOLD_INGOT
display_name : "Armor Boost"
craft :
+ number : -1
shape :
- "XXX"
- "XCC"
diff --git a/src/main/resources/perks/attack_damage.yml b/src/main/resources/perks/attack_damage.yml
index 2b825ec..5721d6b 100644
--- a/src/main/resources/perks/attack_damage.yml
+++ b/src/main/resources/perks/attack_damage.yml
@@ -3,6 +3,7 @@ item:
material : "AMETHYST_SHARD"
display_name : "Damage Boost"
craft :
+ number : -1
shape :
- "XCX"
- "CBC"
diff --git a/src/main/resources/perks/attack_speed.yml b/src/main/resources/perks/attack_speed.yml
index 355825f..dea466f 100644
--- a/src/main/resources/perks/attack_speed.yml
+++ b/src/main/resources/perks/attack_speed.yml
@@ -3,6 +3,7 @@ item:
material : "AMETHYST_SHARD"
display_name : "Attack Speed Boost"
craft :
+ number : -1
shape :
- "XCX"
- "CBC"
diff --git a/src/main/resources/perks/double_jump.yml b/src/main/resources/perks/double_jump.yml
index 86b2dfa..ecec937 100644
--- a/src/main/resources/perks/double_jump.yml
+++ b/src/main/resources/perks/double_jump.yml
@@ -3,6 +3,7 @@ item:
material : "FEATHER"
display_name : "Double Jump"
craft :
+ number : 30
shape :
- "XPX"
- "DED"
diff --git a/src/main/resources/perks/glass_cannon.yml b/src/main/resources/perks/glass_cannon.yml
index 1d8e688..ac20d51 100644
--- a/src/main/resources/perks/glass_cannon.yml
+++ b/src/main/resources/perks/glass_cannon.yml
@@ -3,6 +3,7 @@ item:
material : "FIRE_CHARGE"
display_name : "Glass Cannon"
craft :
+ number : -1
shape :
- "BGB"
- "DTD"
diff --git a/src/main/resources/perks/health.yml b/src/main/resources/perks/health.yml
index 7a9a70b..1f26139 100644
--- a/src/main/resources/perks/health.yml
+++ b/src/main/resources/perks/health.yml
@@ -3,6 +3,7 @@ item:
material : "SUGAR"
display_name : "Sprinter"
craft :
+ number : -1
shape :
- "XXX"
- "CCC"
diff --git a/src/main/resources/perks/lifesteal.yml b/src/main/resources/perks/lifesteal.yml
index 603ffab..6de0134 100644
--- a/src/main/resources/perks/lifesteal.yml
+++ b/src/main/resources/perks/lifesteal.yml
@@ -3,6 +3,7 @@ item:
material : REDSTONE
display_name : "LifeSteal Boost"
craft :
+ number : -1
shape :
- "XCX"
- "CCC"
@@ -12,4 +13,4 @@ craft :
C : APPLE
values :
- heal_percent : [3, 6, 10]
\ No newline at end of file
+ heal_percent : [10, 26, 40]
\ No newline at end of file
diff --git a/src/main/resources/perks/magnet.yml b/src/main/resources/perks/magnet.yml
index 468653a..0e4cf81 100644
--- a/src/main/resources/perks/magnet.yml
+++ b/src/main/resources/perks/magnet.yml
@@ -3,6 +3,7 @@ item:
material : "COMPASS"
display_name : "Magnet"
craft :
+ number : -1
shape :
- "IEI"
- "DCD"
diff --git a/src/main/resources/perks/miner.yml b/src/main/resources/perks/miner.yml
index cdb8a63..522da2a 100644
--- a/src/main/resources/perks/miner.yml
+++ b/src/main/resources/perks/miner.yml
@@ -3,6 +3,7 @@ item:
material : "FLINT"
display_name : "Miner"
craft :
+ number : -1
shape :
- "GDG"
- "DPD"
diff --git a/src/main/resources/perks/night_vision.yml b/src/main/resources/perks/night_vision.yml
index 2128357..f5efd93 100644
--- a/src/main/resources/perks/night_vision.yml
+++ b/src/main/resources/perks/night_vision.yml
@@ -3,6 +3,7 @@ item:
material : "SPIDER_EYE"
display_name : "Night Vision"
craft :
+ number : -1
shape :
- "XDX"
- "DED"
diff --git a/src/main/resources/perks/nofall.yml b/src/main/resources/perks/nofall.yml
index 8509a7c..0b79f08 100644
--- a/src/main/resources/perks/nofall.yml
+++ b/src/main/resources/perks/nofall.yml
@@ -3,6 +3,7 @@ item:
material : REDSTONE
display_name : "NoFall Perk"
craft :
+ number : -1
shape :
- "XXX"
- "BCB"
diff --git a/src/main/resources/perks/smelter.yml b/src/main/resources/perks/smelter.yml
index 695aec7..78e09e0 100644
--- a/src/main/resources/perks/smelter.yml
+++ b/src/main/resources/perks/smelter.yml
@@ -3,6 +3,7 @@ item:
material : "BLAZE_POWDER"
display_name : "Smelter"
craft :
+ number : -1
shape :
- "RMR"
- "DFD"
diff --git a/src/main/resources/perks/speed.yml b/src/main/resources/perks/speed.yml
index 2fc0a20..b5278bd 100644
--- a/src/main/resources/perks/speed.yml
+++ b/src/main/resources/perks/speed.yml
@@ -3,6 +3,7 @@ item:
material : "LAPIS_LAZULI"
display_name : "Speed Boost"
craft :
+ number : -1
shape :
- "XCX"
- "CBC"
diff --git a/src/main/resources/perks/sprinter.yml b/src/main/resources/perks/sprinter.yml
index 11ac0be..46a30bd 100644
--- a/src/main/resources/perks/sprinter.yml
+++ b/src/main/resources/perks/sprinter.yml
@@ -3,6 +3,7 @@ item:
material : "SUGAR"
display_name : "Sprinter"
craft :
+ number : -1
shape :
- "SDS"
- "DRD"
diff --git a/src/main/resources/perks/warden.yml b/src/main/resources/perks/warden.yml
index 8940021..4c95d35 100644
--- a/src/main/resources/perks/warden.yml
+++ b/src/main/resources/perks/warden.yml
@@ -3,6 +3,7 @@ item:
material : "ECHO_SHARD"
display_name : "Warden Boost"
craft :
+ number : 1
shape :
- "XSX"
- "DED"