diff --git a/CHANGELOG.md b/CHANGELOG.md index 68fd2794e..310bca48b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,7 +48,8 @@ ## Release Candidate 11 (TBD) #### Additions -* Added experimental 1.13 backwards compatibility +* Added GEOResourceGenerationEvent +* Added SlimefunGuide-Options API #### Changes diff --git a/README.md b/README.md index 5e41b65dc..fbb6c57a4 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Here is a full summary of the differences between these two versions of Slimefun | | development builds | "stable" builds | | ------------------ | -------- | -------- | -| **Supported Minecraft version(s)** | 1.14.X - 1.15.X | 1.14.X - 1.15.X | +| **Supported Minecraft version(s)** | 1.13.X - 1.15.X | 1.14.X - 1.15.X | | **extensive testing before release** | :x: | :heavy_check_mark: | | **latest content** | :heavy_check_mark: | :x: | | **Discord support** | :heavy_check_mark: | :x: | diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/GEOResourceGenerationEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/GEOResourceGenerationEvent.java new file mode 100644 index 000000000..d560dab5c --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/GEOResourceGenerationEvent.java @@ -0,0 +1,140 @@ +package io.github.thebusybiscuit.slimefun4.api.events; + +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.World.Environment; +import org.bukkit.block.Biome; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource; +import io.github.thebusybiscuit.slimefun4.api.geo.ResourceManager; +import io.github.thebusybiscuit.slimefun4.implementation.items.geo.GEOScanner; + +/** + * This {@link Event} is fired whenever a {@link GEOResource} is being freshly generated. + * This only ocurs when a {@link GEOScanner} queries the {@link Chunk} for a {@link GEOResource} + * but cannot find it. + * + * You can modify this {@link Event} by listening to it. + * + * @author TheBusyBiscuit + * + * @see ResourceManager + * @see GEOResource + * @see GEOScanner + * + */ +public class GEOResourceGenerationEvent extends Event { + + private static final HandlerList handlers = new HandlerList(); + + private final World world; + private final Biome biome; + private final GEOResource resource; + private final int x; + private final int z; + + private int value; + + public GEOResourceGenerationEvent(World world, Biome biome, int x, int z, GEOResource resource, int value) { + this.world = world; + this.biome = biome; + this.resource = resource; + this.x = x; + this.z = z; + + this.value = value; + } + + /** + * This returns the amount that will be generated of this {@link GEOResource}. + * + * @return The value aka the supply of this {@link GEOResource} to generate + */ + public int getValue() { + return value; + } + + /** + * This modifies the amount that will be generated. + * + * @param value + * The new supply for this {@link GEOResource} + */ + public void setValue(int value) { + if (value < 0) { + throw new IllegalArgumentException("You cannot set a GEO-Resource supply to a negative value."); + } + + this.value = value; + } + + /** + * This returns the {@link World} in which this event takes place. + * + * @return The affected {@link World} + */ + public World getWorld() { + return world; + } + + /** + * This method returns the {@link GEOResource} that is being generated + * + * @return The generated {@link GEOResource} + */ + public GEOResource getResource() { + return resource; + } + + /** + * This returns the X coordinate of the {@link Chunk} in which the {@link GEOResource} + * is generated. + * + * @return The x value of this {@link Chunk} + */ + public int getChunkX() { + return x; + } + + /** + * This returns the Z coordinate of the {@link Chunk} in which the {@link GEOResource} + * is generated. + * + * @return The z value of this {@link Chunk} + */ + public int getChunkZ() { + return z; + } + + /** + * This method returns the {@link Environment} in which the resource is generated. + * It is equivalent to {@link World#getEnvironment()}. + * + * @return The {@link Environment} of this generation + */ + public Environment getEnvironment() { + return world.getEnvironment(); + } + + /** + * This returns the {@link Biome} at the {@link Location} at which the {@link GEOResource} is + * generated. + * + * @return The {@link Biome} of this generation + */ + public Biome getBiome() { + return biome; + } + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/MultiBlockInteractEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/MultiBlockInteractEvent.java index fc15957aa..2783de7b3 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/MultiBlockInteractEvent.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/MultiBlockInteractEvent.java @@ -37,10 +37,20 @@ public class MultiBlockInteractEvent extends Event implements Cancellable { this.clickedBlock = clicked; } + /** + * This returns the {@link Player} who interacted with our {@link MultiBlock} + * + * @return The {@link Player} who interacted with the {@link MultiBlock} + */ public Player getPlayer() { return this.player; } + /** + * This method returns the {@link MultiBlock} which was interacted with. + * + * @return The {@link MultiBlock} of this {@link MultiBlockInteractEvent} + */ public MultiBlock getMultiBlock() { return this.multiBlock; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/geo/GEOResource.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/geo/GEOResource.java index 3bddaec29..b9828dc02 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/geo/GEOResource.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/geo/GEOResource.java @@ -8,6 +8,7 @@ import org.bukkit.block.Biome; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import io.github.thebusybiscuit.slimefun4.api.events.GEOResourceGenerationEvent; import io.github.thebusybiscuit.slimefun4.core.services.localization.Language; import io.github.thebusybiscuit.slimefun4.implementation.items.geo.GEOMiner; import io.github.thebusybiscuit.slimefun4.implementation.items.geo.GEOScanner; @@ -27,6 +28,7 @@ import me.mrCookieSlime.Slimefun.SlimefunPlugin; * @see ResourceManager * @see GEOMiner * @see GEOScanner + * @see GEOResourceGenerationEvent * */ public interface GEOResource extends Keyed { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/geo/ResourceManager.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/geo/ResourceManager.java index a36578eb4..734ad6779 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/geo/ResourceManager.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/geo/ResourceManager.java @@ -3,6 +3,7 @@ package io.github.thebusybiscuit.slimefun4.api.geo; import java.util.OptionalInt; import java.util.concurrent.ThreadLocalRandom; +import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.entity.Player; @@ -11,6 +12,7 @@ import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.config.Config; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.skull.SkullItem; +import io.github.thebusybiscuit.slimefun4.api.events.GEOResourceGenerationEvent; import io.github.thebusybiscuit.slimefun4.implementation.items.geo.GEOMiner; import io.github.thebusybiscuit.slimefun4.implementation.items.geo.GEOScanner; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; @@ -75,6 +77,10 @@ public class ResourceManager { value += ThreadLocalRandom.current().nextInt(resource.getMaxDeviation()); } + GEOResourceGenerationEvent event = new GEOResourceGenerationEvent(world, block.getBiome(), x, z, resource, value); + Bukkit.getPluginManager().callEvent(event); + value = event.getValue(); + setSupplies(resource, world, x, z, value); return value; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/EnergyNetComponent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/EnergyNetComponent.java index 919df1866..8623fe6a4 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/EnergyNetComponent.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/EnergyNetComponent.java @@ -2,6 +2,7 @@ package io.github.thebusybiscuit.slimefun4.core.attributes; import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNet; import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType; +import me.mrCookieSlime.Slimefun.SlimefunPlugin; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; /** @@ -36,4 +37,33 @@ public interface EnergyNetComponent extends ItemAttribute { */ int getCapacity(); + /** + * This method is used for internal purposes to register the component. + * You do not have to call this method yourself. + * + * @param id + * The id of the {@link SlimefunItem} this refers to + */ + default void registerComponent(String id) { + switch (getEnergyComponentType()) { + case CONSUMER: + SlimefunPlugin.getRegistry().getEnergyConsumers().add(id); + break; + case CAPACITOR: + SlimefunPlugin.getRegistry().getEnergyCapacitors().add(id); + break; + case GENERATOR: + SlimefunPlugin.getRegistry().getEnergyGenerators().add(id); + break; + default: + break; + } + + int capacity = getCapacity(); + + if (capacity > 0) { + SlimefunPlugin.getRegistry().getEnergyCapacities().put(id, capacity); + } + } + } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/SlimefunLocalization.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/SlimefunLocalization.java index ee4d7aa7b..f238c46d6 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/SlimefunLocalization.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/SlimefunLocalization.java @@ -11,6 +11,7 @@ import org.bukkit.Server; import org.bukkit.command.CommandSender; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; @@ -135,8 +136,11 @@ public abstract class SlimefunLocalization extends Localization implements Keyed return new CustomItem(item, meta -> { meta.setDisplayName(ChatColor.AQUA + config.getString(key.getNamespace() + "." + key.getKey() + ".name")); List lore = config.getStringList(key.getNamespace() + "." + key.getKey() + ".lore"); - lore.replaceAll(str -> ChatColor.GRAY + str); + lore.replaceAll(line -> ChatColor.GRAY + line); meta.setLore(lore); + + meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); + meta.addItemFlags(ItemFlag.HIDE_ENCHANTS); }); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/ChestSlimefunGuide.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/ChestSlimefunGuide.java index da277db0d..1e208ca0d 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/ChestSlimefunGuide.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/ChestSlimefunGuide.java @@ -464,7 +464,7 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation { Player p = profile.getPlayer(); if (p == null) return; - ItemStack result = item.getRecipeOutput() != null ? item.getRecipeOutput() : item.getItem(); + ItemStack result = item.getRecipeOutput(); RecipeType recipeType = item.getRecipeType(); ItemStack[] recipe = item.getRecipe(); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/RadioactiveItem.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/RadioactiveItem.java index 51574f4c7..69f1dcf5f 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/RadioactiveItem.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/RadioactiveItem.java @@ -1,5 +1,6 @@ package io.github.thebusybiscuit.slimefun4.implementation.items; +import org.bukkit.block.Biome; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.slimefun4.core.attributes.Radioactive; @@ -41,7 +42,7 @@ public class RadioactiveItem extends SlimefunItem implements Radioactive { */ public RadioactiveItem(Category category, Radioactivity radioactivity, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { super(category, item, recipeType, recipe); - + this.radioactivity = radioactivity; } 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 f1f9494cc..cf7c21407 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java @@ -70,7 +70,7 @@ public class SlimefunItem implements Placeable { private boolean ticking = false; private BlockTicker blockTicker; - private GeneratorTicker energyTicker; + private GeneratorTicker generatorTicker; /** * This creates a new {@link SlimefunItem} from the given arguments. @@ -183,10 +183,21 @@ public class SlimefunItem implements Placeable { return recipeType; } + /** + * This method returns the result of crafting this {@link SlimefunItem} + * + * @return The recipe output of this {@link SlimefunItem} + */ public ItemStack getRecipeOutput() { - return recipeOutput; + return recipeOutput != null ? recipeOutput.clone() : item.clone(); } + /** + * This method returns the {@link Research} this {@link SlimefunItem} is linked to. + * This will be null if the item is not linked to any {@link Research} + * + * @return The linked {@link Research} or null + */ public Research getResearch() { return research; } @@ -248,7 +259,7 @@ public class SlimefunItem implements Placeable { // We should maybe refactor this and move it to a subclass public GeneratorTicker getEnergyTicker() { - return energyTicker; + return generatorTicker; } /** @@ -285,7 +296,6 @@ public class SlimefunItem implements Placeable { preRegister(); SlimefunItem conflicting = getByID(id); - if (conflicting != null) { throw new IdConflictException(this, conflicting); } @@ -327,7 +337,7 @@ public class SlimefunItem implements Placeable { } if (this instanceof EnergyNetComponent && !SlimefunPlugin.getRegistry().getEnergyCapacities().containsKey(getID())) { - registerEnergyNetComponent((EnergyNetComponent) this); + ((EnergyNetComponent) this).registerComponent(id); } if (SlimefunPlugin.getItemCfg().getBoolean(id + ".enabled")) { @@ -345,19 +355,7 @@ public class SlimefunItem implements Placeable { SlimefunPlugin.getRegistry().getEnabledSlimefunItems().add(this); SlimefunPlugin.getRegistry().getSlimefunItemIds().put(id, this); - - for (ItemHandler handler : itemhandlers.values()) { - Optional exception = handler.validate(this); - - if (exception.isPresent()) { - throw exception.get(); - } - - if (!handler.isPrivate()) { - Set handlerset = getPublicItemHandlers(handler.getIdentifier()); - handlerset.add(handler); - } - } + loadItemHandlers(); } else if (this instanceof VanillaItem) { state = ItemState.VANILLA; @@ -373,25 +371,18 @@ public class SlimefunItem implements Placeable { } } - private void registerEnergyNetComponent(EnergyNetComponent component) { - switch (component.getEnergyComponentType()) { - case CONSUMER: - SlimefunPlugin.getRegistry().getEnergyConsumers().add(id); - break; - case CAPACITOR: - SlimefunPlugin.getRegistry().getEnergyCapacitors().add(id); - break; - case GENERATOR: - SlimefunPlugin.getRegistry().getEnergyGenerators().add(id); - break; - default: - break; - } + private void loadItemHandlers() { + for (ItemHandler handler : itemhandlers.values()) { + Optional exception = handler.validate(this); - int capacity = component.getCapacity(); + if (exception.isPresent()) { + throw exception.get(); + } - if (capacity > 0) { - SlimefunPlugin.getRegistry().getEnergyCapacities().put(id, capacity); + if (!handler.isPrivate()) { + Set handlerset = getPublicItemHandlers(handler.getIdentifier()); + handlerset.add(handler); + } } } @@ -404,6 +395,10 @@ public class SlimefunItem implements Placeable { } public void setRecipe(ItemStack[] recipe) { + if (recipe == null || recipe.length < 9) { + throw new IllegalArgumentException("Cannot set a recipe shorter than 9 elements."); + } + this.recipe = recipe; } @@ -412,6 +407,7 @@ public class SlimefunItem implements Placeable { } public void setCategory(Category category) { + Validate.notNull(category, "'category' is not allowed to be null!"); this.category = category; } @@ -482,8 +478,7 @@ public class SlimefunItem implements Placeable { category.add(this); } - ItemStack output = recipeOutput == null ? item.clone() : recipeOutput.clone(); - recipeType.register(recipe, output); + recipeType.register(recipe, getRecipeOutput()); } catch (Exception x) { error("Failed to properly load the Item \"" + id + "\"", x); @@ -501,7 +496,7 @@ public class SlimefunItem implements Placeable { blockTicker = (BlockTicker) handler; } else if (handler instanceof GeneratorTicker) { - energyTicker = (GeneratorTicker) handler; + generatorTicker = (GeneratorTicker) handler; } } } @@ -525,10 +520,6 @@ public class SlimefunItem implements Placeable { // Useful for calls to Slimefun.getItemValue(...) } - protected void setItem(ItemStack stack) { - this.item = stack; - } - /** * This method will assign the given wiki page to this Item. * Note that you only need to provide the page name itself,