+ * This method will invoke {@link #setSupplies(GEOResource, World, int, int, int)} and also calls a
+ * {@link GEOResourceGenerationEvent}.
+ *
+ * @param resource
+ * The {@link GEOResource} to generate
+ * @param world
+ * The {@link World}
+ * @param x
+ * The x coordinate of that {@link Chunk}
+ * @param z
+ * The z coordinate of that {@link Chunk}
+ *
+ * @return The new supply value
+ */
private int generate(@Nonnull GEOResource resource, @Nonnull World world, int x, int z) {
Validate.notNull(resource, "Cannot generate resources for null");
Validate.notNull(world, "World cannot be null");
+ // Get the corresponding Block (and Biome)
Block block = world.getBlockAt(x << 4, 72, z << 4);
- int value = resource.getDefaultSupply(world.getEnvironment(), block.getBiome());
+ Biome biome = block.getBiome();
+ /*
+ * getBiome() is marked as NotNull, but it seems like some servers ignore this entirely.
+ * We have seen multiple reports on Tuinity where it has indeed returned null.
+ */
+ Validate.notNull(biome, "Biome appears to be null for position: " + new BlockPosition(block));
+
+ // Make sure the value is not below zero.
+ int value = Math.max(0, resource.getDefaultSupply(world.getEnvironment(), biome));
+
+ // Check if more than zero units are to be generated.
if (value > 0) {
int max = resource.getMaxDeviation();
@@ -134,7 +186,8 @@ public class ResourceManager {
value += ThreadLocalRandom.current().nextInt(max);
}
- GEOResourceGenerationEvent event = new GEOResourceGenerationEvent(world, block.getBiome(), x, z, resource, value);
+ // Fire an event, so that plugins can modify this.
+ GEOResourceGenerationEvent event = new GEOResourceGenerationEvent(world, biome, x, z, resource, value);
Bukkit.getPluginManager().callEvent(event);
value = event.getValue();
@@ -166,7 +219,8 @@ public class ResourceManager {
int x = block.getX() >> 4;
int z = block.getZ() >> 4;
- ChestMenu menu = new ChestMenu("&4" + SlimefunPlugin.getLocalization().getResourceString(p, "tooltips.results"));
+ String title = "&4" + SlimefunPlugin.getLocalization().getResourceString(p, "tooltips.results");
+ ChestMenu menu = new ChestMenu(title);
for (int slot : backgroundSlots) {
menu.addItem(slot, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler());
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/GPSNetwork.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/GPSNetwork.java
index d621934ec..7923b7aba 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/GPSNetwork.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/GPSNetwork.java
@@ -58,6 +58,13 @@ public class GPSNetwork {
private final TeleportationManager teleportation = new TeleportationManager();
private final ResourceManager resourceManager;
+ /**
+ * This constructs a new {@link GPSNetwork}.
+ * Note that this network is per {@link Server} and not per {@link Player}.
+ *
+ * @param plugin
+ * Our {@link SlimefunPlugin} instance
+ */
public GPSNetwork(@Nonnull SlimefunPlugin plugin) {
resourceManager = new ResourceManager(plugin);
}
@@ -125,6 +132,13 @@ public class GPSNetwork {
return locations == null ? 0 : locations.size();
}
+ /**
+ * This method opens the {@link GPSTransmitter} control panel to the given
+ * {@link Player}.
+ *
+ * @param p
+ * The {@link Player}
+ */
public void openTransmitterControlPanel(@Nonnull Player p) {
ChestMenu menu = new ChestMenu(ChatColor.BLUE + SlimefunPlugin.getLocalization().getMessage(p, "machines.GPS_CONTROL_PANEL.title"));
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/Waypoint.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/Waypoint.java
index d1e9407c1..953059db5 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/Waypoint.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/Waypoint.java
@@ -7,6 +7,7 @@ import javax.annotation.ParametersAreNonnullByDefault;
import org.apache.commons.lang.Validate;
import org.bukkit.Location;
+import org.bukkit.World.Environment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@@ -34,53 +35,103 @@ public class Waypoint {
private final String name;
private final Location location;
+ /**
+ * This constructs a new {@link Waypoint} object.
+ *
+ * @param profile
+ * The owning {@link PlayerProfile}
+ * @param id
+ * The unique id for this {@link Waypoint}
+ * @param loc
+ * The {@link Location} of the {@link Waypoint}
+ * @param name
+ * The name of this {@link Waypoint}
+ */
@ParametersAreNonnullByDefault
- public Waypoint(PlayerProfile profile, String id, Location l, String name) {
+ public Waypoint(PlayerProfile profile, String id, Location loc, String name) {
Validate.notNull(profile, "Profile must never be null!");
Validate.notNull(id, "id must never be null!");
- Validate.notNull(l, "Location must never be null!");
+ Validate.notNull(loc, "Location must never be null!");
Validate.notNull(name, "Name must never be null!");
this.profile = profile;
this.id = id;
- this.location = l;
+ this.location = loc;
this.name = name;
}
+ /**
+ * This returns the owner of the {@link Waypoint}.
+ *
+ * @return The corresponding {@link PlayerProfile}
+ */
@Nonnull
public PlayerProfile getOwner() {
return profile;
}
+ /**
+ * This method returns the unique identifier for this {@link Waypoint}.
+ *
+ * @return The {@link Waypoint} id
+ */
@Nonnull
public String getId() {
return id;
}
+ /**
+ * This returns the name of this {@link Waypoint}.
+ *
+ * @return The name of this {@link Waypoint}
+ */
@Nonnull
public String getName() {
return name;
}
+ /**
+ * This returns the {@link Location} of this {@link Waypoint}
+ *
+ * @return The {@link Waypoint} {@link Location}
+ */
@Nonnull
public Location getLocation() {
return location;
}
+ /**
+ * This method returns whether this {@link Waypoint} is a Deathpoint.
+ *
+ * @return Whether this is a Deathpoint
+ */
public boolean isDeathpoint() {
return name.startsWith("player:death ");
}
+ /**
+ * This method returns the {@link ItemStack} icon for this {@link Waypoint}.
+ * The icon is dependent on the {@link Environment} the {@link Waypoint} is in
+ * and whether it is a Deathpoint.
+ *
+ * @return The {@link ItemStack} icon for this {@link Waypoint}
+ */
@Nonnull
public ItemStack getIcon() {
return SlimefunPlugin.getGPSNetwork().getIcon(name, location.getWorld().getEnvironment());
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public int hashCode() {
return Objects.hash(profile.getUUID(), id, name, location);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Waypoint)) {
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/ItemRestriction.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/ItemRestriction.java
deleted file mode 100644
index c48a5da31..000000000
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/ItemRestriction.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package io.github.thebusybiscuit.slimefun4.api.items;
-
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.ItemStack;
-
-import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
-import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
-
-public interface ItemRestriction {
-
- /**
- * This method represents a check.
- * The returned boolean will decide whether to allow the action.
- *
- * @param profile
- * The Player's profile
- * @param p
- * The Player itself
- * @param item
- * The SlimefunItem that the {@link ItemStack} represents
- * @param itemstack
- * The ItemStack that is being tested.
- *
- * @return Whether the action was allowed
- */
- boolean isAllowed(PlayerProfile profile, Player p, SlimefunItem item, ItemStack itemstack);
-
- /**
- * This method is executed if an ItemRestriction took affect.
- * Override it to send a message to the Player telling them they cannot
- * use that item, or do something else in there.
- *
- * @param profile
- * The Player's profile
- * @param p
- * The Player to warn
- * @param item
- * The SlimefunItem that the {@link ItemStack} represents
- * @param itemstack
- * The ItemStack that was prevented from being used
- */
- void warnPlayer(PlayerProfile profile, Player p, SlimefunItem item, ItemStack itemstack);
-
-}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java
index d867ac51a..9b24caca2 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java
@@ -471,6 +471,8 @@ public class PlayerProfile {
}
public boolean hasFullProtectionAgainst(@Nonnull ProtectionType type) {
+ Validate.notNull(type, "ProtectionType must not be null.");
+
int armorCount = 0;
NamespacedKey setId = null;
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java
index 9763f6a9a..03ed71260 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java
@@ -36,7 +36,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.guide.CheatSheetSlimefunGuide;
import io.github.thebusybiscuit.slimefun4.implementation.guide.SurvivalSlimefunGuide;
import me.mrCookieSlime.Slimefun.Objects.Category;
-import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler;
import me.mrCookieSlime.Slimefun.api.BlockInfoConfig;
@@ -92,7 +91,6 @@ public final class SlimefunRegistry {
private final Map
+ * It can be obtained via gold dust and other gold ingots in a {@link Smeltery}.
+ *
+ * @author TheBusyBiscuit
+ *
+ * @see Smeltery
+ *
+ */
+public class GoldIngot extends SlimefunItem {
+
+ /**
+ * The carat rating.
+ */
+ private final int caratRating;
+
+ @ParametersAreNonnullByDefault
+ public GoldIngot(Category category, int caratRating, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
+ super(category, item, recipeType, recipe);
+
+ Validate.isTrue(caratRating > 0, "Carat rating must be above zero.");
+ Validate.isTrue(caratRating <= 24, "Carat rating cannot go above 24.");
+ this.caratRating = caratRating;
+ }
+
+ /**
+ * This returns the carat rating of this {@link GoldIngot}.
+ *
+ * The purity of the {@link GoldIngot} is measured in carat (1-24).
+ *
+ *
- * It is notably used by
- * {@link me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler#onBreak(org.bukkit.entity.Player, org.bukkit.block.Block, SlimefunItem, UnregisterReason)}.
- *
- * @author TheBusyBiscuit
- *
- * @deprecated This enum is no longer needed
- *
- * @see SlimefunBlockHandler
- *
- */
-@Deprecated
-public enum UnregisterReason {
-
- /**
- * An explosion destroys the block.
- */
- EXPLODE,
-
- /**
- * A player breaks the block.
- */
- PLAYER_BREAK,
-
- /**
- * An android miner breaks the block.
- */
- ANDROID_DIG
-
-}
diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AContainer.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AContainer.java
index ee71c86dc..62265bca7 100644
--- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AContainer.java
+++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AContainer.java
@@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
@@ -24,7 +25,9 @@ import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
import io.github.thebusybiscuit.slimefun4.api.events.AsyncMachineProcessCompleteEvent;
import io.github.thebusybiscuit.slimefun4.api.items.ItemState;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
+import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler;
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType;
+import io.github.thebusybiscuit.slimefun4.implementation.handlers.SimpleBlockBreakHandler;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
@@ -47,8 +50,9 @@ public abstract class AContainer extends SlimefunItem implements InventoryBlock,
private static final int[] BORDER_IN = { 9, 10, 11, 12, 18, 21, 27, 28, 29, 30 };
private static final int[] BORDER_OUT = { 14, 15, 16, 17, 23, 26, 32, 33, 34, 35 };
- public static Map
+ * 24k = 100% gold.
+ * 18k = 75% gold.
+ * 12k = 50% gold.
+ *
+ *
+ * and so on...
+ *
+ * @return The carat rating of this {@link GoldIngot}
+ */
+ public int getCaratRating() {
+ return caratRating;
+ }
+
+}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/ArmorForge.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/ArmorForge.java
index 7d66099fc..1b328545f 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/ArmorForge.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/ArmorForge.java
@@ -51,7 +51,11 @@ public class ArmorForge extends AbstractCraftingTable {
}
}
- SlimefunPlugin.getLocalization().sendMessage(p, "machines.pattern-not-found", true);
+ if (inv.isEmpty()) {
+ SlimefunPlugin.getLocalization().sendMessage(p, "machines.inventory-empty", true);
+ } else {
+ SlimefunPlugin.getLocalization().sendMessage(p, "machines.pattern-not-found", true);
+ }
}
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/EnhancedCraftingTable.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/EnhancedCraftingTable.java
index 5aeab8fb5..bb30cab7f 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/EnhancedCraftingTable.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/EnhancedCraftingTable.java
@@ -50,7 +50,11 @@ public class EnhancedCraftingTable extends AbstractCraftingTable {
}
}
- SlimefunPlugin.getLocalization().sendMessage(p, "machines.pattern-not-found", true);
+ if (inv.isEmpty()) {
+ SlimefunPlugin.getLocalization().sendMessage(p, "machines.inventory-empty", true);
+ } else {
+ SlimefunPlugin.getLocalization().sendMessage(p, "machines.pattern-not-found", true);
+ }
}
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/GrindStone.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/GrindStone.java
index 54d28c391..9950dbb46 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/GrindStone.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/GrindStone.java
@@ -76,6 +76,9 @@ public class GrindStone extends MultiBlockMachine {
recipes.add(new ItemStack(Material.NETHER_WART_BLOCK));
recipes.add(new ItemStack(Material.NETHER_WART, 9));
+
+ recipes.add(new ItemStack(Material.QUARTZ_BLOCK));
+ recipes.add(new ItemStack(Material.QUARTZ, 4));
}
@Override
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/MagicWorkbench.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/MagicWorkbench.java
index d98935eb1..7fe4e5b15 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/MagicWorkbench.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/MagicWorkbench.java
@@ -57,7 +57,11 @@ public class MagicWorkbench extends AbstractCraftingTable {
}
}
- SlimefunPlugin.getLocalization().sendMessage(p, "machines.pattern-not-found", true);
+ if (inv.isEmpty()) {
+ SlimefunPlugin.getLocalization().sendMessage(p, "machines.inventory-empty", true);
+ } else {
+ SlimefunPlugin.getLocalization().sendMessage(p, "machines.pattern-not-found", true);
+ }
}
}
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/OreCrusher.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/OreCrusher.java
index 162f05625..874c07ad3 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/OreCrusher.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/OreCrusher.java
@@ -89,7 +89,7 @@ public class OreCrusher extends MultiBlockMachine {
recipes.add(new ItemStack(Material.GRAVEL));
recipes.add(new ItemStack(Material.SAND));
- recipes.add(new ItemStack(Material.MAGMA_BLOCK, 4));
+ recipes.add(new ItemStack(Material.MAGMA_BLOCK));
recipes.add(SlimefunItems.SULFATE);
recipes.add(SlimefunItems.CARBON);
diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ClimbingPick.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ClimbingPick.java
index 9f6a7122f..ddc485819 100644
--- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ClimbingPick.java
+++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ClimbingPick.java
@@ -11,6 +11,7 @@ import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import org.apache.commons.lang.Validate;
@@ -235,7 +236,7 @@ public class ClimbingPick extends SimpleSlimefunItem