diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/HashedArmorpiece.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/HashedArmorpiece.java index afb0cd4be..a848cadca 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/HashedArmorpiece.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/HashedArmorpiece.java @@ -78,7 +78,7 @@ public final class HashedArmorpiece { */ public boolean hasDiverged(ItemStack stack) { if (stack == null || stack.getType() == Material.AIR) { - return hash == 0; + return hash != 0; } else { ItemStack copy = stack.clone(); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java index 2e98e117a..74a2bf75a 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java @@ -19,6 +19,7 @@ import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Location; +import org.bukkit.NamespacedKey; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -31,9 +32,12 @@ import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; import io.github.thebusybiscuit.cscorelib2.config.Config; import io.github.thebusybiscuit.slimefun4.api.gps.Waypoint; import io.github.thebusybiscuit.slimefun4.api.items.HashedArmorpiece; +import io.github.thebusybiscuit.slimefun4.core.attributes.CustomProtection; +import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType; import io.github.thebusybiscuit.slimefun4.core.guide.GuideHistory; import io.github.thebusybiscuit.slimefun4.core.researching.Research; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece; import io.github.thebusybiscuit.slimefun4.utils.NumberUtils; import io.github.thebusybiscuit.slimefun4.utils.PatternUtils; import me.mrCookieSlime.Slimefun.api.Slimefun; @@ -47,6 +51,7 @@ import me.mrCookieSlime.Slimefun.api.Slimefun; * @see Research * @see Waypoint * @see PlayerBackpack + * @see HashedArmorpiece * */ public final class PlayerProfile { @@ -448,6 +453,37 @@ public final class PlayerProfile { } } + public boolean isProtected(ProtectionType type) { + int armorCount = 0; + + NamespacedKey setId = null; + for (HashedArmorpiece armor : armor) { + Optional armorPiece = armor.getItem(); + if (!armorPiece.isPresent()) return false; + + if (armorPiece.get() instanceof CustomProtection) { + CustomProtection protectedArmor = (CustomProtection) armorPiece.get(); + + if (setId == null && protectedArmor.isFullSetRequired()) { + setId = protectedArmor.getSetId(); + } + + for (ProtectionType protectionType : protectedArmor.getProtectionTypes()) { + if (protectionType == type) { + if (setId == null) { + return true; + } else if (setId.equals(protectedArmor.getSetId())) { + armorCount++; + } + } + } + + } + } + + return armorCount == 4; + } + @Override public int hashCode() { return uuid.hashCode(); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/CustomProtection.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/CustomProtection.java new file mode 100644 index 000000000..8a24a4cc2 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/CustomProtection.java @@ -0,0 +1,49 @@ +package io.github.thebusybiscuit.slimefun4.core.attributes; + +import org.bukkit.NamespacedKey; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageEvent; + +import io.github.thebusybiscuit.slimefun4.implementation.items.armor.HazmatArmorPiece; +import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece; + +/** + * Implement this interface to a {@link SlimefunArmorPiece} to protect + * the {@link Player} who wears that {@link SlimefunArmorPiece} from + * {@link ProtectionType} damage. + * + * Important: You need to specify which {@link ProtectionType} damages + * to protect the {@link Player} from. + * + * @author Linox + * + * @see SlimefunArmorPiece + * @see HazmatArmorPiece + * @see ItemAttribute + * + */ +public interface CustomProtection extends ItemAttribute { + + /** + * This returns which {@link ProtectionType} damages this {@link ItemAttribute} + * will protect the {@link Player} from. + * + * @return The {@link ProtectionType}s. + */ + ProtectionType[] getProtectionTypes(); + + /** + * This returns whether the full set is required for {@link Player}'s protection on + * assigned {@link ProtectionType} damages. + * + * @return Whether or not he full set is required. + */ + boolean isFullSetRequired(); + + /** + * This returns the armor set {@link NamespacedKey} of this {@link SlimefunArmorPiece}. + * + * @return The set {@link NamespacedKey}, null if none is found. + */ + NamespacedKey getSetId(); +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/ProtectionType.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/ProtectionType.java new file mode 100644 index 000000000..5fbc54eeb --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/ProtectionType.java @@ -0,0 +1,17 @@ +package io.github.thebusybiscuit.slimefun4.core.attributes; + +/** + * Represents the {@link ProtectionType} that a {@link CustomProtection} + * prevents the damage from. + * + * @author Linox + * + * @see CustomProtection + * + */ +public enum ProtectionType { + + RADIATION, + BEES; + +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java index 1ccac6d0e..d8a96572c 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java @@ -1,6 +1,8 @@ package io.github.thebusybiscuit.slimefun4.implementation; +import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.bukkit.Color; @@ -11,6 +13,7 @@ import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; +import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; import io.github.thebusybiscuit.slimefun4.core.attributes.MachineTier; import io.github.thebusybiscuit.slimefun4.core.attributes.MachineType; @@ -296,6 +299,40 @@ public final class SlimefunItems { REINFORCED_ALLOY_LEGGINGS.addUnsafeEnchantments(reinforced); REINFORCED_ALLOY_BOOTS.addUnsafeEnchantments(reinforced); + if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_15)) { + ItemMeta scubaHelmetMeta = SCUBA_HELMET.getItemMeta(); + List scubaHelmetMetaLore = scubaHelmetMeta.getLore(); + scubaHelmetMetaLore.addAll(Arrays.asList("", + ChatColors.color( "&7Equip the full set for:"), + ChatColors.color( "&7+Bee Protection"))); + scubaHelmetMeta.setLore(scubaHelmetMetaLore); + SCUBA_HELMET.setItemMeta(scubaHelmetMeta); + + ItemMeta hazmatChestplateItemMeta = HAZMAT_CHESTPLATE.getItemMeta(); + List hazmatChestplateItemMetaLore = hazmatChestplateItemMeta.getLore(); + hazmatChestplateItemMetaLore.addAll(Arrays.asList("", + ChatColors.color( "&7Equip the full set for:"), + ChatColors.color( "&7+Bee Protection"))); + hazmatChestplateItemMeta.setLore(hazmatChestplateItemMetaLore); + HAZMAT_CHESTPLATE.setItemMeta(hazmatChestplateItemMeta); + + ItemMeta hazmatLeggingsItemMeta = HAZMAT_LEGGINGS.getItemMeta(); + List hazmatLeggingsItemMetaLore = hazmatLeggingsItemMeta.getLore(); + hazmatLeggingsItemMetaLore.addAll(Arrays.asList("", + ChatColors.color( "&7Equip the full set for:"), + ChatColors.color( "&7+Bee Protection"))); + hazmatLeggingsItemMeta.setLore(hazmatLeggingsItemMetaLore); + HAZMAT_LEGGINGS.setItemMeta(hazmatLeggingsItemMeta); + + ItemMeta rubberBootsItemMeta = RUBBER_BOOTS.getItemMeta(); + List rubberBootsItemMetaLore = rubberBootsItemMeta.getLore(); + rubberBootsItemMetaLore.addAll(Arrays.asList("", + ChatColors.color( "&7Equip the full set for:"), + ChatColors.color( "&7+Bee Protection"))); + rubberBootsItemMeta.setLore(rubberBootsItemMetaLore); + RUBBER_BOOTS.setItemMeta(rubberBootsItemMeta); + } + Map gilded = new HashMap<>(); gilded.put(Enchantment.DURABILITY, 6); gilded.put(Enchantment.PROTECTION_ENVIRONMENTAL, 8); @@ -329,6 +366,7 @@ public final class SlimefunItems { public static final SlimefunItemStack ENDER_LUMP_3 = new SlimefunItemStack("ENDER_LUMP_3", Material.GOLD_NUGGET, "&5Ender Lump &7- &eIII", "", "&c&oTier: III"); public static final SlimefunItemStack MAGICAL_BOOK_COVER = new SlimefunItemStack("MAGICAL_BOOK_COVER", Material.PAPER, "&6Magical Book Cover", "", "&a&oUsed for various Magic Books"); public static final SlimefunItemStack MAGICAL_ZOMBIE_PILLS = new SlimefunItemStack("MAGICAL_ZOMBIE_PILLS", Material.NETHER_WART, "&6Magical Zombie Pills", "", "&eRight Click &7a Zombified Villager to", "&7instantly cure it from its curse"); + public static final SlimefunItemStack MAGICAL_GLASS = new SlimefunItemStack("MAGICAL_GLASS", Material.GLASS_PANE, "&6Magical Glass", "", "&a&oUsed for various Magical Gadgets"); public static final SlimefunItemStack BASIC_CIRCUIT_BOARD = new SlimefunItemStack("BASIC_CIRCUIT_BOARD", Material.ACTIVATOR_RAIL, "&bBasic Circuit Board"); public static final SlimefunItemStack ADVANCED_CIRCUIT_BOARD = new SlimefunItemStack("ADVANCED_CIRCUIT_BOARD", Material.POWERED_RAIL, "&bAdvanced Circuit Board"); public static final SlimefunItemStack WHEAT_FLOUR = new SlimefunItemStack("WHEAT_FLOUR", Material.SUGAR, "&fWheat Flour"); @@ -600,6 +638,7 @@ public final class SlimefunItems { public static final SlimefunItemStack RAINBOW_RUNE = new SlimefunItemStack("ANCIENT_RUNE_RAINBOW", new ColoredFireworkStar(Color.FUCHSIA, "&7Ancient Rune &8&l[&d&lRainbow&8&l]")); public static final SlimefunItemStack LIGHTNING_RUNE = new SlimefunItemStack("ANCIENT_RUNE_LIGHTNING", new ColoredFireworkStar(Color.fromRGB(255, 255, 95), "&7Ancient Rune &8&l[&e&lLightning&8&l]")); public static final SlimefunItemStack SOULBOUND_RUNE = new SlimefunItemStack("ANCIENT_RUNE_SOULBOUND", new ColoredFireworkStar(Color.fromRGB(47, 0, 117), "&7Ancient Rune &8&l[&5&lSoulbound&8&l]", "&eDrop this rune onto a dropped item to", "&5bind ðat item to your soul.", " ", "&eIt is advised that you only use this rune", "&eon &6important &eitems.", " ", "&eItems bound to your soul won't drop on death.")); + public static final SlimefunItemStack ENCHANTMENT_RUNE = new SlimefunItemStack("ANCIENT_RUNE_ENCHANTMENT", new ColoredFireworkStar(Color.fromRGB(255, 217, 25), "&7Ancient Rune &8&l[&6&lEnchantment&8&l]", "&eDrop this rune onto a dropped item to", "&6enchant ðat item with a random enchantment.")); /* Electricity */ public static final SlimefunItemStack SOLAR_GENERATOR = new SlimefunItemStack("SOLAR_GENERATOR", Material.DAYLIGHT_DETECTOR, "&bSolar Generator", "", LoreBuilder.machine(MachineTier.BASIC, MachineType.GENERATOR), LoreBuilder.powerBuffer(0), LoreBuilder.powerPerSecond(4)); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java index 3da4f58f4..e0a6e764f 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java @@ -52,6 +52,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.SeismicAx import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.VampireBlade; import io.github.thebusybiscuit.slimefun4.implementation.listeners.AncientAltarListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.BackpackListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.BeeListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.BlockListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.BlockPhysicsListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.CargoNodeListener; @@ -236,6 +237,9 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { new WitherListener(this); new IronGolemListener(this); new PlayerInteractEntityListener(this); + if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_15)) { + new BeeListener(this); + } new MobDropListener(this, (BasicCircuitBoard) SlimefunItems.BASIC_CIRCUIT_BOARD.getItem()); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/armor/HazmatArmorPiece.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/armor/HazmatArmorPiece.java new file mode 100644 index 000000000..3e55f1515 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/armor/HazmatArmorPiece.java @@ -0,0 +1,50 @@ +package io.github.thebusybiscuit.slimefun4.implementation.items.armor; + +import org.bukkit.NamespacedKey; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; + +import io.github.thebusybiscuit.slimefun4.core.attributes.CustomProtection; +import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +import me.mrCookieSlime.Slimefun.Lists.RecipeType; +import me.mrCookieSlime.Slimefun.Objects.Category; +import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; + +/** + * Represents 1 {@link SlimefunArmorPiece} of the Hazmat armor set. + * One of the very few utilisations of {@link CustomProtection}. + * + * @author Linox + * + * @see SlimefunArmorPiece + * @see CustomProtection + * + */ +public class HazmatArmorPiece extends SlimefunArmorPiece implements CustomProtection { + + private final NamespacedKey setId; + private final ProtectionType[] types; + + public HazmatArmorPiece(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, PotionEffect[] effects) { + super(category, item, recipeType, recipe, effects); + + types = new ProtectionType[] {ProtectionType.BEES, ProtectionType.RADIATION}; + setId = new NamespacedKey(SlimefunPlugin.instance, "hazmat_suit"); + } + + @Override + public ProtectionType[] getProtectionTypes() { + return types; + } + + @Override + public boolean isFullSetRequired() { + return true; + } + + @Override + public NamespacedKey getSetId() { + return setId; + } +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/armor/SlimefunArmorPiece.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/armor/SlimefunArmorPiece.java index 925934c64..47473bab7 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/armor/SlimefunArmorPiece.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/armor/SlimefunArmorPiece.java @@ -28,5 +28,4 @@ public class SlimefunArmorPiece extends SlimefunItem { public PotionEffect[] getPotionEffects() { return effects; } - } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/EnchantmentRune.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/EnchantmentRune.java new file mode 100644 index 000000000..658a215b4 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/EnchantmentRune.java @@ -0,0 +1,156 @@ +package io.github.thebusybiscuit.slimefun4.implementation.items.magical; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.EnumMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ThreadLocalRandom; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Particle; +import org.bukkit.Sound; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.inventory.ItemStack; + +import me.mrCookieSlime.Slimefun.Lists.RecipeType; +import me.mrCookieSlime.Slimefun.Objects.Category; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SimpleSlimefunItem; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; +import me.mrCookieSlime.Slimefun.Objects.handlers.ItemDropHandler; +import me.mrCookieSlime.Slimefun.SlimefunPlugin; +import me.mrCookieSlime.Slimefun.api.Slimefun; +import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; + +/** + * This {@link SlimefunItem} allows you to enchant any enchantable {@link ItemStack} with a random + * {@link Enchantment}. It is also one of the very few utilisations of {@link ItemDropHandler}. + * + * @author Linox + * + * @see ItemDropHandler + * @see Enchantment + * + */ +public class EnchantmentRune extends SimpleSlimefunItem { + + private static final double RANGE = 1.5; + private final Map> applicableEnchantments = new EnumMap<>(Material.class); + + public EnchantmentRune(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { + super(category, item, recipeType, recipe); + + for (Material mat : Material.values()) { + List enchantments = new ArrayList<>(); + for (Enchantment enchantment : Enchantment.values()) { + if (enchantment == Enchantment.BINDING_CURSE || enchantment == Enchantment.VANISHING_CURSE) continue; + if (enchantment.canEnchantItem(new ItemStack(mat))) enchantments.add(enchantment); + } + applicableEnchantments.put(mat, enchantments); + } + } + + @Override + public ItemDropHandler getItemHandler() { + return (e, p, item) -> { + if (isItem(item.getItemStack())) { + + if (!Slimefun.hasUnlocked(p, this, true)) { + return true; + } + + Slimefun.runSync(() -> activate(p, e, item), 20L); + + return true; + } + return false; + }; + } + + private void activate(Player p, PlayerDropItemEvent e, Item item) { + // Being sure the entity is still valid and not picked up or whatsoever. + if (!item.isValid()) { + return; + } + + Location l = item.getLocation(); + Collection entites = l.getWorld().getNearbyEntities(l, RANGE, RANGE, RANGE, this::findCompatibleItem); + Optional optional = entites.stream().findFirst(); + + if (optional.isPresent()) { + Item entity = (Item) optional.get(); + ItemStack target = entity.getItemStack(); + + List applicableEnchantmentList = applicableEnchantments.get(target.getType()); + if (applicableEnchantmentList == null) { + SlimefunPlugin.getLocal().sendMessage(p, "messages.enchantment-rune.fail", true); + return; + } else { + applicableEnchantmentList = new ArrayList<>(applicableEnchantmentList); + } + + //Removing the enchantments that the item already has from enchantmentSet + for (Enchantment itemEnchantment : target.getEnchantments().keySet()) { + for (Enchantment applicableEnchantment : applicableEnchantmentList) { + if (applicableEnchantment == itemEnchantment || applicableEnchantment.conflictsWith(itemEnchantment)) { + applicableEnchantmentList.remove(applicableEnchantment); + } + } + } + + if (applicableEnchantmentList.isEmpty()) { + SlimefunPlugin.getLocal().sendMessage(p, "messages.enchantment-rune.no-enchantment", true); + return; + } + + Enchantment enchantment = applicableEnchantmentList.get(ThreadLocalRandom.current().nextInt(applicableEnchantmentList.size())); + int level = 1; + if (enchantment.getMaxLevel() != 1) { + level = ThreadLocalRandom.current().nextInt(enchantment.getMaxLevel()) + 1; + } + target.addEnchantment(enchantment, level); + + if (target.getAmount() == 1) { + e.setCancelled(true); + + // This lightning is just an effect, it deals no damage. + l.getWorld().strikeLightningEffect(l); + + Slimefun.runSync(() -> { + // Being sure entities are still valid and not picked up or whatsoever. + if (item.isValid() && entity.isValid() && target.getAmount() == 1) { + + l.getWorld().spawnParticle(Particle.CRIT_MAGIC, l, 1); + l.getWorld().playSound(l, Sound.ENTITY_ZOMBIE_VILLAGER_CURE, 1F, 1F); + + entity.remove(); + item.remove(); + l.getWorld().dropItemNaturally(l, target); + + SlimefunPlugin.getLocal().sendMessage(p, "messages.enchantment-rune.success", true); + } + }, 10L); + } else { + SlimefunPlugin.getLocal().sendMessage(p, "messages.enchantment-rune.fail", true); + } + } + } + + private boolean findCompatibleItem(Entity n) { + if (n instanceof Item) { + Item item = (Item) n; + + return !isItem(item.getItemStack()); + } + + return false; + } + +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/SoulboundRune.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/SoulboundRune.java index a9eedcd16..309740fc3 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/SoulboundRune.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/SoulboundRune.java @@ -48,7 +48,7 @@ public class SoulboundRune extends SimpleSlimefunItem { return (e, p, item) -> { if (isItem(item.getItemStack())) { - if (!Slimefun.hasUnlocked(p, SlimefunItems.SOULBOUND_RUNE, true)) { + if (!Slimefun.hasUnlocked(p, this, true)) { return true; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BeeListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BeeListener.java new file mode 100644 index 000000000..c45531d5a --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BeeListener.java @@ -0,0 +1,51 @@ +package io.github.thebusybiscuit.slimefun4.implementation.listeners; + +import java.util.Optional; + +import org.bukkit.entity.Bee; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.ItemStack; + +import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils; +import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; +import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; + +/** + * The listener for Hazmat Suit's {@link Bee} sting protection. + * Only applied if the whole set is worn. + * + * @author Linox + * + */ +public class BeeListener implements Listener { + + public BeeListener(SlimefunPlugin plugin) { + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + @EventHandler + public void onDamage(EntityDamageByEntityEvent e) { + if (e.getDamager() instanceof Bee && e.getEntity() instanceof Player) { + + Player p = (Player) e.getEntity(); + Optional optional = PlayerProfile.find(p); + if (!optional.isPresent()) { + PlayerProfile.request(p); + return; + } + + PlayerProfile profile = optional.get(); + if (profile.isProtected(ProtectionType.BEES)) { + for (ItemStack armor : p.getInventory().getArmorContents()) { + ItemUtils.damageItem(armor, 1, false); + } + e.setDamage(0D); + } + } + } + +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/ResearchSetup.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/ResearchSetup.java index e30bfc2ac..c1c875940 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/ResearchSetup.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/ResearchSetup.java @@ -268,6 +268,7 @@ public final class ResearchSetup { register("magical_zombie_pills", 257, "De-Zombification", 22, SlimefunItems.MAGICAL_ZOMBIE_PILLS); register("auto_brewer", 258, "Industrial Brewery", 30, SlimefunItems.AUTO_BREWER); register("climbing_pick", 259, "Block Raider", 20, SlimefunItems.CLIMBING_PICK); + register("enchantment_rune", 260, "Ancient Enchanting", 24, SlimefunItems.MAGICAL_GLASS, SlimefunItems.ENCHANTMENT_RUNE); } private static void register(String key, int id, String name, int defaultCost, ItemStack... items) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java index 66fdf2439..06a162a97 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java @@ -30,6 +30,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.androids.FisherAn import io.github.thebusybiscuit.slimefun4.implementation.items.androids.MinerAndroid; import io.github.thebusybiscuit.slimefun4.implementation.items.androids.ProgrammableAndroid; import io.github.thebusybiscuit.slimefun4.implementation.items.androids.WoodcutterAndroid; +import io.github.thebusybiscuit.slimefun4.implementation.items.armor.HazmatArmorPiece; import io.github.thebusybiscuit.slimefun4.implementation.items.armor.Parachute; import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece; import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler; @@ -118,6 +119,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.gps.GPSTransmitte import io.github.thebusybiscuit.slimefun4.implementation.items.gps.PersonalActivationPlate; import io.github.thebusybiscuit.slimefun4.implementation.items.gps.Teleporter; import io.github.thebusybiscuit.slimefun4.implementation.items.gps.TeleporterPylon; +import io.github.thebusybiscuit.slimefun4.implementation.items.magical.EnchantmentRune; import io.github.thebusybiscuit.slimefun4.implementation.items.magical.InfernalBonemeal; import io.github.thebusybiscuit.slimefun4.implementation.items.magical.InfusedMagnet; import io.github.thebusybiscuit.slimefun4.implementation.items.magical.KnowledgeFlask; @@ -349,12 +351,12 @@ public final class SlimefunItemSetup { new ItemStack[] {SlimefunItems.SALT, new ItemStack(Material.ROTTEN_FLESH), null, null, null, null, null, null, null}) .register(plugin); - new SlimefunItem(categories.magicalArmor, SlimefunItems.SLIME_HELMET, RecipeType.ARMOR_FORGE, - new ItemStack[] {new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), null, new ItemStack(Material.IRON_INGOT), null, null, null}) + new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_HELMET, RecipeType.ARMOR_FORGE, + new ItemStack[] {new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), null, new ItemStack(Material.IRON_INGOT), null, null, null}, null) .register(plugin); - new SlimefunItem(categories.magicalArmor, SlimefunItems.SLIME_CHESTPLATE, RecipeType.ARMOR_FORGE, - new ItemStack[] {new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT)}) + new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_CHESTPLATE, RecipeType.ARMOR_FORGE, + new ItemStack[] {new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT)}, null) .register(plugin); new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_LEGGINGS, RecipeType.ARMOR_FORGE, @@ -375,6 +377,10 @@ public final class SlimefunItemSetup { new ItemStack[] {null, SlimefunItems.MAGIC_LUMP_2, null, SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.BOOK), SlimefunItems.MAGIC_LUMP_2, null, SlimefunItems.MAGIC_LUMP_2, null}) .register(plugin); + new SlimefunItem(categories.magicalResources, SlimefunItems.MAGICAL_GLASS, RecipeType.MAGIC_WORKBENCH, + new ItemStack[] {SlimefunItems.MAGIC_LUMP_2, SlimefunItems.GOLD_DUST, SlimefunItems.MAGIC_LUMP_2, SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE, new ItemStack(Material.GLASS_PANE), SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE, SlimefunItems.MAGIC_LUMP_2, SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE, SlimefunItems.MAGIC_LUMP_2}) + .register(plugin); + new BasicCircuitBoard(categories.technicalComponents, SlimefunItems.BASIC_CIRCUIT_BOARD, RecipeType.MOB_DROP, new ItemStack[] {null, null, null, null, new CustomItem(SlimefunUtils.getCustomHead("89091d79ea0f59ef7ef94d7bba6e5f17f2f7d4572c44f90f76c4819a714"), "&aIron Golem"), null, null, null, null}) .register(plugin); @@ -904,22 +910,22 @@ public final class SlimefunItemSetup { SlimefunItems.GILDED_IRON_HELMET, SlimefunItems.GILDED_IRON_CHESTPLATE, SlimefunItems.GILDED_IRON_LEGGINGS, SlimefunItems.GILDED_IRON_BOOTS }, "GILDED_IRON", false, plugin); - new SlimefunArmorPiece(categories.armor, SlimefunItems.SCUBA_HELMET, RecipeType.ARMOR_FORGE, + new HazmatArmorPiece(categories.armor, SlimefunItems.SCUBA_HELMET, RecipeType.ARMOR_FORGE, new ItemStack[] {new ItemStack(Material.ORANGE_WOOL), new ItemStack(Material.ORANGE_WOOL), new ItemStack(Material.ORANGE_WOOL), new ItemStack(Material.BLACK_WOOL), new ItemStack(Material.GLASS_PANE), new ItemStack(Material.BLACK_WOOL), null, null, null}, new PotionEffect[] {new PotionEffect(PotionEffectType.WATER_BREATHING, 300, 1)}) .register(plugin); - new SlimefunArmorPiece(categories.armor, SlimefunItems.HAZMAT_CHESTPLATE, RecipeType.ARMOR_FORGE, + new HazmatArmorPiece(categories.armor, SlimefunItems.HAZMAT_CHESTPLATE, RecipeType.ARMOR_FORGE, new ItemStack[] {new ItemStack(Material.ORANGE_WOOL), null, new ItemStack(Material.ORANGE_WOOL), new ItemStack(Material.ORANGE_WOOL), new ItemStack(Material.ORANGE_WOOL), new ItemStack(Material.ORANGE_WOOL), new ItemStack(Material.BLACK_WOOL), new ItemStack(Material.BLACK_WOOL), new ItemStack(Material.BLACK_WOOL)}, new PotionEffect[] {new PotionEffect(PotionEffectType.FIRE_RESISTANCE, 300, 1)}) .register(plugin); - new SlimefunItem(categories.armor, SlimefunItems.HAZMAT_LEGGINGS, RecipeType.ARMOR_FORGE, - new ItemStack[] {new ItemStack(Material.BLACK_WOOL), new ItemStack(Material.BLACK_WOOL), new ItemStack(Material.BLACK_WOOL), new ItemStack(Material.ORANGE_WOOL), null, new ItemStack(Material.ORANGE_WOOL), new ItemStack(Material.ORANGE_WOOL), null, new ItemStack(Material.ORANGE_WOOL)}) + new HazmatArmorPiece(categories.armor, SlimefunItems.HAZMAT_LEGGINGS, RecipeType.ARMOR_FORGE, + new ItemStack[] {new ItemStack(Material.BLACK_WOOL), new ItemStack(Material.BLACK_WOOL), new ItemStack(Material.BLACK_WOOL), new ItemStack(Material.ORANGE_WOOL), null, new ItemStack(Material.ORANGE_WOOL), new ItemStack(Material.ORANGE_WOOL), null, new ItemStack(Material.ORANGE_WOOL)}, null) .register(plugin); - new SlimefunItem(categories.armor, SlimefunItems.RUBBER_BOOTS, RecipeType.ARMOR_FORGE, - new ItemStack[] {null, null, null, new ItemStack(Material.BLACK_WOOL), null, new ItemStack(Material.BLACK_WOOL), new ItemStack(Material.BLACK_WOOL), null, new ItemStack(Material.BLACK_WOOL)}) + new HazmatArmorPiece(categories.armor, SlimefunItems.RUBBER_BOOTS, RecipeType.ARMOR_FORGE, + new ItemStack[] {null, null, null, new ItemStack(Material.BLACK_WOOL), null, new ItemStack(Material.BLACK_WOOL), new ItemStack(Material.BLACK_WOOL), null, new ItemStack(Material.BLACK_WOOL)}, null) .register(plugin); new SlimefunItem(categories.misc, SlimefunItems.CRUSHED_ORE, RecipeType.ORE_CRUSHER, @@ -1003,12 +1009,12 @@ public final class SlimefunItemSetup { new TableSaw(categories.basicMachines, SlimefunItems.TABLE_SAW).register(plugin); } - new SlimefunItem(categories.magicalArmor, SlimefunItems.SLIME_HELMET_STEEL, RecipeType.ARMOR_FORGE, - new ItemStack[] {new ItemStack(Material.SLIME_BALL), SlimefunItems.STEEL_PLATE, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), null, null, null}) + new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_HELMET_STEEL, RecipeType.ARMOR_FORGE, + new ItemStack[] {new ItemStack(Material.SLIME_BALL), SlimefunItems.STEEL_PLATE, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), null, null, null}, null) .register(plugin); - new SlimefunItem(categories.magicalArmor, SlimefunItems.SLIME_CHESTPLATE_STEEL, RecipeType.ARMOR_FORGE, - new ItemStack[] {new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), SlimefunItems.STEEL_PLATE, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL)}) + new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_CHESTPLATE_STEEL, RecipeType.ARMOR_FORGE, + new ItemStack[] {new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), SlimefunItems.STEEL_PLATE, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL)}, null) .register(plugin); new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_LEGGINGS_STEEL, RecipeType.ARMOR_FORGE, @@ -2482,6 +2488,10 @@ public final class SlimefunItemSetup { new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.ENDER_LUMP_3, SlimefunItems.ENDER_RUNE, SlimefunItems.ENDER_LUMP_3, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.MAGIC_LUMP_3}) .register(plugin); + new EnchantmentRune(categories.magicalResources, SlimefunItems.ENCHANTMENT_RUNE, RecipeType.ANCIENT_ALTAR, + new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, SlimefunItems.MAGICAL_GLASS, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.MAGICAL_GLASS, SlimefunItems.LIGHTNING_RUNE, SlimefunItems.MAGICAL_GLASS, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.MAGICAL_GLASS, SlimefunItems.MAGIC_LUMP_3}) + .register(plugin); + new InfernalBonemeal(categories.magicalGadgets, SlimefunItems.INFERNAL_BONEMEAL, RecipeType.ANCIENT_ALTAR, new ItemStack[] {new ItemStack(Material.NETHER_WART), SlimefunItems.EARTH_RUNE, new ItemStack(Material.NETHER_WART), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.BONE_MEAL), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.NETHER_WART), new ItemStack(Material.BLAZE_POWDER), new ItemStack(Material.NETHER_WART)}, new CustomItem(SlimefunItems.INFERNAL_BONEMEAL, 8)) diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ArmorTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ArmorTask.java index a64607702..17351980f 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ArmorTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ArmorTask.java @@ -14,6 +14,7 @@ import org.bukkit.potion.PotionEffectType; import io.github.thebusybiscuit.slimefun4.api.items.HashedArmorpiece; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; +import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType; import io.github.thebusybiscuit.slimefun4.core.attributes.Radioactive; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; @@ -63,7 +64,7 @@ public class ArmorTask implements Runnable { checkForSolarHelmet(p); } - checkForRadiation(p); + checkForRadiation(p, profile); }); } } @@ -119,18 +120,17 @@ public class ArmorTask implements Runnable { return (world.getTime() < 12300 || world.getTime() > 23850) && p.getEyeLocation().getBlock().getLightFromSky() == 15; } - private void checkForRadiation(Player p) { - // Check for a Hazmat Suit - if (!SlimefunUtils.isItemSimilar(p.getInventory().getHelmet(), SlimefunItems.SCUBA_HELMET, true) || !SlimefunUtils.isItemSimilar(p.getInventory().getChestplate(), SlimefunItems.HAZMAT_CHESTPLATE, true) || !SlimefunUtils.isItemSimilar(p.getInventory().getLeggings(), SlimefunItems.HAZMAT_LEGGINGS, true) || !SlimefunUtils.isItemSimilar(p.getInventory().getBoots(), SlimefunItems.RUBBER_BOOTS, true)) { + private void checkForRadiation(Player p, PlayerProfile profile) { + if (!profile.isProtected(ProtectionType.RADIATION)) { for (ItemStack item : p.getInventory()) { - if (isRadioactive(p, item)) { + if (checkAndApplyRadiation(p, item)) { break; } } } } - private boolean isRadioactive(Player p, ItemStack item) { + private boolean checkAndApplyRadiation(Player p, ItemStack item) { for (SlimefunItem radioactiveItem : SlimefunPlugin.getRegistry().getRadioactiveItems()) { if (radioactiveItem.isItem(item) && Slimefun.isEnabled(p, radioactiveItem, true)) { // If the item is enabled in the world, then make radioactivity do its job @@ -147,5 +147,4 @@ public class ArmorTask implements Runnable { return false; } - } diff --git a/src/main/java/me/mrCookieSlime/Slimefun/SlimefunPlugin.java b/src/main/java/me/mrCookieSlime/Slimefun/SlimefunPlugin.java index df0719e51..0e46652a7 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/SlimefunPlugin.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/SlimefunPlugin.java @@ -23,6 +23,17 @@ import io.github.thebusybiscuit.slimefun4.core.services.github.GitHubService; import io.github.thebusybiscuit.slimefun4.core.services.plugins.ThirdPartyPluginService; import io.github.thebusybiscuit.slimefun4.implementation.listeners.AncientAltarListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.BackpackListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.BlockListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.BlockPhysicsListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.CargoNodeListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.CoolerListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.DeathpointListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.DebugFishListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.DispenserListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.EnhancedFurnaceListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.ExplosionsListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.FireworksListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.GadgetsListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.GrapplingHookListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunBowListener; import io.github.thebusybiscuit.slimefun4.implementation.tasks.TickerTask; @@ -30,7 +41,7 @@ import me.mrCookieSlime.CSCoreLibPlugin.CSCoreLib; /** * @deprecated This class has been moved to {@link io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin} - * + * * @author TheBusyBiscuit * */ diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/SlimefunItemStack.java b/src/main/java/me/mrCookieSlime/Slimefun/api/SlimefunItemStack.java index b0bf9854c..6ea97ce8f 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/SlimefunItemStack.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/SlimefunItemStack.java @@ -244,5 +244,4 @@ public class SlimefunItemStack extends CustomItem { throw new IllegalArgumentException("The provided texture for Item \"" + id + "\" does not seem to be a valid texture String!"); } } - } diff --git a/src/main/resources/languages/messages_en.yml b/src/main/resources/languages/messages_en.yml index 5b5c4ad0a..db8b32017 100644 --- a/src/main/resources/languages/messages_en.yml +++ b/src/main/resources/languages/messages_en.yml @@ -130,6 +130,11 @@ messages: soulbound-rune: fail: '&cYou can only bind one item to your soul at a time.' success: '&aYou have successfully bound this item to your soul! You will keep it when you die.' + + enchantment-rune: + fail: '&cYou cannot enchant this item.' + no-enchantment: '&cCouldn''t find any applicable enchantment for this item.' + success: '&aYou have successfully applied a random applicable enchantment to this item.' research: start: '&7The Ancient Spirits whisper mysterious words into your ear!' diff --git a/src/main/resources/languages/researches_en.yml b/src/main/resources/languages/researches_en.yml index 95f9b4ef1..0aca404dc 100644 --- a/src/main/resources/languages/researches_en.yml +++ b/src/main/resources/languages/researches_en.yml @@ -236,3 +236,4 @@ slimefun: magical_zombie_pills: De-Zombification auto_brewer: Industrial Brewery climbing_pick: Block Raider + enchantment_rune: Ancient Enchanting