diff --git a/src/main/java/fr/openmc/core/features/events/contents/dailyevents/contents/bloodynight/contents/enchantments/Vampirism.java b/src/main/java/fr/openmc/core/features/events/contents/dailyevents/contents/bloodynight/contents/enchantments/Vampirism.java new file mode 100644 index 000000000..83ff1f7d2 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/events/contents/dailyevents/contents/bloodynight/contents/enchantments/Vampirism.java @@ -0,0 +1,148 @@ +package fr.openmc.core.features.events.contents.dailyevents.contents.bloodynight.contents.enchantments; + +import fr.openmc.core.features.dream.models.registry.DreamEnchantment; +import fr.openmc.core.utils.text.messages.TranslationManager; +import io.papermc.paper.registry.data.EnchantmentRegistryEntry; +import io.papermc.paper.registry.keys.tags.ItemTypeTagKeys; +import io.papermc.paper.registry.tag.TagKey; +import net.kyori.adventure.key.Key; +import net.kyori.adventure.text.Component; +import org.bukkit.NamespacedKey; +import org.bukkit.attribute.Attribute; +import org.bukkit.attribute.AttributeInstance; +import org.bukkit.attribute.AttributeModifier; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.player.PlayerItemHeldEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.ItemType; + +@SuppressWarnings("UnstableApiUsage") +public class Vampirism extends DreamEnchantment implements Listener { + private static final NamespacedKey MAX_HEALTH_MODIFIER_KEY = + new NamespacedKey("omc_daily_events", "vampirism_max_health"); + + @Override + public Key getKey() { + return Key.key("omc_daily_events:vampirism"); + } + + @Override + public Component getName() { + return TranslationManager.translation("feature.dailyevents.bloody_night.enchantment.vampirism.name"); + } + + @Override + public TagKey getSupportedItems() { + return ItemTypeTagKeys.SWORDS; + } + + @Override + public int getMaxLevel() { + return 3; + } + + @Override + public int getWeight() { + return 1; + } + + @Override + public int getAnvilCost() { + return 4; + } + + @Override + public EnchantmentRegistryEntry.EnchantmentCost getMinimumCost() { + return EnchantmentRegistryEntry.EnchantmentCost.of(1, 2); + } + + @Override + public EnchantmentRegistryEntry.EnchantmentCost getMaximalmCost() { + return EnchantmentRegistryEntry.EnchantmentCost.of(4, 5); + } + + @EventHandler + public void onAttack(EntityDamageByEntityEvent event) { + if (!(event.getDamager() instanceof Player player)) return; + if (!(event.getEntity() instanceof LivingEntity)) return; + + Enchantment enchant = this.getEnchantment(); + if (enchant == null) return; + + ItemStack item = player.getInventory().getItemInMainHand(); + if (!item.getEnchantments().containsKey(enchant)) return; + int level = item.getEnchantmentLevel(enchant); + + double damageDealt = event.getFinalDamage(); + if (damageDealt <= 0) return; + + healPlayer(player, damageDealt); + + if (level >= 2) { + double max = getMaxHealthForLevel(level); + + AttributeInstance maxHealthAttr = player.getAttribute(Attribute.MAX_HEALTH); + if (maxHealthAttr == null) return; + + maxHealthAttr.addModifier(new AttributeModifier( + MAX_HEALTH_MODIFIER_KEY, + max - maxHealthAttr.getValue(), + AttributeModifier.Operation.ADD_NUMBER + )); + } + } + + @EventHandler + public void onItemHeldChange(PlayerItemHeldEvent event) { + Player player = event.getPlayer(); + + Enchantment enchant = this.getEnchantment(); + if (enchant == null) return; + + ItemStack item = player.getInventory().getItem(event.getPreviousSlot()); + if (item == null) return; + if (!item.getEnchantments().containsKey(enchant)) return; + + int level = item.getEnchantmentLevel(enchant); + + if (level < 2) return; + + AttributeInstance maxHealthAttr = player.getAttribute(Attribute.MAX_HEALTH); + if (maxHealthAttr == null) return; + maxHealthAttr.removeModifier(MAX_HEALTH_MODIFIER_KEY); + } + + /** + * Donne 1/8 de vie en fonction des dégâts infligés à l'attaquant. + * @param player le joueur ciblé + * @param damageDealt le nombre de dégats mis + */ + private void healPlayer(Player player, double damageDealt) { + AttributeInstance maxHealthAttr = player.getAttribute(Attribute.MAX_HEALTH); + if (maxHealthAttr == null) return; + + double maxHealth = maxHealthAttr.getValue(); + double heal = damageDealt * 0.125; + double newHealth = Math.min(maxHealth, player.getHealth() + heal); + + player.setHealth(newHealth); + } + + /** + * Donne la vie maximale que le joueur peut avoir en fonction du niveau de l'enchantement. + * @param level le niveau de l'enchantement + * @return la vie maximale + */ + private double getMaxHealthForLevel(int level) { + return switch (level) { + case 2 -> 25.0; + case 3 -> 30.0; + default -> 0.0; + }; + } +} \ No newline at end of file diff --git a/src/main/java/fr/openmc/core/features/events/contents/dailyevents/contents/bloodynight/contents/loottable/BloodyMobLootTable.java b/src/main/java/fr/openmc/core/features/events/contents/dailyevents/contents/bloodynight/contents/loottable/BloodyMobLootTable.java new file mode 100644 index 000000000..bff68b171 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/events/contents/dailyevents/contents/bloodynight/contents/loottable/BloodyMobLootTable.java @@ -0,0 +1,37 @@ +package fr.openmc.core.features.events.contents.dailyevents.contents.bloodynight.contents.loottable; + +import fr.openmc.core.registry.loottable.CustomLootTable; +import fr.openmc.core.registry.loottable.loots.CustomLoot; +import fr.openmc.core.registry.loottable.loots.ItemLoot; +import fr.openmc.core.utils.text.messages.TranslationManager; +import net.kyori.adventure.text.Component; +import org.bukkit.Material; + +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +public class BloodyMobLootTable extends CustomLootTable { + @Override + public Component getName() { + return TranslationManager.translation("feature.dailyevents.bloody_night.loot_table.bloody_mob"); + } + + @Override + public String getNamespace() { + return "omc_daily_events:bloody_mobs"; + } + + @Override + public Set getLoots() { + return new LinkedHashSet<>(List.of( + new ItemLoot(Material.IRON_INGOT,0.3, 1, 5), + new ItemLoot(Material.GOLD_INGOT,0.2, 2, 4), + new ItemLoot(Material.DIAMOND,0.1, 1, 2), + new ItemLoot(Material.IRON_BLOCK,0.08, 1, 2), + new ItemLoot(Material.GOLD_BLOCK,0.06, 1, 2), + new ItemLoot(Material.DIAMOND_BLOCK,0.03, 1), + new ItemLoot(Material.NETHERITE_INGOT,0.004, 1) + )); + } +} diff --git a/src/main/java/fr/openmc/core/features/events/contents/dailyevents/contents/bloodynight/contents/loottable/VampireLootTable.java b/src/main/java/fr/openmc/core/features/events/contents/dailyevents/contents/bloodynight/contents/loottable/VampireLootTable.java new file mode 100644 index 000000000..427ba492f --- /dev/null +++ b/src/main/java/fr/openmc/core/features/events/contents/dailyevents/contents/bloodynight/contents/loottable/VampireLootTable.java @@ -0,0 +1,37 @@ +package fr.openmc.core.features.events.contents.dailyevents.contents.bloodynight.contents.loottable; + +import fr.openmc.core.OMCRegistry; +import fr.openmc.core.registry.loottable.CustomLootTable; +import fr.openmc.core.registry.loottable.loots.CustomLoot; +import fr.openmc.core.registry.loottable.loots.ItemLoot; +import fr.openmc.core.utils.text.messages.TranslationManager; +import net.kyori.adventure.text.Component; + +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +public class VampireLootTable extends CustomLootTable { + @Override + public Component getName() { + return TranslationManager.translation("feature.dailyevents.bloody_night.loot_table.vampire_boss"); + } + + @Override + public String getNamespace() { + return "omc_daily_events.vampire_boss"; + } + + @Override + public Set getLoots() { + return new LinkedHashSet<>(List.of( + new ItemLoot(OMCRegistry.CUSTOM_ITEMS.AYWENITE_BLOCK,1, 1, 5), + new ItemLoot(OMCRegistry.CUSTOM_ITEMS.VAMPIRE_HEAD,0.25, 1), + new ItemLoot( + OMCRegistry.CUSTOM_ENCHANTS.VAMPIRISM.getEnchantedBookItem(1, 3), + 0.1, + 1 + ) + )); + } +} \ No newline at end of file diff --git a/src/main/java/fr/openmc/core/registry/enchantments/CustomEnchantment.java b/src/main/java/fr/openmc/core/registry/enchantments/CustomEnchantment.java index 13f6d7097..694e83e10 100644 --- a/src/main/java/fr/openmc/core/registry/enchantments/CustomEnchantment.java +++ b/src/main/java/fr/openmc/core/registry/enchantments/CustomEnchantment.java @@ -1,6 +1,7 @@ package fr.openmc.core.registry.enchantments; import fr.openmc.core.registry.items.CustomItem; +import fr.openmc.core.utils.RandomUtils; import io.papermc.paper.registry.RegistryAccess; import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.data.EnchantmentRegistryEntry; @@ -54,6 +55,11 @@ public ItemStack getVanilla() { }; } + public CustomItem getEnchantedBookItem(int minLevel, int maxLevel) { + int level = RandomUtils.randomBetween(minLevel, maxLevel); + return getEnchantedBookItem(level); + } + public Enchantment getEnchantment() { Registry<@NotNull Enchantment> enchantmentRegistry = RegistryAccess .registryAccess() diff --git a/src/main/java/fr/openmc/core/registry/enchantments/CustomEnchantmentRegistry.java b/src/main/java/fr/openmc/core/registry/enchantments/CustomEnchantmentRegistry.java index b632fdb78..d6a65d4a9 100644 --- a/src/main/java/fr/openmc/core/registry/enchantments/CustomEnchantmentRegistry.java +++ b/src/main/java/fr/openmc/core/registry/enchantments/CustomEnchantmentRegistry.java @@ -7,6 +7,7 @@ import fr.openmc.core.features.dream.registries.enchantements.DreamSleeper; import fr.openmc.core.features.dream.registries.enchantements.Experientastic; import fr.openmc.core.features.dream.registries.enchantements.Soulbound; +import fr.openmc.core.features.events.contents.dailyevents.contents.bloodynight.contents.enchantments.Vampirism; import io.papermc.paper.plugin.bootstrap.BootstrapContext; import io.papermc.paper.registry.data.EnchantmentRegistryEntry; import io.papermc.paper.registry.event.RegistryComposeEvent; @@ -30,6 +31,8 @@ public Key key(CustomEnchantment registryObject) { public final CustomEnchantment EXPERIENTASTIC = register(new Experientastic()); public final CustomEnchantment DREAM_SLEEPER = register(new DreamSleeper()); + public final CustomEnchantment VAMPIRISM = register(new Vampirism()); + @Override public void bootstrap(BootstrapContext context) { context.getLifecycleManager().registerEventHandler(RegistryEvents.ENCHANTMENT.compose() diff --git a/src/main/java/fr/openmc/core/registry/items/CustomItemRegistry.java b/src/main/java/fr/openmc/core/registry/items/CustomItemRegistry.java index f96d58213..200175764 100644 --- a/src/main/java/fr/openmc/core/registry/items/CustomItemRegistry.java +++ b/src/main/java/fr/openmc/core/registry/items/CustomItemRegistry.java @@ -127,6 +127,8 @@ public class CustomItemRegistry extends Registry implements public final CustomItem POISSON_STEVE_HEAD = register("omc_daily_events:poisson_steve_head", Material.PLAYER_HEAD); public final CustomItem KRAKEN_HEAD = register("omc_daily_events:kraken_head", Material.PLAYER_HEAD); public final CustomItem LEVIATHAN_HEAD = register("omc_daily_events:leviathan_head", Material.PLAYER_HEAD); + public final CustomItem VAMPIRE_HEAD = register("omc_daily_events:vampire_head", Material.PLAYER_HEAD); + @Override diff --git a/src/main/java/fr/openmc/core/registry/loottable/CustomLootTableRegistry.java b/src/main/java/fr/openmc/core/registry/loottable/CustomLootTableRegistry.java index 2b6797b86..092e79273 100644 --- a/src/main/java/fr/openmc/core/registry/loottable/CustomLootTableRegistry.java +++ b/src/main/java/fr/openmc/core/registry/loottable/CustomLootTableRegistry.java @@ -2,6 +2,8 @@ import fr.openmc.core.bootstrap.registries.KeyedRegistry; import fr.openmc.core.bootstrap.registries.Registry; +import fr.openmc.core.features.events.contents.dailyevents.contents.bloodynight.contents.loottable.BloodyMobLootTable; +import fr.openmc.core.features.events.contents.dailyevents.contents.bloodynight.contents.loottable.VampireLootTable; import fr.openmc.core.features.events.contents.dailyevents.contents.miraculousfishing.contents.loottable.fishing.BasicFishLootTable; import fr.openmc.core.features.events.contents.dailyevents.contents.miraculousfishing.contents.loottable.fishing.MiraculousFishLootTable; import fr.openmc.core.features.events.contents.dailyevents.contents.miraculousfishing.contents.loottable.fishing.SeaCreatureLootTable; @@ -19,12 +21,14 @@ public class CustomLootTableRegistry extends Registry i public final CustomLootTable MIRACULOUS_FISHING = register(new MiraculousFishLootTable()); public final CustomLootTable BASIC_FISHING = register(new BasicFishLootTable()); public final CustomLootTable SEA_CREATURE = register(new SeaCreatureLootTable()); - public final CustomLootTable FISHING_FURNITURE = register(new FishingFurnitureLootTable()); public final CustomLootTable RARE_FISHING_TREASURE = register(new RareFishingTreasureLootTable()); public final CustomLootTable EPIC_FISHING_TREASURE = register(new EpicFishingTreasureLootTable()); public final CustomLootTable LEGENDARY_FISHING_TREASURE = register(new LegendaryFishingTreasureLootTable()); + public final CustomLootTable VAMPIRE = register(new VampireLootTable()); + public final CustomLootTable BLOODY_MOB = register(new BloodyMobLootTable()); + @Override public String key(CustomLootTable registryObject) { return registryObject.getNamespace(); diff --git a/src/main/java/fr/openmc/core/registry/loottable/loots/ItemLoot.java b/src/main/java/fr/openmc/core/registry/loottable/loots/ItemLoot.java index 014003291..04bd03a5e 100644 --- a/src/main/java/fr/openmc/core/registry/loottable/loots/ItemLoot.java +++ b/src/main/java/fr/openmc/core/registry/loottable/loots/ItemLoot.java @@ -60,6 +60,16 @@ public ItemLoot(Material item, double chance, int minAmount, int maxAmount) { maxAmount); } + public ItemLoot(Material item, double chance, int amount) { + if (item == null) { + throw new IllegalArgumentException("CustomItem cannot be null"); + } + this(Collections.singleton(ItemStack.of(item)), + null, + chance, + amount, + amount); + } public ItemLoot(CustomItem item, double chance, int amount) { if (item == null) { throw new IllegalArgumentException("CustomItem cannot be null"); diff --git a/src/main/resources/contents/omc_daily_events/head.yml b/src/main/resources/contents/omc_daily_events/head.yml index 53b204b82..90d141995 100644 --- a/src/main/resources/contents/omc_daily_events/head.yml +++ b/src/main/resources/contents/omc_daily_events/head.yml @@ -41,4 +41,9 @@ items: leviathan_head: display_name: "Tete de Léviathan" components_nbt_file: "nbt/head/leviathan.json" + material: PLAYER_HEAD + + vampire_head: + display_name: "Tete de Vampire" + components_nbt_file: "nbt/head/vampire.json" material: PLAYER_HEAD \ No newline at end of file diff --git a/src/main/resources/contents/omc_daily_events/nbt/head/vampire.json b/src/main/resources/contents/omc_daily_events/nbt/head/vampire.json new file mode 100644 index 000000000..616087460 --- /dev/null +++ b/src/main/resources/contents/omc_daily_events/nbt/head/vampire.json @@ -0,0 +1,12 @@ +{ + "components": { + "profile": { + "properties": [ + { + "name": "textures", + "value": "e3RleHR1cmVzOntTS0lOOnt1cmw6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZTdkOWFkNzk1NzdkYTBkMjY3MTlmNTljNGY0NDlkOTBjZGVhYjM5ZTcwMDk1ZTQ2NWI5ZWNhYWJmMjZjYmY3MSJ9fX0=\"}]},minecraft:lore=['{\"text\":\"https://namemc.com/skin/efaad3c14fefec0c" + } + ] + } + } +} \ No newline at end of file diff --git a/src/main/resources/translations/default/dailyevents.properties b/src/main/resources/translations/default/dailyevents.properties index a9a60699d..ea139460a 100644 --- a/src/main/resources/translations/default/dailyevents.properties +++ b/src/main/resources/translations/default/dailyevents.properties @@ -30,7 +30,7 @@ feature.dailyevents.broadcast.soon=*un évènement commence feature.dailyevents.miraculousfishing.broadcast.start= \
\
PËCHE MIRACLEUSE ! La grande session a commencé !\ -
*sortez vous canne à pêche et découvrez les mystères des lacs*\ +
*sortez vos cannes à pêche et découvrez les mystères des lacs*\
\
Effets :\
+ %1$s% vitesse de pêche\ @@ -99,4 +99,10 @@ feature.dailyevents.miraculousfishing.menu.info.sea_creature.lore=Des loots uniques et spéciaux feature.dailyevents.miraculousfishing.menu.info.loot_table.lore=Bénéficiez d'une bénédiction miraculeuse \
vous laissant des récompenses et des loots nouveaux\ -
CLIQUEZ ICI POUR VOIR LES ITEMS PECHABLE \ No newline at end of file +
CLIQUEZ ICI POUR VOIR LES ITEMS PECHABLE + +# ** Nuit sanglante ** +feature.dailyevents.bloody_night.loot_table.bloody_mob=Loots des monstres sanglants +feature.dailyevents.bloody_night.loot_table.vampire_boss=Loots du Vampire + +feature.dailyevents.bloody_night.enchantment.vampirism.name=Vampirisme \ No newline at end of file