diff --git a/CHANGELOG.md b/CHANGELOG.md index 99252737f..20b3c4609 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,7 +31,10 @@ * Added a config option for Grappling Hooks to not be consumed on use * Added Talisman of the Caveman * You can now convert any gold ingot into gold dust with slightly less returns +* Magical Zombie Pills now also work on Zombified Piglins * (API) Added SlimefunGuideOpenEvent +* (API) Added "NotConfigurable" attribute to disable configurability +* Added Elytra Cap #### Changes * Improved Auto-Updater (Multi-Threading and more) @@ -58,6 +61,9 @@ * Fixed #2357 * Fixed Auto Enchanters being unaffected by speed modifications from addons * Fixed Auto Disenchanters being unaffected by speed modifications from addons +* Fixed radioactive items still being radioactive when disabled +* Fixed #2391 +* Fixed #2403 ## Release Candidate 16 (07 Sep 2020) https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#16 diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/NotConfigurable.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/NotConfigurable.java new file mode 100644 index 000000000..8d52d32c7 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/NotConfigurable.java @@ -0,0 +1,14 @@ +package io.github.thebusybiscuit.slimefun4.core.attributes; + +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; + +/** + * Implement this interface for any {@link SlimefunItem} to prevent + * that {@link SlimefunItem} from showing up in the {@code Items.yml} config file. + * + * @author TheBusyBiscuit + * + */ +public interface NotConfigurable { + +} 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 index df48ca2eb..bb2fd0a17 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/ProtectionType.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/ProtectionType.java @@ -21,6 +21,11 @@ public enum ProtectionType { /** * This damage type represents damage caused by a {@link Bee} */ - BEES; + BEES, + + /** + * This damage type represents damage caused by flying into a wall with an elytra + */ + FLYING_INTO_WALL; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/SlimefunCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/SlimefunCommand.java index 8fd253456..5bbc09820 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/SlimefunCommand.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/SlimefunCommand.java @@ -83,7 +83,10 @@ public class SlimefunCommand implements CommandExecutor, Listener { sendHelp(sender); - return true; + // We could just return true here, but if there's no subcommands, then + // something went horribly wrong anyway. This will also stop sonarcloud + // from nagging about this always returning true... + return !commands.isEmpty(); } public void sendHelp(@Nonnull CommandSender sender) { 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 4022d4d77..2ed7ebbf5 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java @@ -56,6 +56,7 @@ public final class SlimefunItems { public static final SlimefunItemStack REINFORCED_CLOTH = new SlimefunItemStack("REINFORCED_CLOTH", Material.PAPER, "&bReinforced Cloth", "", "&fThis cloth has been reinforced", "&fwith &bLead &fto protect against", "&fradioactive substances"); public static final SlimefunItemStack TIN_CAN = new SlimefunItemStack("CAN", HeadTexture.TIN_CAN, "&fTin Can"); public static final SlimefunItemStack NIGHT_VISION_GOGGLES = new SlimefunItemStack("NIGHT_VISION_GOGGLES", Material.LEATHER_HELMET, Color.BLACK, "&aNight Vision Goggles", "", "&9+ Night Vision"); + public static final SlimefunItemStack ELYTRA_CAP = new SlimefunItemStack("ELYTRA_CAP", Material.LEATHER_HELMET, Color.PURPLE, "&5Elytra Cap", "", "&7This helmet will protect you from", "&7crashing while flying with an elytra."); public static final SlimefunItemStack FARMER_SHOES = new SlimefunItemStack("FARMER_SHOES", Material.LEATHER_BOOTS, Color.YELLOW, "&eFarmer Shoes", "", "&6&oPrevents you from trampling your Crops"); public static final SlimefunItemStack INFUSED_MAGNET = new SlimefunItemStack("INFUSED_MAGNET", HeadTexture.MAGNET, "&aInfused Magnet", "", "&fMagical infused Magnets", "&fattract nearby Items", "&fas long as it is somewhere in", "&fyour Inventory", "", "&7Hold &eShift&7 to pick up nearby Items"); public static final SlimefunItemStack RAG = new SlimefunItemStack("RAG", Material.PAPER, "&cRag", "", "&aLevel I - Medical Supply", "", "&fRestores 2 Hearts", "&fExtinguishes Fire", "", LoreBuilder.RIGHT_CLICK_TO_USE); @@ -63,7 +64,7 @@ public final class SlimefunItems { public static final SlimefunItemStack SPLINT = new SlimefunItemStack("SPLINT", Material.STICK, "&cSplint", "", "&aLevel I - Medical Supply", "", "&fRestores 2 Hearts", "", LoreBuilder.RIGHT_CLICK_TO_USE); public static final SlimefunItemStack VITAMINS = new SlimefunItemStack("VITAMINS", Material.NETHER_WART, "&cVitamins", "", "&aLevel III - Medical Supply", "", "&fRestores 4 Hearts", "&fExtinguishes Fire", "&fCures Poison/Wither/Radiation", "", LoreBuilder.RIGHT_CLICK_TO_USE); public static final SlimefunItemStack MEDICINE = new SlimefunItemStack("MEDICINE", Material.POTION, Color.RED, "&cMedicine", "", "&aLevel III - Medical Supply", "", "&fRestores 4 Hearts", "&fExtinguishes Fire", "&fCures Poison/Wither/Radiation"); - 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_ZOMBIE_PILLS = new SlimefunItemStack("MAGICAL_ZOMBIE_PILLS", Material.NETHER_WART, "&6Magical Zombie Pills", "", "&eRight Click &7a Zombified Villager", "&eor &7a Zombified Piglin to", "&7instantly cure it from its curse"); public static final SlimefunItemStack FLASK_OF_KNOWLEDGE = new SlimefunItemStack("FLASK_OF_KNOWLEDGE", Material.GLASS_BOTTLE, "&cFlask of Knowledge", "", "&fAllows you to store some of", "&fyour Experience in a Bottle", "&7Cost: &a1 Level"); public static final SlimefunItemStack FILLED_FLASK_OF_KNOWLEDGE = new SlimefunItemStack("FILLED_FLASK_OF_KNOWLEDGE", Material.EXPERIENCE_BOTTLE, "&aFlask of Knowledge"); 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 ab0b9e2d0..0a237ef2a 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java @@ -63,6 +63,7 @@ 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.ElytraCrashListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.DeathpointListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.DebugFishListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.DispenserListener; @@ -453,6 +454,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { new EntityInteractionListener(this); new MobDropListener(this); new VillagerTradingListener(this); + new ElytraCrashListener(this); if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_15)) { new BeeListener(this); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/armor/ElytraCap.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/armor/ElytraCap.java new file mode 100644 index 000000000..cdeef8ca3 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/armor/ElytraCap.java @@ -0,0 +1,56 @@ +package io.github.thebusybiscuit.slimefun4.implementation.items.armor; + +import io.github.thebusybiscuit.slimefun4.core.attributes.DamageableItem; +import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType; +import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectiveArmor; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.ElytraCrashListener; +import me.mrCookieSlime.Slimefun.Lists.RecipeType; +import me.mrCookieSlime.Slimefun.Objects.Category; +import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; +import org.bukkit.NamespacedKey; +import org.bukkit.inventory.ItemStack; + +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; + +/** + * The {@link ElytraCap} negates damage taken when crashing into a wall using an elytra. + * + * @author Seggan + * + * @see ElytraCrashListener + */ +public class ElytraCap extends SlimefunArmorPiece implements DamageableItem, ProtectiveArmor { + + private final NamespacedKey key; + + @ParametersAreNonnullByDefault + public ElytraCap(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { + super(category, item, recipeType, recipe, null); + + key = new NamespacedKey(SlimefunPlugin.instance(), "elytra_armor"); + } + + @Override + public boolean isDamageable() { + return true; + } + + @Nonnull + @Override + public ProtectionType[] getProtectionTypes() { + return new ProtectionType[] {ProtectionType.FLYING_INTO_WALL}; + } + + @Override + public boolean isFullSetRequired() { + return false; + } + + @Nonnull + @Override + public NamespacedKey getArmorSetId() { + return key; + } +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/MagicalZombiePills.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/MagicalZombiePills.java index 775a970bd..5d114ee63 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/MagicalZombiePills.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/MagicalZombiePills.java @@ -1,9 +1,13 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.magical; +import javax.annotation.Nonnull; + import org.bukkit.GameMode; +import org.bukkit.Location; import org.bukkit.Sound; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; +import org.bukkit.entity.PigZombie; import org.bukkit.entity.Player; import org.bukkit.entity.Villager; import org.bukkit.entity.ZombieVillager; @@ -46,22 +50,15 @@ public class MagicalZombiePills extends SimpleSlimefunItem { Entity entity = e.getRightClicked(); + Player p = e.getPlayer(); - if (entity.getType() == EntityType.ZOMBIE_VILLAGER) { - Player p = e.getPlayer(); - - if (p.getGameMode() != GameMode.CREATIVE) { - ItemUtils.consumeItem(item, false); - } - - p.playSound(p.getLocation(), Sound.ENTITY_ZOMBIE_VILLAGER_CONVERTED, 1, 1); - - ZombieVillager zombieVillager = (ZombieVillager) entity; - zombieVillager.setConversionTime(1); - - if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_15)) { - zombieVillager.setConversionPlayer(p); - } + if (entity instanceof ZombieVillager) { + useItem(p); + healZombieVillager((ZombieVillager) entity, p); + } + else if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16) && entity instanceof PigZombie) { + useItem(p); + healZombifiedPiglin((PigZombie) entity); } }; } @@ -74,4 +71,27 @@ public class MagicalZombiePills extends SimpleSlimefunItem { private final ItemSetting consumeOnUse = new ItemSetting<>("consume-on-use", true); private final ItemSetting despawnTicks = new ItemSetting<>("despawn-seconds", 60); + @ParametersAreNonnullByDefault public GrapplingHook(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { super(category, item, recipeType, recipe); @@ -37,7 +53,7 @@ public class GrapplingHook extends SimpleSlimefunItem { return e -> { Player p = e.getPlayer(); UUID uuid = p.getUniqueId(); - boolean consumeOnUseValue = consumeOnUse.getValue(); + boolean isConsumed = consumeOnUse.getValue(); if (!e.getClickedBlock().isPresent() && !SlimefunPlugin.getGrapplingHookListener().isGrappling(uuid)) { e.cancel(); @@ -49,11 +65,9 @@ public class GrapplingHook extends SimpleSlimefunItem { ItemStack item = e.getItem(); - if (item.getType() == Material.LEAD) { - //If consume on use is enabled, the if statement below will take 1 grappling hook out of player's hand - if (consumeOnUseValue) { - item.setAmount(item.getAmount() - 1); - } + if (item.getType() == Material.LEAD && isConsumed) { + // If consume on use is enabled, consume one item + ItemUtils.consumeItem(item, false); } Vector direction = p.getEyeLocation().getDirection().multiply(2.0); @@ -69,7 +83,7 @@ public class GrapplingHook extends SimpleSlimefunItem { bat.setLeashHolder(arrow); boolean state = item.getType() != Material.SHEARS; - SlimefunPlugin.getGrapplingHookListener().addGrapplingHook(p, arrow, bat, state, despawnTicks.getValue(), consumeOnUseValue); + SlimefunPlugin.getGrapplingHookListener().addGrapplingHook(p, arrow, bat, state, despawnTicks.getValue(), isConsumed); } }; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/TapeMeasure.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/TapeMeasure.java index c9fb3cd54..d4a6bb326 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/TapeMeasure.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/TapeMeasure.java @@ -76,7 +76,6 @@ public class TapeMeasure extends SimpleSlimefunItem implements N SlimefunPlugin.getLocalization().sendMessage(p, "messages.tape-measure.anchor-set", msg -> msg.replace("%anchor%", anchor)); item.setItemMeta(meta); - } @Nonnull diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/ElytraCrashListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/ElytraCrashListener.java new file mode 100644 index 000000000..d01992c45 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/ElytraCrashListener.java @@ -0,0 +1,63 @@ +package io.github.thebusybiscuit.slimefun4.implementation.listeners; + +import io.github.thebusybiscuit.slimefun4.api.items.HashedArmorpiece; +import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; +import io.github.thebusybiscuit.slimefun4.core.attributes.DamageableItem; +import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType; +import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectiveArmor; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +import io.github.thebusybiscuit.slimefun4.implementation.items.armor.ElytraCap; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; +import me.mrCookieSlime.Slimefun.api.Slimefun; +import org.bukkit.GameMode; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.inventory.ItemStack; + +import javax.annotation.Nonnull; +import java.util.Arrays; +import java.util.Optional; + +/** + * The {@link Listener} for the {@link ElytraCap}. + * + * @author Seggan + */ +public class ElytraCrashListener implements Listener { + + public ElytraCrashListener(@Nonnull SlimefunPlugin plugin) { + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + @EventHandler + public void onPlayerCrash(EntityDamageEvent e) { + if (!(e.getEntity() instanceof Player)) return; + if (!(e.getCause() == EntityDamageEvent.DamageCause.FALL || + e.getCause() == EntityDamageEvent.DamageCause.FLY_INTO_WALL)) return; + + Player p = (Player) e.getEntity(); + if (p.isGliding()) { + Optional optional = PlayerProfile.find(p); + if (!optional.isPresent()) { + PlayerProfile.request(p); + return; + } + PlayerProfile profile = optional.get(); + HashedArmorpiece helmet = profile.getArmor()[0]; + if (helmet.getItem().isPresent()) { + SlimefunItem item = helmet.getItem().get(); + if (Slimefun.hasUnlocked(p, item, true) + && profile.hasFullProtectionAgainst(ProtectionType.FLYING_INTO_WALL)) { + e.setDamage(0); + p.playSound(p.getLocation(), Sound.BLOCK_STONE_HIT, 20, 1); + if (p.getGameMode() != GameMode.CREATIVE && item instanceof DamageableItem) { + ((DamageableItem) item).damageItem(p, p.getInventory().getHelmet()); + } + } + } + } + } +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/GrapplingHookEntity.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/GrapplingHookEntity.java index 57cfa4c9b..f4572f3a4 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/GrapplingHookEntity.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/GrapplingHookEntity.java @@ -33,12 +33,10 @@ final class GrapplingHookEntity { } public void drop(@Nonnull Location l) { - if (dropItem) { - //If a grappling hook was consumed, then the below if statement will be executed and will drop one grappling hook on the floor - if (wasConsumed) { - Item item = l.getWorld().dropItem(l, SlimefunItems.GRAPPLING_HOOK.clone()); - item.setPickupDelay(16); - } + // If a grappling hook was consumed, drop one grappling hook on the floor + if (dropItem && wasConsumed) { + Item item = l.getWorld().dropItem(l, SlimefunItems.GRAPPLING_HOOK.clone()); + item.setPickupDelay(16); } } 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 a2b5d0331..e282f7532 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 @@ -276,8 +276,9 @@ public final class ResearchSetup { register("climbing_pick", 265, "Block Raider", 20, SlimefunItems.CLIMBING_PICK); register("even_higher_tier_capacitors", 266, "Tier 3 Capacitors", 40, SlimefunItems.ENERGIZED_CAPACITOR); register("caveman_talisman", 267, "Talisman of the Caveman", 20, SlimefunItems.TALISMAN_CAVEMAN); - register("wise_talisman", 268, "Talisman of the Wise", 20, SlimefunItems.TALISMAN_WISE); - register("resurrected_talisman", 269, "Talisman of the Resurrected", 20, SlimefunItems.TALISMAN_RESURRECTED); + register("elytra_cap", 268, "Crash Gear", 20, SlimefunItems.ELYTRA_CAP); + register("wise_talisman", 269, "Talisman of the Wise", 20, SlimefunItems.TALISMAN_WISE); + register("resurrected_talisman", 270, "Talisman of the Resurrected", 20, SlimefunItems.TALISMAN_RESURRECTED); } 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 d2c723dd1..f3343cf2f 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 @@ -39,6 +39,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.armor.HazmatArmor 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.armor.StomperBoots; +import io.github.thebusybiscuit.slimefun4.implementation.items.armor.ElytraCap; import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler; import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.EnderBackpack; import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.RestoredBackpack; @@ -1127,6 +1128,10 @@ public final class SlimefunItemSetup { new ItemStack[] {SlimefunItems.NICKEL_INGOT, SlimefunItems.ALUMINUM_DUST, SlimefunItems.IRON_DUST, SlimefunItems.COBALT_INGOT, null, null, null, null, null}) .register(plugin); + new ElytraCap(categories.magicalGadgets, 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 InfusedMagnet(categories.magicalGadgets, SlimefunItems.INFUSED_MAGNET, RecipeType.MAGIC_WORKBENCH, new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.ENDER_LUMP_2, SlimefunItems.MAGNET, SlimefunItems.ENDER_LUMP_2, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}) .register(plugin); diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java index 1800613fa..ca4f39e17 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java @@ -8,6 +8,7 @@ import java.util.Optional; import java.util.Set; import java.util.function.Consumer; import java.util.logging.Level; +import java.util.logging.Logger; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -30,6 +31,7 @@ import io.github.thebusybiscuit.slimefun4.api.exceptions.UnregisteredItemExcepti import io.github.thebusybiscuit.slimefun4.api.exceptions.WrongItemStackException; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.ItemState; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotConfigurable; import io.github.thebusybiscuit.slimefun4.core.attributes.Placeable; import io.github.thebusybiscuit.slimefun4.core.attributes.Radioactive; import io.github.thebusybiscuit.slimefun4.core.attributes.Rechargeable; @@ -360,15 +362,18 @@ public class SlimefunItem implements Placeable { SlimefunPlugin.getRegistry().getAllSlimefunItems().add(this); SlimefunPlugin.getRegistry().getSlimefunItemIds().put(id, this); - SlimefunPlugin.getItemCfg().setDefaultValue(id + ".enabled", true); - SlimefunPlugin.getItemCfg().setDefaultValue(id + ".can-be-used-in-workbenches", useableInWorkbench); - SlimefunPlugin.getItemCfg().setDefaultValue(id + ".hide-in-guide", hidden); - SlimefunPlugin.getItemCfg().setDefaultValue(id + ".allow-enchanting", enchantable); - SlimefunPlugin.getItemCfg().setDefaultValue(id + ".allow-disenchanting", disenchantable); + // Items that are "not-configurable" cannot be configured. + if (!(this instanceof NotConfigurable)) { + SlimefunPlugin.getItemCfg().setDefaultValue(id + ".enabled", true); + SlimefunPlugin.getItemCfg().setDefaultValue(id + ".can-be-used-in-workbenches", useableInWorkbench); + SlimefunPlugin.getItemCfg().setDefaultValue(id + ".hide-in-guide", hidden); + SlimefunPlugin.getItemCfg().setDefaultValue(id + ".allow-enchanting", enchantable); + SlimefunPlugin.getItemCfg().setDefaultValue(id + ".allow-disenchanting", disenchantable); - // Load all item settings - for (ItemSetting setting : itemSettings) { - setting.load(this); + // Load all item settings + for (ItemSetting setting : itemSettings) { + setting.load(this); + } } if (ticking && !SlimefunPlugin.getCfg().getBoolean("URID.enable-tickers")) { @@ -376,26 +381,17 @@ public class SlimefunItem implements Placeable { return; } - if (this instanceof Radioactive) { - SlimefunPlugin.getRegistry().getRadioactiveItems().add(this); - } - - if (SlimefunPlugin.getItemCfg().getBoolean(id + ".enabled")) { - - if (!category.isRegistered()) { - category.register(); - } - + if (this instanceof NotConfigurable) { + // Not-configurable items will be enabled. + // Any other settings will remain as default. + state = ItemState.ENABLED; + } + else if (SlimefunPlugin.getItemCfg().getBoolean(id + ".enabled")) { state = ItemState.ENABLED; - checkForDeprecations(getClass()); - useableInWorkbench = SlimefunPlugin.getItemCfg().getBoolean(id + ".can-be-used-in-workbenches"); hidden = SlimefunPlugin.getItemCfg().getBoolean(id + ".hide-in-guide"); enchantable = SlimefunPlugin.getItemCfg().getBoolean(id + ".allow-enchanting"); disenchantable = SlimefunPlugin.getItemCfg().getBoolean(id + ".allow-disenchanting"); - - SlimefunPlugin.getRegistry().getEnabledSlimefunItems().add(this); - loadItemHandlers(); } else if (this instanceof VanillaItem) { state = ItemState.VANILLA_FALLBACK; @@ -404,19 +400,43 @@ public class SlimefunItem implements Placeable { state = ItemState.DISABLED; } + // Now we can be certain this item should be enabled + if (state == ItemState.ENABLED) { + // Register the Category too if it hasn't been registered yet + if (!category.isRegistered()) { + category.register(); + } + + // Send out deprecation warnings for any classes or intefaces + checkForDeprecations(getClass()); + + // Add it to the list of enabled items + SlimefunPlugin.getRegistry().getEnabledSlimefunItems().add(this); + + // Load our Item Handlers + loadItemHandlers(); + + // Properly mark this Item as radioactive + if (this instanceof Radioactive) { + SlimefunPlugin.getRegistry().getRadioactiveItems().add(this); + } + } + + // Lock the SlimefunItemStack from any accidental manipulations if (item instanceof SlimefunItemStack && isItemStackImmutable()) { ((SlimefunItemStack) item).lock(); } postRegister(); + // handle runtime-registrations / auto-loading if (SlimefunPlugin.getRegistry().isAutoLoadingEnabled() && state == ItemState.ENABLED) { info("Item was registered during runtime."); load(); } } catch (Exception x) { - error("Registering " + toString() + " has failed", x); + error("Registering " + toString() + " has failed!", x); } } @@ -464,7 +484,7 @@ public class SlimefunItem implements Placeable { * @param c * The {@link Class} from which to start this operation. */ - private void checkForDeprecations(Class c) { + private void checkForDeprecations(@Nullable Class c) { if (SlimefunPlugin.getUpdater().getBranch() == SlimefunBranch.DEVELOPMENT) { // This method is currently way too spammy with all the restructuring going on... // Since DEV builds are anyway under "development", things may be relocated. @@ -526,6 +546,12 @@ public class SlimefunItem implements Placeable { this.recipeType = type; } + /** + * This sets the {@link Category} in which this {@link SlimefunItem} will be displayed. + * + * @param category + * The new {@link Category} + */ public void setCategory(@Nonnull Category category) { Validate.notNull(category, "The Category is not allowed to be null!"); @@ -590,6 +616,7 @@ public class SlimefunItem implements Placeable { return false; } + // If the given item is a SlimefunitemStack, simply compare the id if (item instanceof SlimefunItemStack) { return getID().equals(((SlimefunItemStack) item).getItemId()); } @@ -670,6 +697,10 @@ public class SlimefunItem implements Placeable { throw new UnsupportedOperationException("You cannot add an ItemSetting after the SlimefunItem was registered."); } + if (this instanceof NotConfigurable) { + throw new UnsupportedOperationException("This Item has been marked as NotConfigurable and cannot accept Item Settings!"); + } + for (ItemSetting setting : settings) { if (setting != null) { // Prevent two Item Settings with the same key @@ -817,12 +848,28 @@ public class SlimefunItem implements Placeable { return getDrops(); } - public void info(String message) { + /** + * This will send an info message to the console and signal that this message came + * from this {@link SlimefunItem}, the message will be sent using the {@link Logger} + * of the {@link SlimefunAddon} which registered this {@link SlimefunItem}. + * + * @param message + * The message to send + */ + public void info(@Nonnull String message) { String msg = toString() + ": " + message; addon.getLogger().log(Level.INFO, msg); } - public void warn(String message) { + /** + * This will send a warning to the console and signal that this warning came from + * this {@link SlimefunItem}, the warning will be sent using the {@link Logger} + * of the {@link SlimefunAddon} which registered this {@link SlimefunItem}. + * + * @param message + * The message to send + */ + public void warn(@Nonnull String message) { String msg = toString() + ": " + message; addon.getLogger().log(Level.WARNING, msg); @@ -841,7 +888,7 @@ public class SlimefunItem implements Placeable { * @param throwable * The {@link Throwable} to throw as a stacktrace. */ - public void error(String message, Throwable throwable) { + public void error(@Nonnull String message, @Nonnull Throwable throwable) { addon.getLogger().log(Level.SEVERE, "Item \"{0}\" from {1} v{2} has caused an Error!", new Object[] { id, addon.getName(), addon.getPluginVersion() }); if (addon.getBugTrackerURL() != null) { diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/DirtyChestMenu.java b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/DirtyChestMenu.java index 20fda5505..86696d817 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/DirtyChestMenu.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/DirtyChestMenu.java @@ -128,6 +128,7 @@ public class DirtyChestMenu extends ChestMenu { if (ItemUtils.canStack(wrapper, stack)) { amount -= (stack.getMaxStackSize() - stack.getAmount()); stack.setAmount(Math.min(stack.getAmount() + item.getAmount(), stack.getMaxStackSize())); + item.setAmount(amount); } } } diff --git a/src/main/resources/languages/researches_en.yml b/src/main/resources/languages/researches_en.yml index 4e8502905..d660c78fb 100644 --- a/src/main/resources/languages/researches_en.yml +++ b/src/main/resources/languages/researches_en.yml @@ -246,3 +246,4 @@ slimefun: tape_measure: Tape Measure iron_golem_assembler: Automated Iron Golems villager_rune: Reset Villager Trades + elytra_cap: Crash Gear