new file: src/main/java/com/simolzimol/levelcraft/item/ItemEffects.java
modified: src/main/java/com/simolzimol/levelcraft/item/ItemUtil.java new file: src/main/java/com/simolzimol/levelcraft/item/StatTier.java modified: src/main/java/com/simolzimol/levelcraft/listener/CraftListener.java modified: src/main/java/com/simolzimol/levelcraft/listener/LootListener.java modified: src/main/java/com/simolzimol/levelcraft/listener/MobDropListener.java modified: src/main/java/com/simolzimol/levelcraft/listener/VillagerTradeListener.java
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
package com.simolzimol.levelcraft.item;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ItemEffects {
|
||||
public static final List<String> EFFECTS = List.of(
|
||||
"§bEffekt: Feuerresistenz",
|
||||
"§bEffekt: Schnelligkeit",
|
||||
"§bEffekt: Regeneration",
|
||||
"§bEffekt: Unsichtbarkeit",
|
||||
"§bEffekt: Stärke"
|
||||
);
|
||||
|
||||
public static final List<String> SKILLS = List.of(
|
||||
"§dSkill: Doppelschlag",
|
||||
"§dSkill: Lebensraub",
|
||||
"§dSkill: Flächenschaden",
|
||||
"§dSkill: Rückstoß",
|
||||
"§dSkill: Kritischer Treffer"
|
||||
);
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
package com.simolzimol.levelcraft.item;
|
||||
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.attribute.AttributeModifier;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
@@ -54,4 +57,208 @@ public class ItemUtil {
|
||||
public static NamespacedKey getRarityKey() {
|
||||
return rarityKey;
|
||||
}
|
||||
|
||||
public static void addRandomBonuses(ItemStack item, Rarity rarity, java.util.Random random) {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
java.util.List<String> lore = meta.hasLore() ? meta.getLore() : new java.util.ArrayList<>();
|
||||
|
||||
int stats = switch (rarity) {
|
||||
case COMMON -> 1;
|
||||
case UNCOMMON, RARE, EPIC -> 2;
|
||||
case LEGENDARY, MYTHIC -> 3;
|
||||
case ANCIENT -> 4;
|
||||
case DIVINE -> 5;
|
||||
default -> 0;
|
||||
};
|
||||
|
||||
// Stat-Typen, die für dieses Item zulässig sind
|
||||
java.util.List<String> possibleStats = new java.util.ArrayList<>();
|
||||
if (item.getType().getMaxDurability() > 0) possibleStats.add("DURABILITY");
|
||||
if (isWeapon(item)) possibleStats.add("DAMAGE");
|
||||
if (isArmor(item) || item.getType().name().equals("SHIELD")) possibleStats.add("ARMOR");
|
||||
if (isTool(item)) possibleStats.add("MINING_SPEED");
|
||||
possibleStats.add("LUCK"); // Luck kann auf alles
|
||||
|
||||
java.util.Collections.shuffle(possibleStats, random);
|
||||
|
||||
java.util.Set<String> usedStats = new java.util.HashSet<>();
|
||||
for (int i = 0; i < stats && i < possibleStats.size(); i++) {
|
||||
StatTier tier = StatTier.values()[Math.min(i, StatTier.values().length-1)];
|
||||
String stat = possibleStats.get(i);
|
||||
usedStats.add(stat);
|
||||
|
||||
switch (stat) {
|
||||
case "DURABILITY" -> {
|
||||
double percent = tier.getMinDurability() + (tier.getMaxDurability() - tier.getMinDurability()) * random.nextDouble();
|
||||
int bonus = (int) Math.round(item.getType().getMaxDurability() * percent);
|
||||
lore.add(tier.getDisplay() + ": +" + (int)(percent*100) + "% Haltbarkeit (" + bonus + " Punkte)");
|
||||
item.setDurability((short) 0); // Item ist voll repariert
|
||||
}
|
||||
case "DAMAGE" -> {
|
||||
double percent = tier.getMinDamage() + (tier.getMaxDamage() - tier.getMinDamage()) * random.nextDouble();
|
||||
double base = getBaseDamage(item);
|
||||
double bonus = base * percent * 10; // Bonus x10
|
||||
double newDamage = base + bonus;
|
||||
meta.addAttributeModifier(
|
||||
org.bukkit.attribute.Attribute.GENERIC_ATTACK_DAMAGE,
|
||||
new AttributeModifier(UUID.nameUUIDFromBytes("levelcraft_base_damage".getBytes()), "levelcraft_base_damage", base, AttributeModifier.Operation.ADD_NUMBER));
|
||||
meta.addAttributeModifier(
|
||||
org.bukkit.attribute.Attribute.GENERIC_ATTACK_DAMAGE,
|
||||
new AttributeModifier(UUID.randomUUID(), "levelcraft_bonus_damage", bonus, AttributeModifier.Operation.ADD_NUMBER));
|
||||
lore.add(tier.getDisplay() + ": +" + String.format("%.2f", bonus) + " Angriffsschaden (gesamt: " + String.format("%.2f", newDamage) + ")");
|
||||
}
|
||||
case "ARMOR" -> {
|
||||
double percent = tier.getMinArmor() + (tier.getMaxArmor() - tier.getMinArmor()) * random.nextDouble();
|
||||
double base = getBaseArmor(item);
|
||||
double bonus = base * percent * 10; // Bonus x10
|
||||
double newArmor = base + bonus;
|
||||
// Erst Basiswert als Modifier setzen
|
||||
meta.addAttributeModifier(
|
||||
org.bukkit.attribute.Attribute.GENERIC_ARMOR,
|
||||
new AttributeModifier(UUID.nameUUIDFromBytes("levelcraft_base_armor".getBytes()), "levelcraft_base_armor", base, AttributeModifier.Operation.ADD_NUMBER));
|
||||
// Dann Bonus als Modifier setzen
|
||||
meta.addAttributeModifier(
|
||||
org.bukkit.attribute.Attribute.GENERIC_ARMOR,
|
||||
new AttributeModifier(UUID.randomUUID(), "levelcraft_bonus_armor", bonus, AttributeModifier.Operation.ADD_NUMBER));
|
||||
lore.add(tier.getDisplay() + ": +" + String.format("%.2f", bonus) + " Rüstung (gesamt: " + String.format("%.2f", newArmor) + ")");
|
||||
}
|
||||
case "MINING_SPEED" -> {
|
||||
double percent = tier.getMinAttackSpeed() + (tier.getMaxAttackSpeed() - tier.getMinAttackSpeed()) * random.nextDouble();
|
||||
double bonus = 4.0 * percent * 10; // Bonus x10
|
||||
meta.addAttributeModifier(
|
||||
org.bukkit.attribute.Attribute.GENERIC_ATTACK_SPEED,
|
||||
new AttributeModifier(UUID.randomUUID(), "levelcraft_bonus_mining_speed", bonus, AttributeModifier.Operation.ADD_NUMBER));
|
||||
lore.add(tier.getDisplay() + ": +" + String.format("%.2f", bonus) + " Abbausgeschwindigkeit");
|
||||
}
|
||||
case "LUCK" -> {
|
||||
double percent = tier.getMinLuck() + (tier.getMaxLuck() - tier.getMinLuck()) * random.nextDouble();
|
||||
double bonus = 1.0 * percent * 10; // Bonus x10
|
||||
meta.addAttributeModifier(
|
||||
org.bukkit.attribute.Attribute.GENERIC_LUCK,
|
||||
new AttributeModifier(UUID.randomUUID(), "levelcraft_bonus_luck", bonus, AttributeModifier.Operation.ADD_NUMBER));
|
||||
lore.add(tier.getDisplay() + ": +" + String.format("%.2f", bonus) + " Glück");
|
||||
}
|
||||
case "ATTACK_SPEED" -> {
|
||||
double percent = tier.getMinAttackSpeed() + (tier.getMaxAttackSpeed() - tier.getMinAttackSpeed()) * random.nextDouble();
|
||||
double base = 4.0; // Standard für Waffen
|
||||
double malus = base * percent; // KEIN x2!
|
||||
double newSpeed = base - malus;
|
||||
if (newSpeed < 0.1) newSpeed = 0.1;
|
||||
// Basiswert als Modifier setzen
|
||||
meta.addAttributeModifier(
|
||||
org.bukkit.attribute.Attribute.GENERIC_ATTACK_SPEED,
|
||||
new AttributeModifier(UUID.nameUUIDFromBytes("levelcraft_base_attackspeed".getBytes()), "levelcraft_base_attackspeed", base, AttributeModifier.Operation.ADD_NUMBER));
|
||||
// Bonus als Modifier setzen (negativ, weil niedriger besser)
|
||||
meta.addAttributeModifier(
|
||||
org.bukkit.attribute.Attribute.GENERIC_ATTACK_SPEED,
|
||||
new AttributeModifier(UUID.randomUUID(), "levelcraft_bonus_attackspeed", -malus, AttributeModifier.Operation.ADD_NUMBER));
|
||||
lore.add(tier.getDisplay() + ": -" + String.format("%.2f", malus) + " Angriffsgeschwindigkeit (neu: " + String.format("%.2f", newSpeed) + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Effekte und Skills wie gehabt (hier nicht verändert)
|
||||
java.util.List<String> effectsList = new java.util.ArrayList<>(ItemEffects.EFFECTS);
|
||||
java.util.Collections.shuffle(effectsList, random);
|
||||
int effects = 1; // Beispiel, passe nach deinem System an
|
||||
for (int i = 0; i < effects && i < effectsList.size(); i++) {
|
||||
lore.add(effectsList.get(i));
|
||||
}
|
||||
java.util.List<String> skillsList = new java.util.ArrayList<>(ItemEffects.SKILLS);
|
||||
java.util.Collections.shuffle(skillsList, random);
|
||||
int skills = 1; // Beispiel, passe nach deinem System an
|
||||
for (int i = 0; i < skills && i < skillsList.size(); i++) {
|
||||
lore.add(skillsList.get(i));
|
||||
}
|
||||
|
||||
meta.setLore(lore);
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
// Beispiel: ActionBar mit aktuellen Stats anzeigen (nur wenn Player bekannt)
|
||||
public static void sendItemStatsActionBar(org.bukkit.entity.Player player, ItemStack item) {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
double damage = 0, armor = 0, speed = 0, luck = 0;
|
||||
if (meta != null && meta.hasAttributeModifiers()) {
|
||||
for (var attr : meta.getAttributeModifiers().keySet()) {
|
||||
for (AttributeModifier mod : meta.getAttributeModifiers(attr)) {
|
||||
switch (attr.name()) {
|
||||
case "GENERIC_ATTACK_DAMAGE" -> damage += mod.getAmount();
|
||||
case "GENERIC_ARMOR" -> armor += mod.getAmount();
|
||||
case "GENERIC_ATTACK_SPEED" -> speed += mod.getAmount();
|
||||
case "GENERIC_LUCK" -> luck += mod.getAmount();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
String stats = "§eStats: ";
|
||||
if (damage > 0) stats += "§c" + String.format("%.2f", damage) + "⚔ ";
|
||||
if (armor > 0) stats += "§b" + String.format("%.2f", armor) + "🛡 ";
|
||||
if (speed > 0) stats += "§a" + String.format("%.2f", speed) + "⏩ ";
|
||||
if (luck > 0) stats += "§d" + String.format("%.2f", luck) + "☘ ";
|
||||
player.sendActionBar(stats.trim());
|
||||
}
|
||||
|
||||
// Hilfsmethoden für Item-Typen:
|
||||
private static boolean isWeapon(ItemStack item) {
|
||||
String name = item.getType().name();
|
||||
return name.endsWith("_SWORD") || name.endsWith("_AXE") || name.equals("TRIDENT") || name.equals("BOW") || name.equals("CROSSBOW");
|
||||
}
|
||||
private static boolean isArmor(ItemStack item) {
|
||||
String name = item.getType().name();
|
||||
return name.endsWith("_HELMET") || name.endsWith("_CHESTPLATE") || name.endsWith("_LEGGINGS") || name.endsWith("_BOOTS");
|
||||
}
|
||||
private static boolean isTool(ItemStack item) {
|
||||
String name = item.getType().name();
|
||||
return name.endsWith("_PICKAXE") || name.endsWith("_SHOVEL") || name.endsWith("_HOE");
|
||||
}
|
||||
|
||||
private static double getBaseDamage(ItemStack item) {
|
||||
switch (item.getType()) {
|
||||
case WOODEN_SWORD: return 4;
|
||||
case STONE_SWORD: return 5;
|
||||
case IRON_SWORD: return 6;
|
||||
case DIAMOND_SWORD: return 7;
|
||||
case NETHERITE_SWORD: return 8;
|
||||
case WOODEN_AXE: return 7;
|
||||
case STONE_AXE: return 9;
|
||||
case IRON_AXE: return 9;
|
||||
case DIAMOND_AXE: return 9;
|
||||
case NETHERITE_AXE: return 10;
|
||||
case TRIDENT: return 8;
|
||||
case BOW: return 6;
|
||||
case CROSSBOW: return 9;
|
||||
default: return 1;
|
||||
}
|
||||
}
|
||||
|
||||
private static double getBaseArmor(ItemStack item) {
|
||||
switch (item.getType()) {
|
||||
case LEATHER_HELMET: return 1;
|
||||
case LEATHER_CHESTPLATE: return 3;
|
||||
case LEATHER_LEGGINGS: return 2;
|
||||
case LEATHER_BOOTS: return 1;
|
||||
case CHAINMAIL_HELMET: return 2;
|
||||
case CHAINMAIL_CHESTPLATE: return 5;
|
||||
case CHAINMAIL_LEGGINGS: return 4;
|
||||
case CHAINMAIL_BOOTS: return 1;
|
||||
case IRON_HELMET: return 2;
|
||||
case IRON_CHESTPLATE: return 6;
|
||||
case IRON_LEGGINGS: return 5;
|
||||
case IRON_BOOTS: return 2;
|
||||
case DIAMOND_HELMET: return 3;
|
||||
case DIAMOND_CHESTPLATE: return 8;
|
||||
case DIAMOND_LEGGINGS: return 6;
|
||||
case DIAMOND_BOOTS: return 3;
|
||||
case NETHERITE_HELMET: return 3;
|
||||
case NETHERITE_CHESTPLATE: return 8;
|
||||
case NETHERITE_LEGGINGS: return 6;
|
||||
case NETHERITE_BOOTS: return 3;
|
||||
case GOLDEN_HELMET: return 2;
|
||||
case GOLDEN_CHESTPLATE: return 5;
|
||||
case GOLDEN_LEGGINGS: return 3;
|
||||
case GOLDEN_BOOTS: return 1;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
53
src/main/java/com/simolzimol/levelcraft/item/StatTier.java
Normal file
53
src/main/java/com/simolzimol/levelcraft/item/StatTier.java
Normal file
@@ -0,0 +1,53 @@
|
||||
package com.simolzimol.levelcraft.item;
|
||||
|
||||
public enum StatTier {
|
||||
TIER_1("§7Tier 1", 0.01, 0.03, 0.01, 0.03, 0.01, 0.03, 0.01, 0.02, 0.01, 0.02, 0.01, 0.02),
|
||||
TIER_2("§aTier 2", 0.04, 0.07, 0.04, 0.07, 0.04, 0.07, 0.02, 0.04, 0.02, 0.04, 0.02, 0.04),
|
||||
TIER_3("§9Tier 3", 0.08, 0.12, 0.08, 0.12, 0.08, 0.12, 0.04, 0.07, 0.04, 0.07, 0.04, 0.07),
|
||||
TIER_4("§5Tier 4", 0.13, 0.18, 0.13, 0.18, 0.13, 0.18, 0.07, 0.10, 0.07, 0.10, 0.07, 0.10),
|
||||
TIER_5("§6Tier 5", 0.19, 0.25, 0.19, 0.25, 0.19, 0.25, 0.10, 0.15, 0.10, 0.15, 0.10, 0.15);
|
||||
|
||||
private final String display;
|
||||
private final double minDurability, maxDurability;
|
||||
private final double minDamage, maxDamage;
|
||||
private final double minArmor, maxArmor;
|
||||
private final double minAttackSpeed, maxAttackSpeed;
|
||||
private final double minMoveSpeed, maxMoveSpeed;
|
||||
private final double minLuck, maxLuck;
|
||||
|
||||
StatTier(String display,
|
||||
double minDurability, double maxDurability,
|
||||
double minDamage, double maxDamage,
|
||||
double minArmor, double maxArmor,
|
||||
double minAttackSpeed, double maxAttackSpeed,
|
||||
double minMoveSpeed, double maxMoveSpeed,
|
||||
double minLuck, double maxLuck) {
|
||||
this.display = display;
|
||||
this.minDurability = minDurability;
|
||||
this.maxDurability = maxDurability;
|
||||
this.minDamage = minDamage;
|
||||
this.maxDamage = maxDamage;
|
||||
this.minArmor = minArmor;
|
||||
this.maxArmor = maxArmor;
|
||||
this.minAttackSpeed = minAttackSpeed;
|
||||
this.maxAttackSpeed = maxAttackSpeed;
|
||||
this.minMoveSpeed = minMoveSpeed;
|
||||
this.maxMoveSpeed = maxMoveSpeed;
|
||||
this.minLuck = minLuck;
|
||||
this.maxLuck = maxLuck;
|
||||
}
|
||||
|
||||
public String getDisplay() { return display; }
|
||||
public double getMinDurability() { return minDurability; }
|
||||
public double getMaxDurability() { return maxDurability; }
|
||||
public double getMinDamage() { return minDamage; }
|
||||
public double getMaxDamage() { return maxDamage; }
|
||||
public double getMinArmor() { return minArmor; }
|
||||
public double getMaxArmor() { return maxArmor; }
|
||||
public double getMinAttackSpeed() { return minAttackSpeed; }
|
||||
public double getMaxAttackSpeed() { return maxAttackSpeed; }
|
||||
public double getMinMoveSpeed() { return minMoveSpeed; }
|
||||
public double getMaxMoveSpeed() { return maxMoveSpeed; }
|
||||
public double getMinLuck() { return minLuck; }
|
||||
public double getMaxLuck() { return maxLuck; }
|
||||
}
|
||||
@@ -18,10 +18,10 @@ public class CraftListener implements Listener {
|
||||
if (result == null) return;
|
||||
if (result.getType().getMaxDurability() <= 0) return;
|
||||
|
||||
// Gecraftete Items: -1 (selten) bis 3 (häufig)
|
||||
Rarity rarity = Rarity.getRandomRarity(random, true, 3);
|
||||
ItemUtil.setRarity(result, rarity);
|
||||
ItemUtil.assignUniqueId(result);
|
||||
ItemUtil.addRandomBonuses(result, rarity, random);
|
||||
event.setCurrentItem(result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,6 +75,7 @@ public class LootListener implements Listener {
|
||||
Rarity rarity = Rarity.fromValue(rarityValue);
|
||||
ItemUtil.setRarity(item, rarity);
|
||||
ItemUtil.assignUniqueId(item);
|
||||
ItemUtil.addRandomBonuses(item, rarity, random);
|
||||
item.setItemMeta(item.getItemMeta());
|
||||
}
|
||||
}, 1L); // 1 Tick Verzögerung
|
||||
|
||||
@@ -16,10 +16,8 @@ public class MobDropListener implements Listener {
|
||||
public void onMobDrop(EntityDropItemEvent event) {
|
||||
ItemStack item = event.getItemDrop().getItemStack();
|
||||
if (item == null) return;
|
||||
// Nur Items mit Haltbarkeit (Waffen, Rüstung, Werkzeuge)
|
||||
if (item.getType().getMaxDurability() <= 0) return;
|
||||
|
||||
// Rarity für Mobdrops: -1 bis 7
|
||||
int rarityValue = random.nextInt(9) - 1; // -1 bis 7
|
||||
if (rarityValue > 7) rarityValue = 7;
|
||||
if (rarityValue < -1) rarityValue = -1;
|
||||
@@ -27,6 +25,7 @@ public class MobDropListener implements Listener {
|
||||
Rarity rarity = Rarity.fromValue(rarityValue);
|
||||
ItemUtil.setRarity(item, rarity);
|
||||
ItemUtil.assignUniqueId(item);
|
||||
ItemUtil.addRandomBonuses(item, rarity, random);
|
||||
event.getItemDrop().setItemStack(item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ public class VillagerTradeListener implements Listener {
|
||||
ItemStack result = recipe.getResult().clone();
|
||||
ItemMeta meta = result.getItemMeta();
|
||||
if (meta != null && !meta.getPersistentDataContainer().has(ItemUtil.getRarityKey(), PersistentDataType.INTEGER)) {
|
||||
// Nur Items mit Haltbarkeit (Waffen, Rüstung, Werkzeuge)
|
||||
if (result.getType().getMaxDurability() > 0) {
|
||||
int rarityValue = random.nextInt(7) - 1; // -1 bis 5
|
||||
if (rarityValue > 5) rarityValue = 5;
|
||||
@@ -38,6 +37,7 @@ public class VillagerTradeListener implements Listener {
|
||||
Rarity rarity = Rarity.fromValue(rarityValue);
|
||||
ItemUtil.setRarity(result, rarity);
|
||||
ItemUtil.assignUniqueId(result);
|
||||
ItemUtil.addRandomBonuses(result, rarity, random);
|
||||
}
|
||||
}
|
||||
// Neues Rezept mit gleichem Input, aber modifiziertem Output
|
||||
|
||||
Reference in New Issue
Block a user