From 5b458f1623cca4bf901428a84d964b94f410b101 Mon Sep 17 00:00:00 2001 From: J3fftw <44972470+J3fftw1@users.noreply.github.com> Date: Sat, 8 Jul 2023 18:10:21 +0200 Subject: [PATCH] Cumulative Armor-Scheduling changes (Rainbow Armor + Radiation update) (#3892) * armor task continuation * added empty line * requested changes * Dirty bandage fix armor not working in creative * rainbow armor clean up * fixed radiation - not sure if this is the intended way * ugly fix * clean up * requested changes * import order * made tiny uranium radiactive * requested changes * missed import from comment * made it gold * requested changes and actually make solar helmet work * requested cahnges --- .../slimefun4/api/items/HashedArmorpiece.java | 4 +- .../core/attributes/RadiationSymptom.java | 69 ++++++++++++++++ .../core/attributes/Radioactivity.java | 32 +++++--- .../slimefun4/implementation/Slimefun.java | 13 ++- .../implementation/SlimefunItems.java | 20 ++--- .../implementation/items/armor/Parachute.java | 2 +- .../items/armor/RainbowArmorPiece.java | 62 +++++++++++++++ .../items/electric/gadgets/JetBoots.java | 2 +- .../items/electric/gadgets/Jetpack.java | 2 +- .../items/electric/gadgets/SolarHelmet.java | 6 +- .../items/magical/BeeWings.java | 2 +- .../items/medical/Medicine.java | 2 + .../items/medical/Vitamins.java | 2 + .../listeners/BeeWingsListener.java | 2 +- .../listeners/GadgetsListener.java | 8 +- .../listeners/RadioactivityListener.java | 28 +++++++ .../implementation/setup/ResearchSetup.java | 1 + .../setup/SlimefunItemSetup.java | 42 +++++++++- .../tasks/armor/AbstractArmorTask.java | 79 +++++++++++++++++++ .../tasks/armor/RadiationTask.java | 77 ++++++++++++++++++ .../tasks/armor/RainbowArmorTask.java | 56 +++++++++++++ .../tasks/armor/SlimefunArmorTask.java | 79 +++++++++++++++++++ .../tasks/armor/SolarHelmetTask.java | 64 +++++++++++++++ .../{ => player}/AbstractPlayerTask.java | 2 +- .../tasks/{ => player}/BeeWingsTask.java | 2 +- .../tasks/{ => player}/InfusedMagnetTask.java | 2 +- .../tasks/{ => player}/JetBootsTask.java | 2 +- .../tasks/{ => player}/JetpackTask.java | 2 +- .../tasks/{ => player}/ParachuteTask.java | 2 +- .../slimefun4/utils/LoreBuilder.java | 2 +- .../slimefun4/utils/RadiationUtils.java | 52 ++++++++++++ src/main/resources/config.yml | 2 + src/main/resources/languages/en/messages.yml | 3 + .../resources/languages/en/researches.yml | 1 + 34 files changed, 682 insertions(+), 44 deletions(-) create mode 100644 src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/RadiationSymptom.java create mode 100644 src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/armor/RainbowArmorPiece.java create mode 100644 src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/RadioactivityListener.java create mode 100644 src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/AbstractArmorTask.java create mode 100644 src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/RadiationTask.java create mode 100644 src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/RainbowArmorTask.java create mode 100644 src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/SlimefunArmorTask.java create mode 100644 src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/SolarHelmetTask.java rename src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/{ => player}/AbstractPlayerTask.java (95%) rename src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/{ => player}/BeeWingsTask.java (97%) rename src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/{ => player}/InfusedMagnetTask.java (96%) rename src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/{ => player}/JetBootsTask.java (95%) rename src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/{ => player}/JetpackTask.java (94%) rename src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/{ => player}/ParachuteTask.java (92%) create mode 100644 src/main/java/io/github/thebusybiscuit/slimefun4/utils/RadiationUtils.java 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 ae31cb93c..92a66e5a2 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 @@ -12,7 +12,7 @@ import org.bukkit.inventory.meta.Damageable; import org.bukkit.inventory.meta.ItemMeta; import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece; -import io.github.thebusybiscuit.slimefun4.implementation.tasks.ArmorTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.armor.SlimefunArmorTask; /** * This class serves as a way of checking whether a {@link Player} has changed their armor @@ -25,7 +25,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.tasks.ArmorTask; * @author TheBusyBiscuit * * @see SlimefunArmorPiece - * @see ArmorTask + * @see SlimefunArmorTask */ public final class HashedArmorpiece { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/RadiationSymptom.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/RadiationSymptom.java new file mode 100644 index 000000000..2c703de40 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/RadiationSymptom.java @@ -0,0 +1,69 @@ +package io.github.thebusybiscuit.slimefun4.core.attributes; + +import javax.annotation.Nonnull; + +import com.google.common.base.Preconditions; + +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; +import io.github.thebusybiscuit.slimefun4.utils.RadiationUtils; + +/** + * An enum of potential radiation symptoms. + * A symptom will be applied when the minExposure + * threshold is reached on the {@link Player}'s + * exposure level. + * When the {@link Player} gets above the minExposure threshold + * the {@link PotionEffect} will be applied. + * + * @author Semisol + * + * @see RadiationUtils + */ +public enum RadiationSymptom { + + SLOW(10, PotionEffectType.SLOW, 3), + WITHER_LOW(25, PotionEffectType.WITHER, 0), + BLINDNESS(50, PotionEffectType.BLINDNESS, 4), + WITHER_HIGH(75, PotionEffectType.WITHER, 3), + IMMINENT_DEATH(100, PotionEffectType.HARM, 49); + + private final int minExposure; + private final PotionEffect potionEffect; + + RadiationSymptom(int minExposure, @Nonnull PotionEffectType type, int level) { + Preconditions.checkNotNull(type, "The effect type cannot be null"); + Preconditions.checkArgument(minExposure > 0, "The minimum exposure must be greater than 0."); + Preconditions.checkArgument(level >= 0, "The status effect level must be non-negative."); + + this.minExposure = minExposure; + this.potionEffect = new PotionEffect(type, Slimefun.getCfg().getOrSetDefault("options.radiation-update-interval", 1) * 20 + 20, level); + } + + /** + * This method applies the symptom to a player. + * + * @param p + * The player + */ + public void apply(@Nonnull Player p) { + Preconditions.checkNotNull(p, "The player cannot be null"); + p.addPotionEffect(potionEffect); + } + + /** + * This method returns if this symptom + * should be applied. + * + * @param exposure + * Exposure level + * + * @return If the symptom should be applied + */ + public boolean shouldApply(int exposure) { + return exposure >= minExposure; + } +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/Radioactivity.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/Radioactivity.java index 3e4bd9f12..1025e1e07 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/Radioactivity.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/Radioactivity.java @@ -2,6 +2,8 @@ package io.github.thebusybiscuit.slimefun4.core.attributes; import javax.annotation.Nonnull; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.armor.RadiationTask; + import org.bukkit.ChatColor; import org.bukkit.entity.Player; @@ -20,41 +22,53 @@ public enum Radioactivity { * This represents a low level of radiation. * It will still cause damage but will take a while before it becomes deadly. */ - LOW(ChatColor.YELLOW), + LOW(ChatColor.YELLOW, 1), /** * This represents a medium level of radiation. * This can be considered the default. */ - MODERATE(ChatColor.YELLOW), + MODERATE(ChatColor.YELLOW, 2), /** * This is a high level of radiation. * It will cause death if the {@link Player} does not act quickly. */ - HIGH(ChatColor.DARK_GREEN), + HIGH(ChatColor.GOLD, 3), /** * A very high level of radiation will be deadly. * The {@link Player} should not take this too lightly... */ - VERY_HIGH(ChatColor.RED), + VERY_HIGH(ChatColor.RED, 5), /** - * This is the deadlies level of radiation. + * This is the deadliest level of radiation. * The {@link Player} has basically no chance to protect themselves in time. * It will cause certain death. */ - VERY_DEADLY(ChatColor.DARK_RED); + VERY_DEADLY(ChatColor.DARK_RED, 10); private final ChatColor color; + private final int exposureModifier; - Radioactivity(@Nonnull ChatColor color) { + Radioactivity(@Nonnull ChatColor color, int exposureModifier) { this.color = color; + this.exposureModifier = exposureModifier; } - @Nonnull - public String getLore() { + /** + * This method returns the amount of exposure applied + * to a player every run of the {@link RadiationTask} + * for this radiation level. + * + * @return The exposure amount applied per run. + */ + public int getExposureModifier() { + return exposureModifier; + } + + public @Nonnull String getLore() { return ChatColor.GREEN + "\u2622" + ChatColor.GRAY + " Radiation level: " + color + toString().replace('_', ' '); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java index bd4618ac1..f1fffb2b8 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java @@ -87,6 +87,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.MiningAndroid import io.github.thebusybiscuit.slimefun4.implementation.listeners.MultiBlockListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.NetworkListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.PlayerProfileListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.RadioactivityListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.SeismicAxeListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunBootsListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunBowListener; @@ -115,7 +116,10 @@ import io.github.thebusybiscuit.slimefun4.implementation.resources.GEOResourcesS import io.github.thebusybiscuit.slimefun4.implementation.setup.PostSetup; import io.github.thebusybiscuit.slimefun4.implementation.setup.ResearchSetup; import io.github.thebusybiscuit.slimefun4.implementation.setup.SlimefunItemSetup; -import io.github.thebusybiscuit.slimefun4.implementation.tasks.ArmorTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.armor.RadiationTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.armor.RainbowArmorTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.armor.SlimefunArmorTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.armor.SolarHelmetTask; import io.github.thebusybiscuit.slimefun4.implementation.tasks.SlimefunStartupTask; import io.github.thebusybiscuit.slimefun4.implementation.tasks.TickerTask; import io.github.thebusybiscuit.slimefun4.integrations.IntegrationsManager; @@ -361,8 +365,10 @@ public final class Slimefun extends JavaPlugin implements SlimefunAddon { // Armor Update Task if (config.getBoolean("options.enable-armor-effects")) { - boolean radioactiveFire = config.getBoolean("options.burn-players-when-radioactive"); - getServer().getScheduler().runTaskTimerAsynchronously(this, new ArmorTask(radioactiveFire), 0L, config.getInt("options.armor-update-interval") * 20L); + new SlimefunArmorTask().schedule(this, config.getInt("options.armor-update-interval") * 20L); + new RadiationTask().schedule(this, config.getInt("options.radiation-update-interval") * 20L); + new RainbowArmorTask().schedule(this, config.getInt("options.rainbow-armor-update-interval") * 20L); + new SolarHelmetTask().schedule(this, config.getInt("options.armor-update-interval")); } // Starting our tasks @@ -644,6 +650,7 @@ public final class Slimefun extends JavaPlugin implements SlimefunAddon { // Item-specific Listeners new CoolerListener(this, (Cooler) SlimefunItems.COOLER.getItem()); new SeismicAxeListener(this, (SeismicAxe) SlimefunItems.SEISMIC_AXE.getItem()); + new RadioactivityListener(this); new AncientAltarListener(this, (AncientAltar) SlimefunItems.ANCIENT_ALTAR.getItem(), (AncientPedestal) SlimefunItems.ANCIENT_PEDESTAL.getItem()); grapplingHookListener.register(this, (GrapplingHook) SlimefunItems.GRAPPLING_HOOK.getItem()); bowListener.register(this); 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 f0bd20081..d65a67bd3 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java @@ -221,7 +221,11 @@ public final class SlimefunItems { public static final SlimefunItemStack GLOWSTONE_CHESTPLATE = new SlimefunItemStack("GLOWSTONE_CHESTPLATE", Material.LEATHER_CHESTPLATE, Color.YELLOW, "&e&lGlowstone Chestplate", "", "&a&oShining like the sun!", "", "&9+ Night Vision"); public static final SlimefunItemStack GLOWSTONE_LEGGINGS = new SlimefunItemStack("GLOWSTONE_LEGGINGS", Material.LEATHER_LEGGINGS, Color.YELLOW, "&e&lGlowstone Leggings", "", "&a&oShining like the sun!", "", "&9+ Night Vision"); public static final SlimefunItemStack GLOWSTONE_BOOTS = new SlimefunItemStack("GLOWSTONE_BOOTS", Material.LEATHER_BOOTS, Color.YELLOW, "&e&lGlowstone Boots", "", "&a&oShining like the sun!", "", "&9+ Night Vision"); - + public static final SlimefunItemStack RAINBOW_LEATHER = new SlimefunItemStack("RAINBOW_LEATHER", Material.RABBIT_HIDE, Color.FUCHSIA, "&dRainbow Leather", "", "&fCan be used to craft rainbow armor"); + public static final SlimefunItemStack RAINBOW_HELMET = new SlimefunItemStack("RAINBOW_HELMET", Material.LEATHER_HELMET, Color.FUCHSIA, "&d&lRainbow Helmet", "", LoreBuilder.RAINBOW); + public static final SlimefunItemStack RAINBOW_CHESTPLATE = new SlimefunItemStack("RAINBOW_CHESTPLATE", Material.LEATHER_CHESTPLATE, Color.FUCHSIA, "&d&lRainbow Chestplate", "", LoreBuilder.RAINBOW); + public static final SlimefunItemStack RAINBOW_LEGGINGS = new SlimefunItemStack("RAINBOW_LEGGINGS", Material.LEATHER_LEGGINGS, Color.FUCHSIA, "&d&lRainbow Leggings", "", LoreBuilder.RAINBOW); + public static final SlimefunItemStack RAINBOW_BOOTS = new SlimefunItemStack("RAINBOW_BOOTS", Material.LEATHER_BOOTS, Color.FUCHSIA, "&d&lRainbow Boots", "", LoreBuilder.RAINBOW); public static final SlimefunItemStack ENDER_HELMET = new SlimefunItemStack("ENDER_HELMET", Material.LEATHER_HELMET, Color.fromRGB(28, 25, 112), "&5&lEnder Helmet", "", "&a&oSometimes its here, sometimes there!"); public static final SlimefunItemStack ENDER_CHESTPLATE = new SlimefunItemStack("ENDER_CHESTPLATE", Material.LEATHER_CHESTPLATE, Color.fromRGB(28, 25, 112), "&5&lEnder Chestplate", "", "&a&oSometimes its here, sometimes there!"); public static final SlimefunItemStack ENDER_LEGGINGS = new SlimefunItemStack("ENDER_LEGGINGS", Material.LEATHER_LEGGINGS, Color.fromRGB(28, 25, 112), "&5&lEnder Leggings", "", "&a&oSometimes its here, sometimes there!"); @@ -419,14 +423,12 @@ public final class SlimefunItems { public static final SlimefunItemStack CRAFTING_MOTOR = new SlimefunItemStack("CRAFTING_MOTOR", HeadTexture.CRAFTING_MOTOR, "&6Crafting Motor", "", "&7Important component of Auto-Crafters"); /* Rainbow blocks */ - private static final String RAINBOW = "&dCycles through all Colors of the Rainbow!"; - public static final SlimefunItemStack RAINBOW_WOOL = new SlimefunItemStack("RAINBOW_WOOL", Material.WHITE_WOOL, "&5Rainbow Wool", "", RAINBOW); - public static final SlimefunItemStack RAINBOW_GLASS = new SlimefunItemStack("RAINBOW_GLASS", Material.WHITE_STAINED_GLASS, "&5Rainbow Glass", "", RAINBOW); - public static final SlimefunItemStack RAINBOW_CLAY = new SlimefunItemStack("RAINBOW_CLAY", Material.WHITE_TERRACOTTA, "&5Rainbow Clay", "", RAINBOW); - public static final SlimefunItemStack RAINBOW_GLASS_PANE = new SlimefunItemStack("RAINBOW_GLASS_PANE", Material.WHITE_STAINED_GLASS_PANE, "&5Rainbow Glass Pane", "", RAINBOW); - public static final SlimefunItemStack RAINBOW_CONCRETE = new SlimefunItemStack("RAINBOW_CONCRETE", Material.WHITE_CONCRETE, "&5Rainbow Concrete", "", RAINBOW); - public static final SlimefunItemStack RAINBOW_GLAZED_TERRACOTTA = new SlimefunItemStack("RAINBOW_GLAZED_TERRACOTTA", Material.WHITE_GLAZED_TERRACOTTA, "&5Rainbow Glazed Terracotta", "", RAINBOW); - + public static final SlimefunItemStack RAINBOW_WOOL = new SlimefunItemStack("RAINBOW_WOOL", Material.WHITE_WOOL, "&5Rainbow Wool", "", LoreBuilder.RAINBOW); + public static final SlimefunItemStack RAINBOW_GLASS = new SlimefunItemStack("RAINBOW_GLASS", Material.WHITE_STAINED_GLASS, "&5Rainbow Glass", "", LoreBuilder.RAINBOW); + public static final SlimefunItemStack RAINBOW_CLAY = new SlimefunItemStack("RAINBOW_CLAY", Material.WHITE_TERRACOTTA, "&5Rainbow Clay", "", LoreBuilder.RAINBOW); + public static final SlimefunItemStack RAINBOW_GLASS_PANE = new SlimefunItemStack("RAINBOW_GLASS_PANE", Material.WHITE_STAINED_GLASS_PANE, "&5Rainbow Glass Pane", "", LoreBuilder.RAINBOW); + public static final SlimefunItemStack RAINBOW_CONCRETE = new SlimefunItemStack("RAINBOW_CONCRETE", Material.WHITE_CONCRETE, "&5Rainbow Concrete", "", LoreBuilder.RAINBOW); + public static final SlimefunItemStack RAINBOW_GLAZED_TERRACOTTA = new SlimefunItemStack("RAINBOW_GLAZED_TERRACOTTA", Material.WHITE_GLAZED_TERRACOTTA, "&5Rainbow Glazed Terracotta", "", LoreBuilder.RAINBOW); /* Seasonal */ private static final String CHRISTMAS = ChatUtils.christmas("[Christmas Edition]"); public static final SlimefunItemStack RAINBOW_WOOL_XMAS = new SlimefunItemStack("RAINBOW_WOOL_XMAS", Material.WHITE_WOOL, "&5Rainbow Wool &7(Christmas)", "", CHRISTMAS); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/armor/Parachute.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/armor/Parachute.java index 8531c43a0..5efec631c 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/armor/Parachute.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/armor/Parachute.java @@ -9,7 +9,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; import io.github.thebusybiscuit.slimefun4.implementation.items.electric.gadgets.Jetpack; -import io.github.thebusybiscuit.slimefun4.implementation.tasks.ParachuteTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.player.ParachuteTask; /** * The {@link Parachute} is a {@link SlimefunItem} that can be equipped as a chestplate. diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/armor/RainbowArmorPiece.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/armor/RainbowArmorPiece.java new file mode 100644 index 000000000..10a5030b5 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/armor/RainbowArmorPiece.java @@ -0,0 +1,62 @@ +package io.github.thebusybiscuit.slimefun4.implementation.items.armor; + +import java.util.Arrays; + +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; + +import org.apache.commons.lang.Validate; +import org.bukkit.Color; +import org.bukkit.DyeColor; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; + +import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; +import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; +import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; +import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag; + +/** + * Represents a {@link SlimefunArmorPiece} with rainbow properties (leather armor changing color). + * + * @author martinbrom + */ +public class RainbowArmorPiece extends SlimefunArmorPiece { + + private final Color[] colors; + + /** + * This creates a new {@link RainbowArmorPiece} from the given arguments. + * + * @param itemGroup The {@link ItemGroup} this {@link RainbowArmorPiece} belongs to + * @param item The {@link SlimefunItemStack} that describes the visual features of our {@link RainbowArmorPiece} + * @param recipeType the {@link RecipeType} that determines how this {@link RainbowArmorPiece} is crafted + * @param recipe An Array representing the recipe of this {@link RainbowArmorPiece} + * @param dyeColors An Array representing the {@link DyeColor}s this {@link RainbowArmorPiece} will cycle between + */ + @ParametersAreNonnullByDefault + public RainbowArmorPiece(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, DyeColor[] dyeColors) { + super(itemGroup, item, recipeType, recipe, new PotionEffect[0]); + + // TODO Change this validation over to our custom validation blocked by https://github.com/baked-libs/dough/pull/184 + Validate.notEmpty(dyeColors, "RainbowArmorPiece colors cannot be empty!"); + + if (!SlimefunTag.LEATHER_ARMOR.isTagged(item.getType())) { + throw new IllegalArgumentException("Rainbow armor needs to be a leather armor piece!"); + } + + colors = Arrays.stream(dyeColors) + .map(DyeColor::getColor) + .toArray(Color[]::new); + } + + /** + * Returns the {@link Color}s this {@link RainbowArmorPiece} cycles between + * + * @return The {@link Color}s of this {@link RainbowArmorPiece} + */ + public @Nonnull Color[] getColors() { + return colors; + } + +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/JetBoots.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/JetBoots.java index 1270c763c..ebd08cc5d 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/JetBoots.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/JetBoots.java @@ -9,7 +9,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; import io.github.thebusybiscuit.slimefun4.core.attributes.Rechargeable; -import io.github.thebusybiscuit.slimefun4.implementation.tasks.JetBootsTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.player.JetBootsTask; /** * {@link JetBoots} allow you to hover for a bit. diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/Jetpack.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/Jetpack.java index 3ffd8915a..a5adefa93 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/Jetpack.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/Jetpack.java @@ -9,7 +9,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; import io.github.thebusybiscuit.slimefun4.core.attributes.Rechargeable; -import io.github.thebusybiscuit.slimefun4.implementation.tasks.JetpackTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.player.JetpackTask; /** * {@link JetBoots} allow you to fly up into the air. diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/SolarHelmet.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/SolarHelmet.java index 1a87d59aa..d864a84c2 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/SolarHelmet.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/gadgets/SolarHelmet.java @@ -15,7 +15,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.items.settings.DoubleRangeSetting; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; import io.github.thebusybiscuit.slimefun4.core.attributes.Rechargeable; -import io.github.thebusybiscuit.slimefun4.implementation.tasks.ArmorTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.armor.SolarHelmetTask; /** * The {@link SolarHelmet} can be worn by {@link Player}. @@ -24,8 +24,8 @@ import io.github.thebusybiscuit.slimefun4.implementation.tasks.ArmorTask; * or holding. * * @author TheBusyBiscuit - * - * @see ArmorTask + * + * @see SolarHelmetTask * @see Rechargeable * */ diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/BeeWings.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/BeeWings.java index 5572eca38..a632c9fac 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/BeeWings.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/BeeWings.java @@ -9,7 +9,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; import io.github.thebusybiscuit.slimefun4.implementation.listeners.BeeWingsListener; -import io.github.thebusybiscuit.slimefun4.implementation.tasks.BeeWingsTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.player.BeeWingsTask; /** * The {@link BeeWings} are a special form of the elytra which gives you a slow falling effect diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Medicine.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Medicine.java index 74109abd2..01d06a79f 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Medicine.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Medicine.java @@ -8,6 +8,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; import io.github.thebusybiscuit.slimefun4.core.handlers.ItemConsumptionHandler; +import io.github.thebusybiscuit.slimefun4.utils.RadiationUtils; public class Medicine extends MedicalSupply { @@ -21,6 +22,7 @@ public class Medicine extends MedicalSupply { return (e, p, item) -> { p.setFireTicks(0); clearNegativeEffects(p); + RadiationUtils.clearExposure(p); heal(p); }; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Vitamins.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Vitamins.java index 874b8f81b..bbd822bda 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Vitamins.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/medical/Vitamins.java @@ -13,6 +13,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler; import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect; +import io.github.thebusybiscuit.slimefun4.utils.RadiationUtils; public class Vitamins extends MedicalSupply { @@ -34,6 +35,7 @@ public class Vitamins extends MedicalSupply { e.cancel(); p.setFireTicks(0); clearNegativeEffects(p); + RadiationUtils.clearExposure(p); heal(p); }; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BeeWingsListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BeeWingsListener.java index f79a74349..987409d56 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BeeWingsListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BeeWingsListener.java @@ -10,7 +10,7 @@ import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.implementation.items.magical.BeeWings; -import io.github.thebusybiscuit.slimefun4.implementation.tasks.BeeWingsTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.player.BeeWingsTask; /** * This {@link Listener} is responsible for the slow falling effect given to the {@link Player} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/GadgetsListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/GadgetsListener.java index 7f5048f83..784f52024 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/GadgetsListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/GadgetsListener.java @@ -15,10 +15,10 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.armor.Parachute; import io.github.thebusybiscuit.slimefun4.implementation.items.electric.gadgets.JetBoots; import io.github.thebusybiscuit.slimefun4.implementation.items.electric.gadgets.Jetpack; import io.github.thebusybiscuit.slimefun4.implementation.items.magical.InfusedMagnet; -import io.github.thebusybiscuit.slimefun4.implementation.tasks.InfusedMagnetTask; -import io.github.thebusybiscuit.slimefun4.implementation.tasks.JetBootsTask; -import io.github.thebusybiscuit.slimefun4.implementation.tasks.JetpackTask; -import io.github.thebusybiscuit.slimefun4.implementation.tasks.ParachuteTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.player.InfusedMagnetTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.player.JetBootsTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.player.JetpackTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.player.ParachuteTask; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; /** diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/RadioactivityListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/RadioactivityListener.java new file mode 100644 index 000000000..f0023ff41 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/RadioactivityListener.java @@ -0,0 +1,28 @@ +package io.github.thebusybiscuit.slimefun4.implementation.listeners; + +import javax.annotation.Nonnull; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.PlayerDeathEvent; + +import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; +import io.github.thebusybiscuit.slimefun4.utils.RadiationUtils; + +/** + * {@link RadioactivityListener} handles radioactivity level resets + * on death + * + * @author Semisol + */ +public class RadioactivityListener implements Listener { + + public RadioactivityListener(@Nonnull Slimefun plugin) { + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + @EventHandler + public void onPlayerDeath(@Nonnull PlayerDeathEvent e) { + RadiationUtils.clearExposure(e.getEntity()); + } +} 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 7d28e044b..a3e394883 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 @@ -288,6 +288,7 @@ public final class ResearchSetup { register("portable_teleporter", 278, "Teleportation from Anywhere", 42, SlimefunItems.PORTABLE_TELEPORTER); register("trident", 279, "Trident", 20, "TRIDENT"); register("farmer_talisman", 280, "Talisman of the Farmer", 18, SlimefunItems.TALISMAN_FARMER); + register("rainbow_armor", 281, "I wanna see the rainbow high in the sky", 22, SlimefunItems.RAINBOW_HELMET, SlimefunItems.RAINBOW_CHESTPLATE, SlimefunItems.RAINBOW_LEGGINGS, SlimefunItems.RAINBOW_BOOTS); } @ParametersAreNonnullByDefault 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 18e87c5db..070fb02d3 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 @@ -6,6 +6,7 @@ import java.util.List; import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; +import org.bukkit.DyeColor; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.inventory.ItemStack; @@ -46,6 +47,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.armor.FarmerShoes import io.github.thebusybiscuit.slimefun4.implementation.items.armor.HazmatArmorPiece; import io.github.thebusybiscuit.slimefun4.implementation.items.armor.LongFallBoots; import io.github.thebusybiscuit.slimefun4.implementation.items.armor.Parachute; +import io.github.thebusybiscuit.slimefun4.implementation.items.armor.RainbowArmorPiece; import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece; import io.github.thebusybiscuit.slimefun4.implementation.items.armor.StomperBoots; import io.github.thebusybiscuit.slimefun4.implementation.items.autocrafters.ArmorAutoCrafter; @@ -433,6 +435,37 @@ public final class SlimefunItemSetup { new PotionEffect[] {new PotionEffect(PotionEffectType.NIGHT_VISION, 600, 0)} }, plugin); + DyeColor[] rainbowArmorColors = { + DyeColor.RED, + DyeColor.ORANGE, + DyeColor.YELLOW, + DyeColor.LIME, + DyeColor.LIGHT_BLUE, + DyeColor.PURPLE, + DyeColor.MAGENTA + }; + + new RainbowArmorPiece(itemGroups.magicalArmor, SlimefunItems.RAINBOW_HELMET, RecipeType.ARMOR_FORGE, + new ItemStack[] { SlimefunItems.RAINBOW_LEATHER, SlimefunItems.RAINBOW_LEATHER, SlimefunItems.RAINBOW_LEATHER, SlimefunItems.RAINBOW_LEATHER, null, SlimefunItems.RAINBOW_LEATHER, null, null, null }, + rainbowArmorColors) + .register(plugin); + + new RainbowArmorPiece(itemGroups.magicalArmor, SlimefunItems.RAINBOW_CHESTPLATE, RecipeType.ARMOR_FORGE, + new ItemStack[] { SlimefunItems.RAINBOW_LEATHER, null, SlimefunItems.RAINBOW_LEATHER, SlimefunItems.RAINBOW_LEATHER, SlimefunItems.RAINBOW_LEATHER, SlimefunItems.RAINBOW_LEATHER, SlimefunItems.RAINBOW_LEATHER, SlimefunItems.RAINBOW_LEATHER, SlimefunItems.RAINBOW_LEATHER }, + rainbowArmorColors) + .register(plugin); + + new RainbowArmorPiece(itemGroups.magicalArmor, SlimefunItems.RAINBOW_LEGGINGS, RecipeType.ARMOR_FORGE, + new ItemStack[] { SlimefunItems.RAINBOW_LEATHER, SlimefunItems.RAINBOW_LEATHER, SlimefunItems.RAINBOW_LEATHER, SlimefunItems.RAINBOW_LEATHER, null, SlimefunItems.RAINBOW_LEATHER, SlimefunItems.RAINBOW_LEATHER, null, SlimefunItems.RAINBOW_LEATHER }, + rainbowArmorColors) + .register(plugin); + + new RainbowArmorPiece(itemGroups.magicalArmor, SlimefunItems.RAINBOW_BOOTS, RecipeType.ARMOR_FORGE, + new ItemStack[] { null, null, null, SlimefunItems.RAINBOW_LEATHER, null, SlimefunItems.RAINBOW_LEATHER, SlimefunItems.RAINBOW_LEATHER, null, SlimefunItems.RAINBOW_LEATHER }, + rainbowArmorColors) + .register(plugin); + + registerArmorSet(itemGroups.armor, SlimefunItems.DAMASCUS_STEEL_INGOT, new ItemStack[] {SlimefunItems.DAMASCUS_STEEL_HELMET, SlimefunItems.DAMASCUS_STEEL_CHESTPLATE, SlimefunItems.DAMASCUS_STEEL_LEGGINGS, SlimefunItems.DAMASCUS_STEEL_BOOTS}, "DAMASCUS_STEEL", false, new PotionEffect[0][0], plugin); registerArmorSet(itemGroups.armor, SlimefunItems.REINFORCED_ALLOY_INGOT, new ItemStack[] {SlimefunItems.REINFORCED_ALLOY_HELMET, SlimefunItems.REINFORCED_ALLOY_CHESTPLATE, SlimefunItems.REINFORCED_ALLOY_LEGGINGS, SlimefunItems.REINFORCED_ALLOY_BOOTS}, "REINFORCED_ALLOY", false, new PotionEffect[0][0], plugin); @@ -973,7 +1006,7 @@ public final class SlimefunItemSetup { new ItemStack[] {SlimefunItems.PULVERIZED_ORE, null, null, null, null, null, null, null, null}) .register(plugin); - new UnplaceableBlock(itemGroups.misc, SlimefunItems.TINY_URANIUM, RecipeType.ORE_CRUSHER, + new RadioactiveItem(itemGroups.misc, Radioactivity.LOW, SlimefunItems.TINY_URANIUM, RecipeType.ORE_CRUSHER, new ItemStack[] {SlimefunItems.PURE_ORE_CLUSTER, null, null, null, null, null, null, null, null}) .register(plugin); @@ -2631,7 +2664,12 @@ public final class SlimefunItemSetup { new ElytraCap(itemGroups.magicalArmor, SlimefunItems.ELYTRA_CAP, RecipeType.ARMOR_FORGE, new ItemStack[] {new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), SlimefunItems.ELYTRA_SCALE, SlimefunItems.ELYTRA_SCALE, SlimefunItems.ELYTRA_SCALE, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.LEATHER_HELMET), new ItemStack(Material.SLIME_BALL)}) .register(plugin); - + + new SlimefunItem(itemGroups.magicalResources, SlimefunItems.RAINBOW_LEATHER, RecipeType.ANCIENT_ALTAR, + new ItemStack[] { new ItemStack(Material.EMERALD), new ItemStack(Material.LEATHER), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.RABBIT_HIDE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.RABBIT_HIDE), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.LEATHER), new ItemStack(Material.EMERALD) }, + new SlimefunItemStack(SlimefunItems.RAINBOW_LEATHER, 4)) + .register(plugin); + new UnplaceableBlock(itemGroups.cargo, SlimefunItems.CRAFTING_MOTOR, RecipeType.ENHANCED_CRAFTING_TABLE, new ItemStack[] {new ItemStack(Material.CRAFTING_TABLE), SlimefunItems.BLISTERING_INGOT_3, new ItemStack(Material.CRAFTING_TABLE), SlimefunItems.REDSTONE_ALLOY, SlimefunItems.CARGO_MOTOR, SlimefunItems.REDSTONE_ALLOY, new ItemStack(Material.CRAFTING_TABLE), SlimefunItems.BLISTERING_INGOT_3, new ItemStack(Material.CRAFTING_TABLE)}, new SlimefunItemStack(SlimefunItems.CRAFTING_MOTOR, 2)) diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/AbstractArmorTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/AbstractArmorTask.java new file mode 100644 index 000000000..179e905f1 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/AbstractArmorTask.java @@ -0,0 +1,79 @@ +package io.github.thebusybiscuit.slimefun4.implementation.tasks.armor; + +import java.util.logging.Level; + +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; + +import com.google.common.base.Preconditions; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; +import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; + +/** + * This is a base class for any ArmorTask, it checks every online player + * and handles any armor functionality. + * + * @author TheBusyBiscuit + * @author martinbrom + * + * @see SlimefunArmorTask + * @see RainbowArmorTask + */ +public abstract class AbstractArmorTask implements Runnable { + + @Override + public final void run() { + for (Player p : Bukkit.getOnlinePlayers()) { + if (!p.isValid() || p.isDead()) { + continue; + } + + PlayerProfile.get(p, profile -> onPlayerTick(p, profile)); + } + + onTick(); + } + + /** + * Schedules this {@link AbstractArmorTask} to run every {@code tickInterval} ticks + * + * @param plugin + * The {@link Slimefun} + * @param tickInterval + * Delay between two "runs" of this task in ticks + */ + public final void schedule(@Nonnull Slimefun plugin, long tickInterval) { + Preconditions.checkNotNull(plugin, "The plugin instance cannot be null!"); + + if (tickInterval < 1) { + tickInterval = 1; + plugin.getLogger().log(Level.WARNING, "The interval for {0} is misconfigured! Received {1}, expected at least 1.", new Object[] { getClass().getSimpleName(), tickInterval }); + } + + plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, this, 0L, tickInterval); + } + + /** + * Method to handle things related to the task itself. + * Called once per tick (per schedule interval). + */ + protected void onTick() { + // Can be overridden as necessary. + } + + /** + * Method to handle behavior for player's armor as a whole. + * It is called once per player. + * + * @param p + * The {@link Player} wearing the armor + * @param profile + * The {@link Player}'s {@link PlayerProfile} + */ + @ParametersAreNonnullByDefault + protected abstract void onPlayerTick(Player p, PlayerProfile profile); +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/RadiationTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/RadiationTask.java new file mode 100644 index 000000000..cab9e0cae --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/RadiationTask.java @@ -0,0 +1,77 @@ +package io.github.thebusybiscuit.slimefun4.implementation.tasks.armor; + +import javax.annotation.ParametersAreNonnullByDefault; + +import org.bukkit.GameMode; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import io.github.bakedlibs.dough.common.ChatColors; +import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; +import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; +import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType; +import io.github.thebusybiscuit.slimefun4.core.attributes.RadiationSymptom; +import io.github.thebusybiscuit.slimefun4.core.attributes.Radioactive; +import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; +import io.github.thebusybiscuit.slimefun4.implementation.items.RadioactiveItem; +import io.github.thebusybiscuit.slimefun4.utils.RadiationUtils; + +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.ComponentBuilder; + +/** + * The {@link RadiationTask} handles radioactivity for + * {@link Radioactive} items. + * + * @author Semisol + */ +public class RadiationTask extends AbstractArmorTask { + + private final RadiationSymptom[] symptoms = RadiationSymptom.values(); + + @Override + @ParametersAreNonnullByDefault + protected void onPlayerTick(Player p, PlayerProfile profile) { + int exposureTotal = 0; + + if (!profile.hasFullProtectionAgainst(ProtectionType.RADIATION) && p.getGameMode() != GameMode.CREATIVE && p.getGameMode() != GameMode.SPECTATOR) { + for (ItemStack item : p.getInventory()) { + if (item == null || item.getType().isAir()) { + continue; + } + SlimefunItem sfItem = SlimefunItem.getByItem(item); + if (sfItem instanceof RadioactiveItem radioactiveItem) { + exposureTotal += item.getAmount() * radioactiveItem.getRadioactivity().getExposureModifier(); + } + } + int exposureLevelBefore = RadiationUtils.getExposure(p); + + if (exposureTotal > 0) { + if (exposureLevelBefore == 0) { + Slimefun.getLocalization().sendMessage(p, "messages.radiation"); + } + + RadiationUtils.addExposure(p, exposureTotal); + } else if (exposureLevelBefore > 0) { + RadiationUtils.removeExposure(p, 1); + } + + int exposureLevelAfter = RadiationUtils.getExposure(p); + + Slimefun.runSync(() -> { + for (RadiationSymptom symptom : symptoms) { + if (symptom.shouldApply(exposureLevelAfter)) { + symptom.apply(p); + } + } + }); + + if (exposureLevelAfter > 0 || exposureLevelBefore > 0) { + String msg = Slimefun.getLocalization().getMessage(p, "actionbar.radiation").replace("%level%", "" + exposureLevelAfter); + BaseComponent[] components = new ComponentBuilder().append(ChatColors.color(msg)).create(); + p.spigot().sendMessage(ChatMessageType.ACTION_BAR, components); + } + } + } +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/RainbowArmorTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/RainbowArmorTask.java new file mode 100644 index 000000000..7df8b7e84 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/RainbowArmorTask.java @@ -0,0 +1,56 @@ +package io.github.thebusybiscuit.slimefun4.implementation.tasks.armor; + +import javax.annotation.ParametersAreNonnullByDefault; + +import org.bukkit.Color; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.LeatherArmorMeta; + +import io.github.thebusybiscuit.slimefun4.api.items.HashedArmorpiece; +import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; +import io.github.thebusybiscuit.slimefun4.implementation.items.armor.RainbowArmorPiece; + +/** + * The {@link RainbowArmorTask} is responsible for handling the change in color of any Rainbow Armor piece. + * + * @author martinbrom + */ +public class RainbowArmorTask extends AbstractArmorTask { + + private long currentColorIndex = 0; + + @Override + protected void onTick() { + currentColorIndex++; + } + + @Override + @ParametersAreNonnullByDefault + protected void onPlayerTick(Player p, PlayerProfile profile) { + for (int i = 0; i < 4; i++) { + ItemStack item = p.getInventory().getArmorContents()[i]; + + if (item != null && item.hasItemMeta()) { + HashedArmorpiece armorPiece = profile.getArmor()[i]; + + armorPiece.getItem().ifPresent(sfArmorPiece -> { + if (sfArmorPiece instanceof RainbowArmorPiece rainbowArmorPiece && rainbowArmorPiece.canUse(p, true)) { + updateRainbowArmor(item, rainbowArmorPiece); + } + }); + } + } + } + + @ParametersAreNonnullByDefault + private void updateRainbowArmor(ItemStack itemStack, RainbowArmorPiece armorPiece) { + Color[] colors = armorPiece.getColors(); + Color newColor = colors[(int) (currentColorIndex % colors.length)]; + + if (itemStack.getItemMeta() instanceof LeatherArmorMeta leatherArmorMeta) { + leatherArmorMeta.setColor(newColor); + itemStack.setItemMeta(leatherArmorMeta); + } + } +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/SlimefunArmorTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/SlimefunArmorTask.java new file mode 100644 index 000000000..ce2184692 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/SlimefunArmorTask.java @@ -0,0 +1,79 @@ +package io.github.thebusybiscuit.slimefun4.implementation.tasks.armor; + +import javax.annotation.ParametersAreNonnullByDefault; + +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; + +import io.github.thebusybiscuit.slimefun4.api.items.HashedArmorpiece; +import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; +import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; +import io.github.thebusybiscuit.slimefun4.core.attributes.Radioactive; +import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; +import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece; + +/** + * The {@link SlimefunArmorTask} is responsible for handling {@link SlimefunArmorPiece} + * + * @author TheBusyBiscuit + * @author martinbrom + * @author Semisol + */ +public class SlimefunArmorTask extends AbstractArmorTask { + + @Override + @ParametersAreNonnullByDefault + protected void onPlayerTick(Player p, PlayerProfile profile) { + ItemStack[] armor = p.getInventory().getArmorContents(); + updateAndHandleArmor(p, armor, profile.getArmor()); + } + + @ParametersAreNonnullByDefault + private void updateAndHandleArmor(Player p, ItemStack[] armor, HashedArmorpiece[] cachedArmor) { + for (int slot = 0; slot < 4; slot++) { + ItemStack item = armor[slot]; + HashedArmorpiece armorPiece = cachedArmor[slot]; + + if (armorPiece.hasDiverged(item)) { + SlimefunItem sfItem = SlimefunItem.getByItem(item); + + if (!(sfItem instanceof SlimefunArmorPiece)) { + // If it isn't actually Armor, then we won't care about it. + sfItem = null; + } + + armorPiece.update(item, sfItem); + } + + if (item != null && armorPiece.getItem().isPresent()) { + Slimefun.runSync(() -> { + SlimefunArmorPiece sfArmorPiece = armorPiece.getItem().get(); + + if (sfArmorPiece.canUse(p, true)) { + onArmorPieceTick(p, sfArmorPiece, item); + } + }); + } + } + } + + /** + * Method to handle behavior for pieces of armor. + * It is called per-player and per piece of armor. + * + * @param p + * The {@link Player} wearing the piece of armor + * @param sfArmorPiece + * {@link SlimefunArmorPiece} Slimefun instance of the piece of armor + * @param armorPiece + * The actual {@link ItemStack} of the armor piece + */ + @ParametersAreNonnullByDefault + protected void onArmorPieceTick(Player p, SlimefunArmorPiece sfArmorPiece, ItemStack armorPiece) { + for (PotionEffect effect : sfArmorPiece.getPotionEffects()) { + p.removePotionEffect(effect.getType()); + p.addPotionEffect(effect); + } + } +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/SolarHelmetTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/SolarHelmetTask.java new file mode 100644 index 000000000..41bd6d23a --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/SolarHelmetTask.java @@ -0,0 +1,64 @@ +package io.github.thebusybiscuit.slimefun4.implementation.tasks.armor; + +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; + +import org.bukkit.World; +import org.bukkit.World.Environment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; + +import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; +import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; +import io.github.thebusybiscuit.slimefun4.core.attributes.Radioactive; +import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; +import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece; +import io.github.thebusybiscuit.slimefun4.implementation.items.electric.gadgets.SolarHelmet; +import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; + +/** + * The {@link SolarHelmetTask} is responsible for handling {@link SolarHelmet} for generating power + * and adding checks for if it has sunlight and if the player is actually wearing it. + * + * @author TheBusyBiscuit + * @author martinbrom + * @author Semisol + */ +public class SolarHelmetTask extends AbstractArmorTask { + + @Override + @ParametersAreNonnullByDefault + protected void onPlayerTick(Player p, PlayerProfile profile) { + if (hasSunlight(p)) { + checkForSolarHelmet(p); + } + } + + private void checkForSolarHelmet(@Nonnull Player p) { + ItemStack helmet = p.getInventory().getHelmet(); + + if (Slimefun.getRegistry().isBackwardsCompatible() && !SlimefunUtils.isItemSimilar(helmet, SlimefunItems.SOLAR_HELMET, true, false)) { + // Performance saver for slow backwards-compatible versions of Slimefun + return; + } + + SlimefunItem item = SlimefunItem.getByItem(helmet); + + if (item instanceof SolarHelmet solarHelmet && item.canUse(p, true)) { + solarHelmet.rechargeItems(p); + } + } + + private boolean hasSunlight(@Nonnull Player p) { + World world = p.getWorld(); + + if (world.getEnvironment() != Environment.NORMAL) { + // The End and Nether have no sunlight + return false; + } + + return (world.getTime() < 12300 || world.getTime() > 23850) && p.getEyeLocation().getBlock().getLightFromSky() == 15; + } +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/AbstractPlayerTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/player/AbstractPlayerTask.java similarity index 95% rename from src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/AbstractPlayerTask.java rename to src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/player/AbstractPlayerTask.java index fd10b184e..03744889b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/AbstractPlayerTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/player/AbstractPlayerTask.java @@ -1,4 +1,4 @@ -package io.github.thebusybiscuit.slimefun4.implementation.tasks; +package io.github.thebusybiscuit.slimefun4.implementation.tasks.player; import javax.annotation.Nonnull; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/BeeWingsTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/player/BeeWingsTask.java similarity index 97% rename from src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/BeeWingsTask.java rename to src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/player/BeeWingsTask.java index 4802aa1f7..662f8c6dc 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/BeeWingsTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/player/BeeWingsTask.java @@ -1,4 +1,4 @@ -package io.github.thebusybiscuit.slimefun4.implementation.tasks; +package io.github.thebusybiscuit.slimefun4.implementation.tasks.player; import javax.annotation.Nonnull; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/InfusedMagnetTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/player/InfusedMagnetTask.java similarity index 96% rename from src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/InfusedMagnetTask.java rename to src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/player/InfusedMagnetTask.java index 102568c06..091f59dde 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/InfusedMagnetTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/player/InfusedMagnetTask.java @@ -1,4 +1,4 @@ -package io.github.thebusybiscuit.slimefun4.implementation.tasks; +package io.github.thebusybiscuit.slimefun4.implementation.tasks.player; import javax.annotation.Nonnull; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/JetBootsTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/player/JetBootsTask.java similarity index 95% rename from src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/JetBootsTask.java rename to src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/player/JetBootsTask.java index c8a3695ea..c11c01184 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/JetBootsTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/player/JetBootsTask.java @@ -1,4 +1,4 @@ -package io.github.thebusybiscuit.slimefun4.implementation.tasks; +package io.github.thebusybiscuit.slimefun4.implementation.tasks.player; import java.util.concurrent.ThreadLocalRandom; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/JetpackTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/player/JetpackTask.java similarity index 94% rename from src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/JetpackTask.java rename to src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/player/JetpackTask.java index 5ecf68c69..40c119943 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/JetpackTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/player/JetpackTask.java @@ -1,4 +1,4 @@ -package io.github.thebusybiscuit.slimefun4.implementation.tasks; +package io.github.thebusybiscuit.slimefun4.implementation.tasks.player; import javax.annotation.Nonnull; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ParachuteTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/player/ParachuteTask.java similarity index 92% rename from src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ParachuteTask.java rename to src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/player/ParachuteTask.java index 5d70622de..94382753d 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ParachuteTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/player/ParachuteTask.java @@ -1,4 +1,4 @@ -package io.github.thebusybiscuit.slimefun4.implementation.tasks; +package io.github.thebusybiscuit.slimefun4.implementation.tasks.player; import javax.annotation.Nonnull; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/LoreBuilder.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/LoreBuilder.java index a57f5532b..6a3a67cc9 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/LoreBuilder.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/LoreBuilder.java @@ -24,7 +24,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; public final class LoreBuilder { public static final String HAZMAT_SUIT_REQUIRED = "&8\u21E8 &4Hazmat Suit required!"; - + public static final String RAINBOW = "&dCycles through all Colors of the Rainbow!"; public static final String RIGHT_CLICK_TO_USE = "&eRight Click&7 to use"; public static final String RIGHT_CLICK_TO_OPEN = "&eRight Click&7 to open"; public static final String CROUCH_TO_USE = "&eCrouch&7 to use"; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/RadiationUtils.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/RadiationUtils.java new file mode 100644 index 000000000..a9883b4a5 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/RadiationUtils.java @@ -0,0 +1,52 @@ +package io.github.thebusybiscuit.slimefun4.utils; + +import javax.annotation.Nonnull; + +import com.google.common.base.Preconditions; + +import org.bukkit.NamespacedKey; +import org.bukkit.entity.Player; + +import io.github.thebusybiscuit.slimefun4.api.player.StatusEffect; +import io.github.thebusybiscuit.slimefun4.core.attributes.RadiationSymptom; +import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; + +/** + * This class is a basic wrapper around the + * status effect. + * + * @author Semisol + * + * @see RadiationSymptom + */ +public final class RadiationUtils { + + private static final StatusEffect RADIATION_EFFECT = new StatusEffect(new NamespacedKey(Slimefun.instance(), "radiation")); + private static final int MAX_EXPOSURE_LEVEL = 100; + + public static void clearExposure(@Nonnull Player p) { + Preconditions.checkNotNull(p, "The player cannot be null"); + + RADIATION_EFFECT.clear(p); + } + + public static int getExposure(@Nonnull Player p) { + Preconditions.checkNotNull(p, "The player must not be null"); + + return RADIATION_EFFECT.getLevel(p).orElse(0); + } + + public static void addExposure(@Nonnull Player p, int exposure) { + Preconditions.checkNotNull(p, "The player cannot be null"); + + int level = Math.min(RADIATION_EFFECT.getLevel(p).orElse(0) + exposure, MAX_EXPOSURE_LEVEL); + RADIATION_EFFECT.addPermanent(p, level); + } + + public static void removeExposure(@Nonnull Player p, int exposure) { + Preconditions.checkNotNull(p, "The player should not be null"); + + int level = Math.max(RADIATION_EFFECT.getLevel(p).orElse(0) - exposure, 0); + RADIATION_EFFECT.addPermanent(p, level); + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 04815081f..df41bf721 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -9,6 +9,8 @@ options: chat-prefix: '&a&lSlimefun 4&7> ' armor-update-interval: 10 enable-armor-effects: true + radiation-update-interval: 1 + rainbow-armor-update-interval: 3 auto-save-delay-in-minutes: 10 legacy-ore-washer: false legacy-dust-washer: false diff --git a/src/main/resources/languages/en/messages.yml b/src/main/resources/languages/en/messages.yml index c678a28c2..f9c32a811 100644 --- a/src/main/resources/languages/en/messages.yml +++ b/src/main/resources/languages/en/messages.yml @@ -145,6 +145,9 @@ guide: resourcepack: '&cResourcepack Artist' translator: '&9Translator' +actionbar: + radiation: '&6Radiation Exposure Level: &c%level%&7/&e100' + messages: not-researched: '&4You do not have enough knowledge to understand this. &cYou will need to unlock &f"%item%&f"' not-enough-xp: '&4You do not have enough XP to unlock this' diff --git a/src/main/resources/languages/en/researches.yml b/src/main/resources/languages/en/researches.yml index e6b027e92..6579ac26e 100644 --- a/src/main/resources/languages/en/researches.yml +++ b/src/main/resources/languages/en/researches.yml @@ -258,3 +258,4 @@ slimefun: medium_tier_auto_enchanting: Fast Automatic Enchanting and Disenchanting portable_teleporter: Teleportation from Anywhere farmer_talisman: Talisman of the Farmer + rainbow_armor: I wanna see the rainbow high in the sky