1
mirror of https://github.com/StarWishsama/Slimefun4.git synced 2024-09-19 19:25:48 +00:00
wip/1.18

Conflicts:
	src/main/java/io/github/thebusybiscuit/slimefun4/implementation/resources/OilResource.java
	src/main/java/io/github/thebusybiscuit/slimefun4/implementation/resources/SaltResource.java
	src/test/java/io/github/thebusybiscuit/slimefun4/api/geo/TestResourceRegistration.java
This commit is contained in:
TheBusyBiscuit 2021-12-10 22:45:00 +01:00
commit 93775e36b4
47 changed files with 2151 additions and 236 deletions

View File

@ -21,7 +21,7 @@ jobs:
uses: actions/checkout@v2.4.0
- name: Set up Java JDK 11
uses: actions/setup-java@v2.3.1
uses: actions/setup-java@v2.4.0
with:
distribution: 'adopt'
java-version: '11'

View File

@ -24,7 +24,7 @@ jobs:
uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v2.3.1
uses: actions/setup-java@v2.4.0
with:
distribution: 'adopt'
java-version: '8'

View File

@ -21,7 +21,7 @@ jobs:
fetch-depth: 0
- name: Set up JDK 11
uses: actions/setup-java@v2.3.1
uses: actions/setup-java@v2.4.0
with:
distribution: 'adopt'
java-version: '11'

View File

@ -1,5 +1,6 @@
# Table of contents
- [Release Candidate 29 (07 Nov 2021)](#release-candidate-29-06-nov-2021)
- [Release Candidate 30 (TBD)](#release-candidate-30-tbd)
- [Release Candidate 29 (07 Nov 2021)](#release-candidate-29-07-nov-2021)
- [Release Candidate 28 (06 Sep 2021)](#release-candidate-28-06-sep-2021)
- [Release Candidate 27 (03 Sep 2021)](#release-candidate-27-03-sep-2021)
- [Release Candidate 26 (20 Jul 2021)](#release-candidate-26-20-jul-2021)
@ -29,6 +30,21 @@
- [Release Candidate 2 (29 Sep 2019)](#release-candidate-2-29-sep-2019)
- [Release Candidate 1 (26 Sep 2019)](#release-candidate-1-26-sep-2019)
## Release Candidate 30 (TBD)
#### Additions
* Added a ton of wiki links to the guide
* (API) Added "GRAVITY_AFFECTED_BLOCKS" tag
* (API) Added "Biome-Maps" for more in-depth GEO resource configuration (developers only for now)
#### Changes
* GEO resource distributions have been slightly adjusted
* Salt can now also generate in the Nether (as a GEO resource)
#### Fixes
* Crimson and Warped Pressure Plates are now properly recognized as pressure plates
* Fixed #3336
## Release Candidate 29 (07 Nov 2021)
#### Additions

View File

@ -309,7 +309,9 @@
<include>wiki.json</include>
<include>languages/translators.json</include>
<include>tags/*.json</include>
<include>biome-maps/*.json</include>
<include>languages/**/*.yml</include>
</includes>
@ -354,7 +356,7 @@
<dependency>
<groupId>io.papermc</groupId>
<artifactId>paperlib</artifactId>
<version>1.0.6</version>
<version>1.0.7</version>
<scope>compile</scope>
</dependency>
<dependency>
@ -376,7 +378,7 @@
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.8.1</version>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
@ -489,7 +491,7 @@
<dependency>
<groupId>net.imprex</groupId>
<artifactId>orebfuscator-api</artifactId>
<version>1.0.0</version>
<version>5.2.1</version>
<scope>provided</scope>
<exclusions>

View File

@ -0,0 +1,47 @@
package io.github.thebusybiscuit.slimefun4.api.exceptions;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.NamespacedKey;
import io.github.thebusybiscuit.slimefun4.utils.biomes.BiomeMap;
/**
* A {@link BiomeMapException} is thrown whenever a {@link BiomeMap}
* contains illegal, invalid or unknown values.
*
* @author TheBusyBiscuit
*
*/
public class BiomeMapException extends Exception {
private static final long serialVersionUID = -1894334121194788527L;
/**
* This constructs a new {@link BiomeMapException} for the given
* {@link BiomeMap}'s {@link NamespacedKey} with the provided context.
*
* @param key
* The {@link NamespacedKey} of our {@link BiomeMap}
* @param message
* The message to display
*/
@ParametersAreNonnullByDefault
public BiomeMapException(NamespacedKey key, String message) {
super("Biome Map '" + key + "' has been misconfigured: " + message);
}
/**
* This constructs a new {@link BiomeMapException} for the given
* {@link BiomeMap}'s {@link NamespacedKey} with the provided context.
*
* @param key
* The {@link NamespacedKey} of our {@link BiomeMap}
* @param cause
* The {@link Throwable} which has caused this to happen
*/
@ParametersAreNonnullByDefault
public BiomeMapException(NamespacedKey key, Throwable cause) {
super("Biome Map '" + key + "' has been misconfigured (" + cause.getMessage() + ')', cause);
}
}

View File

@ -42,5 +42,4 @@ public class Jetpack extends SlimefunItem implements Rechargeable {
public float getMaxItemCharge(ItemStack item) {
return capacity;
}
}

View File

@ -39,6 +39,7 @@ import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
public class Talisman extends SlimefunItem {
protected static final ItemGroup TALISMANS_ITEMGROUP = new ItemGroup(new NamespacedKey(Slimefun.instance(), "talismans"), new CustomItemStack(SlimefunItems.COMMON_TALISMAN, "&7Talismans - &aTier I"), 2);
private static final String WIKI_PAGE = "Talismans";
private final SlimefunItemStack enderTalisman;
@ -72,6 +73,7 @@ public class Talisman extends SlimefunItem {
this.suffix = messageSuffix;
this.effects = effects;
this.chance = chance;
addOfficialWikipage(WIKI_PAGE);
if (!(this instanceof EnderTalisman)) {
String name = "&5Ender " + ChatColor.stripColor(getItem().getItemMeta().getDisplayName());
@ -315,5 +317,4 @@ public class Talisman extends SlimefunItem {
return null;
}
}

View File

@ -1,5 +1,7 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.miner;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
@ -21,6 +23,7 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
*/
public class AdvancedIndustrialMiner extends IndustrialMiner {
@ParametersAreNonnullByDefault
public AdvancedIndustrialMiner(ItemGroup itemGroup, SlimefunItemStack item) {
super(itemGroup, item, Material.DIAMOND_BLOCK, true, 5);
}

View File

@ -51,6 +51,7 @@ public class IndustrialMiner extends MultiBlockMachine {
protected final Map<Location, MiningTask> activeMiners = new HashMap<>();
protected final List<MachineFuel> fuelTypes = new ArrayList<>();
private final OreDictionary oreDictionary;
private final ItemSetting<Boolean> canMineAncientDebris = new ItemSetting<>(this, "can-mine-ancient-debris", false);
private final ItemSetting<Boolean> canMineDeepslateOres = new ItemSetting<>(this, "can-mine-deepslate-ores", true);
private final boolean silkTouch;
@ -58,8 +59,15 @@ public class IndustrialMiner extends MultiBlockMachine {
@ParametersAreNonnullByDefault
public IndustrialMiner(ItemGroup itemGroup, SlimefunItemStack item, Material baseMaterial, boolean silkTouch, int range) {
super(itemGroup, item, new ItemStack[] { null, null, null, new CustomItemStack(Material.PISTON, "Piston (facing up)"), new ItemStack(Material.CHEST), new CustomItemStack(Material.PISTON, "Piston (facing up)"), new ItemStack(baseMaterial), new ItemStack(Material.BLAST_FURNACE), new ItemStack(baseMaterial) }, BlockFace.UP);
// @formatter:off
super(itemGroup, item, new ItemStack[] {
null, null, null,
new CustomItemStack(Material.PISTON, "Piston (facing up)"), new ItemStack(Material.CHEST), new CustomItemStack(Material.PISTON, "Piston (facing up)"),
new ItemStack(baseMaterial), new ItemStack(Material.BLAST_FURNACE), new ItemStack(baseMaterial)
}, BlockFace.UP);
// @formatter:on
this.oreDictionary = OreDictionary.forVersion(Slimefun.getMinecraftVersion());
this.range = range;
this.silkTouch = silkTouch;
@ -114,67 +122,17 @@ public class IndustrialMiner extends MultiBlockMachine {
/**
* This method returns the outcome that mining certain ores yields.
*
* @param ore
* @param material
* The {@link Material} of the ore that was mined
*
* @return The outcome when mining this ore
*/
public @Nonnull ItemStack getOutcome(@Nonnull Material ore) {
public @Nonnull ItemStack getOutcome(@Nonnull Material material) {
if (hasSilkTouch()) {
return new ItemStack(ore);
}
MinecraftVersion minecraftVersion = Slimefun.getMinecraftVersion();
return new ItemStack(material);
} else {
Random random = ThreadLocalRandom.current();
if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_17)) {
// In 1.17, breaking metal ores should get raw metals. Also support deepslate ores.
switch (ore) {
case DEEPSLATE_COAL_ORE:
return new ItemStack(Material.COAL);
case DEEPSLATE_DIAMOND_ORE:
return new ItemStack(Material.DIAMOND);
case DEEPSLATE_EMERALD_ORE:
return new ItemStack(Material.EMERALD);
case DEEPSLATE_REDSTONE_ORE:
return new ItemStack(Material.REDSTONE, 4 + random.nextInt(2));
case DEEPSLATE_LAPIS_ORE:
return new ItemStack(Material.LAPIS_LAZULI, 4 + random.nextInt(4));
case COPPER_ORE:
case DEEPSLATE_COPPER_ORE:
return new ItemStack(Material.RAW_COPPER);
case IRON_ORE:
case DEEPSLATE_IRON_ORE:
return new ItemStack(Material.RAW_IRON);
case GOLD_ORE:
case DEEPSLATE_GOLD_ORE:
return new ItemStack(Material.RAW_GOLD);
default:
break;
}
}
// In 1.16, breaking nether gold ores should get gold nuggets
if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_16) && ore == Material.NETHER_GOLD_ORE) {
return new ItemStack(Material.GOLD_NUGGET, 2 + random.nextInt(4));
}
switch (ore) {
case COAL_ORE:
return new ItemStack(Material.COAL);
case DIAMOND_ORE:
return new ItemStack(Material.DIAMOND);
case EMERALD_ORE:
return new ItemStack(Material.EMERALD);
case REDSTONE_ORE:
return new ItemStack(Material.REDSTONE, 4 + random.nextInt(2));
case LAPIS_ORE:
return new ItemStack(Material.LAPIS_LAZULI, 4 + random.nextInt(4));
case NETHER_QUARTZ_ORE:
return new ItemStack(Material.QUARTZ);
default:
// This includes Iron and Gold ore (and Ancient Debris)
return new ItemStack(ore);
return oreDictionary.getDrops(material, random);
}
}

View File

@ -56,7 +56,7 @@ class MiningTask implements Runnable {
private final int height;
private boolean running = false;
private int fuel = 0;
private int fuelLevel = 0;
private int ores = 0;
private int x;
@ -120,14 +120,6 @@ class MiningTask implements Runnable {
* This method starts the warm-up animation for the {@link IndustrialMiner}.
*/
private void warmUp() {
fuel = consumeFuel();
if (fuel <= 0) {
// This Miner has not enough fuel.
stop(MinerStoppingReason.NO_FUEL);
return;
}
/*
* This is our warm up animation.
* The pistons will push after another in decreasing intervals
@ -140,6 +132,21 @@ class MiningTask implements Runnable {
queue.thenRun(8, () -> setPistonState(pistons[1], true));
queue.thenRun(10, () -> setPistonState(pistons[1], false));
/*
* Fixes #3336
* Trigger each piston once, so that the structure is validated.
* Then consume fuel.
*/
queue.thenRun(() -> {
consumeFuel();
if (fuelLevel <= 0) {
// This Miner has not enough fuel.
stop(MinerStoppingReason.NO_FUEL);
return;
}
});
queue.thenRun(6, () -> setPistonState(pistons[0], true));
queue.thenRun(9, () -> setPistonState(pistons[0], false));
@ -196,7 +203,7 @@ class MiningTask implements Runnable {
furnace.getWorld().playSound(furnace.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 0.2F, 1F);
b.setType(Material.AIR);
fuel--;
fuelLevel--;
ores++;
// Repeat the same column when we hit an ore.
@ -251,13 +258,13 @@ class MiningTask implements Runnable {
* @return Whether the operation was successful
*/
private boolean push(@Nonnull ItemStack item) {
if (fuel < 1) {
if (fuelLevel < 1) {
// Restock fuel
fuel = consumeFuel();
consumeFuel();
}
// Check if there is enough fuel to run
if (fuel > 0) {
if (fuelLevel > 0) {
if (chest.getType() == Material.CHEST) {
BlockState state = PaperLib.getBlockState(chest, false).getState();
@ -287,23 +294,19 @@ class MiningTask implements Runnable {
/**
* This consumes fuel from the given {@link Chest}.
*
* @return The gained fuel value
*/
private int consumeFuel() {
private void consumeFuel() {
if (chest.getType() == Material.CHEST) {
BlockState state = PaperLib.getBlockState(chest, false).getState();
if (state instanceof Chest) {
Inventory inv = ((Chest) state).getBlockInventory();
return consumeFuel(inv);
this.fuelLevel = grabFuelFrom(inv);
}
}
}
return 0;
}
private int consumeFuel(@Nonnull Inventory inv) {
private int grabFuelFrom(@Nonnull Inventory inv) {
for (int i = 0; i < inv.getSize(); i++) {
for (MachineFuel fuelType : miner.fuelTypes) {
ItemStack item = inv.getContents()[i];

View File

@ -0,0 +1,37 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.miner;
import java.util.Random;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
/**
* Simple interface to map ore blocks to their respective item(s).
*
* @author TheBusyBiscuit
*
*/
interface OreDictionary {
@Nonnull
@ParametersAreNonnullByDefault
ItemStack getDrops(Material material, Random random);
static @Nonnull OreDictionary forVersion(@Nonnull MinecraftVersion version) {
if (version.isAtLeast(MinecraftVersion.MINECRAFT_1_17)) {
// MC 1.17 - 1.18
return new OreDictionary17();
} else if (version.isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
// MC 1.16
return new OreDictionary16();
} else {
// MC 1.14 - 1.15
return new OreDictionary14();
}
}
}

View File

@ -0,0 +1,44 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.miner;
import java.util.Random;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
/**
* Our {@link OreDictionary} implementation for MC 1.14 or higher.
*
* @author TheBusyBiscuit
*
*/
class OreDictionary14 implements OreDictionary {
@Override
@ParametersAreNonnullByDefault
public @Nonnull ItemStack getDrops(Material material, Random random) {
switch (material) {
case COAL_ORE:
return new ItemStack(Material.COAL);
case DIAMOND_ORE:
return new ItemStack(Material.DIAMOND);
case EMERALD_ORE:
return new ItemStack(Material.EMERALD);
case REDSTONE_ORE:
return new ItemStack(Material.REDSTONE, 4 + random.nextInt(2));
case LAPIS_ORE:
return new ItemStack(Material.LAPIS_LAZULI, 4 + random.nextInt(4));
case NETHER_QUARTZ_ORE:
return new ItemStack(Material.QUARTZ);
case IRON_ORE:
return new ItemStack(Material.IRON_ORE);
case GOLD_ORE:
return new ItemStack(Material.GOLD_ORE);
default:
return new ItemStack(material);
}
}
}

View File

@ -0,0 +1,33 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.miner;
import java.util.Random;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
/**
* Our {@link OreDictionary} implementation for MC 1.16 or higher.
*
* @author TheBusyBiscuit
*
*/
class OreDictionary16 extends OreDictionary14 {
@Override
@ParametersAreNonnullByDefault
public @Nonnull ItemStack getDrops(Material material, Random random) {
switch (material) {
case NETHER_GOLD_ORE:
// In 1.16, breaking nether gold ores should get gold nuggets
return new ItemStack(Material.GOLD_NUGGET, 2 + random.nextInt(4));
case ANCIENT_DEBRIS:
return new ItemStack(Material.ANCIENT_DEBRIS);
default:
return super.getDrops(material, random);
}
}
}

View File

@ -0,0 +1,52 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.miner;
import java.util.Random;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
/**
* Our {@link OreDictionary} implementation for MC 1.17 or higher.
*
* @author TheBusyBiscuit
*
*/
class OreDictionary17 extends OreDictionary16 {
@Override
@ParametersAreNonnullByDefault
public ItemStack getDrops(Material material, Random random) {
// In 1.17, breaking metal ores should get raw metals. Also support deepslate ores.
switch (material) {
case COAL_ORE:
case DEEPSLATE_COAL_ORE:
return new ItemStack(Material.COAL);
case DIAMOND_ORE:
case DEEPSLATE_DIAMOND_ORE:
return new ItemStack(Material.DIAMOND);
case EMERALD_ORE:
case DEEPSLATE_EMERALD_ORE:
return new ItemStack(Material.EMERALD);
case REDSTONE_ORE:
case DEEPSLATE_REDSTONE_ORE:
return new ItemStack(Material.REDSTONE, 4 + random.nextInt(2));
case LAPIS_ORE:
case DEEPSLATE_LAPIS_ORE:
return new ItemStack(Material.LAPIS_LAZULI, 4 + random.nextInt(4));
case COPPER_ORE:
case DEEPSLATE_COPPER_ORE:
return new ItemStack(Material.RAW_COPPER);
case IRON_ORE:
case DEEPSLATE_IRON_ORE:
return new ItemStack(Material.RAW_IRON);
case GOLD_ORE:
case DEEPSLATE_GOLD_ORE:
return new ItemStack(Material.RAW_GOLD);
default:
return super.getDrops(material, random);
}
}
}

View File

@ -1,5 +1,7 @@
package io.github.thebusybiscuit.slimefun4.implementation.resources;
import java.util.logging.Level;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
@ -7,8 +9,12 @@ import org.apache.commons.lang.Validate;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
import com.google.gson.JsonElement;
import io.github.thebusybiscuit.slimefun4.api.exceptions.BiomeMapException;
import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.utils.biomes.BiomeMap;
/**
* This is an abstract parent class for any {@link GEOResource}
@ -21,7 +27,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
* @author TheBusyBiscuit
*
*/
abstract class SlimefunResource implements GEOResource {
abstract class AbstractResource implements GEOResource {
private final NamespacedKey key;
private final String defaultName;
@ -30,7 +36,7 @@ abstract class SlimefunResource implements GEOResource {
private final boolean geoMiner;
@ParametersAreNonnullByDefault
SlimefunResource(String key, String defaultName, ItemStack item, int maxDeviation, boolean geoMiner) {
AbstractResource(String key, String defaultName, ItemStack item, int maxDeviation, boolean geoMiner) {
Validate.notNull(key, "NamespacedKey cannot be null!");
Validate.notNull(defaultName, "The default name cannot be null!");
Validate.notNull(item, "item cannot be null!");
@ -70,4 +76,33 @@ abstract class SlimefunResource implements GEOResource {
return geoMiner;
}
/**
* Internal helper method for reading a {@link BiomeMap} of {@link Integer} type values from
* a resource file.
*
* @param resource
* The {@link AbstractResource} instance
* @param path
* The path to our biome map file
*
* @return A {@link BiomeMap} for this resource
*/
@ParametersAreNonnullByDefault
static final @Nonnull BiomeMap<Integer> getBiomeMap(AbstractResource resource, String path) {
Validate.notNull(resource, "Resource cannot be null.");
Validate.notNull(path, "Path cannot be null.");
try {
return BiomeMap.fromResource(resource.getKey(), path, JsonElement::getAsInt);
} catch (BiomeMapException x) {
if (Slimefun.instance().isUnitTest()) {
// Unit Tests should always fail here, so we re-throw the exception
throw new IllegalStateException(x);
} else {
// In a server environment, we should just print a warning and carry on
Slimefun.logger().log(Level.WARNING, x, () -> "Failed to load BiomeMap for GEO-resource: " + resource.getKey());
return new BiomeMap<>(resource.getKey());
}
}
}
}

View File

@ -3,8 +3,11 @@ package io.github.thebusybiscuit.slimefun4.implementation.resources;
import org.bukkit.World.Environment;
import org.bukkit.block.Biome;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.utils.biomes.BiomeMap;
/**
* A {@link GEOResource} which consists of nether ice.
@ -13,15 +16,30 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
* @author TheBusyBiscuit
*
*/
class NetherIceResource extends SlimefunResource {
class NetherIceResource extends AbstractResource {
private static final int DEFAULT_NETHER_VALUE = 32;
private final BiomeMap<Integer> biomes;
NetherIceResource() {
super("nether_ice", "Nether Ice", SlimefunItems.NETHER_ICE, 6, true);
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
// 1.16+ introduced Nether biomes
biomes = getBiomeMap(this, "/biome-maps/nether_ice_v1.16.json");
} else {
biomes = getBiomeMap(this, "/biome-maps/nether_ice_v1.14.json");
}
}
@Override
public int getDefaultSupply(Environment environment, Biome biome) {
return environment == Environment.NETHER ? 32 : 0;
if (environment != Environment.NETHER) {
return 0;
} else {
return biomes.getOrDefault(biome, DEFAULT_NETHER_VALUE);
}
}
}

View File

@ -1,7 +1,5 @@
package io.github.thebusybiscuit.slimefun4.implementation.resources;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import org.bukkit.World.Environment;
import org.bukkit.block.Biome;
@ -9,6 +7,7 @@ import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.items.geo.GEOMiner;
import io.github.thebusybiscuit.slimefun4.implementation.items.geo.OilPump;
import io.github.thebusybiscuit.slimefun4.utils.biomes.BiomeMap;
/**
* A {@link GEOResource} which consists of buckets of Oil.
@ -20,86 +19,24 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.geo.OilPump;
* @see OilPump
*
*/
class OilResource extends SlimefunResource {
class OilResource extends AbstractResource {
private static final int DEFAULT_OVERWORLD_VALUE = 10;
private final BiomeMap<Integer> biomes;
OilResource() {
super("oil", "Oil", SlimefunItems.OIL_BUCKET, 8, false);
biomes = getBiomeMap(this, "/biome-maps/oil_v1.14.json");
}
@Override
public int getDefaultSupply(Environment environment, Biome biome) {
if (environment != Environment.NORMAL) {
return 0;
}
// TODO: Think of a better way to support biomes.
// Maybe worth making an issue/PR to Spigot in order to add the "biomes" registry.
if (Slimefun.getMinecraftVersion().isBefore(MinecraftVersion.MINECRAFT_1_18)) {
switch (biome.name()) {
case "STONE_SHORE":
return 6;
case "DESERT_HILLS":
case "DESERT_LAKES":
return 45;
case "MOUNTAINS":
case "GRAVELLY_MOUNTAINS":
case "MOUNTAIN_EDGE":
return 17;
case "SNOWY_MOUNTAINS":
case "SNOWY_TUNDRA":
return 14;
case "BADLANDS_PLATEAU":
case "WOODED_BADLANDS_PLATEAU":
case "MODIFIED_BADLANDS_PLATEAU":
case "MODIFIED_WOODED_BADLANDS_PLATEAU":
case "MUSHROOM_FIELD_SHORE":
return 24;
case "DEEP_WARM_OCEAN":
return 62;
case "SWAMP_HILLS":
return 20;
default:
break;
}
}
switch (biome) {
case SNOWY_BEACH:
case STONY_SHORE:
case BEACH:
return 6;
case DESERT:
return 45;
case RIVER:
return 17;
case ICE_SPIKES:
case FROZEN_OCEAN:
case FROZEN_RIVER:
return 14;
case BADLANDS:
case ERODED_BADLANDS:
case MUSHROOM_FIELDS:
return 24;
case DEEP_OCEAN:
case OCEAN:
case COLD_OCEAN:
case DEEP_COLD_OCEAN:
case DEEP_FROZEN_OCEAN:
case DEEP_LUKEWARM_OCEAN:
case LUKEWARM_OCEAN:
case WARM_OCEAN:
return 62;
case SWAMP:
return 20;
default:
return 10;
} else {
return biomes.getOrDefault(biome, DEFAULT_OVERWORLD_VALUE);
}
}
}

View File

@ -1,12 +1,11 @@
package io.github.thebusybiscuit.slimefun4.implementation.resources;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import org.bukkit.World.Environment;
import org.bukkit.block.Biome;
import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.utils.biomes.BiomeMap;
/**
* A {@link GEOResource} which consists of Salt.
@ -14,60 +13,28 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
* @author TheBusyBiscuit
*
*/
class SaltResource extends SlimefunResource {
class SaltResource extends AbstractResource {
private static final int DEFAULT_OVERWORLD_VALUE = 6;
private static final int DEFAULT_NETHER_VALUE = 8;
private final BiomeMap<Integer> biomes;
SaltResource() {
super("salt", "Salt", SlimefunItems.SALT, 18, true);
biomes = getBiomeMap(this, "/biome-maps/salt_v1.14.json");
}
@Override
public int getDefaultSupply(Environment environment, Biome biome) {
if (environment != Environment.NORMAL) {
if (environment == Environment.NORMAL) {
return biomes.getOrDefault(biome, DEFAULT_OVERWORLD_VALUE);
} else if (environment == Environment.NETHER) {
return biomes.getOrDefault(biome, DEFAULT_NETHER_VALUE);
} else {
return 0;
}
// TODO: Think of a better way to support biomes.
// Maybe worth making an issue/PR to Spigot in order to add the "biomes" registry.
if (Slimefun.getMinecraftVersion().isBefore(MinecraftVersion.MINECRAFT_1_18)) {
switch (biome.name()) {
case "STONE_SHORE":
case "DESERT_LAKES":
return 40;
case "DEEP_WARM_OCEAN":
return 60;
case "SWAMP_HILLS":
return 20;
default:
break;
}
}
switch (biome) {
case SNOWY_BEACH:
case STONY_SHORE:
case BEACH:
case RIVER:
case ICE_SPIKES:
case FROZEN_RIVER:
return 40;
case DEEP_OCEAN:
case OCEAN:
case COLD_OCEAN:
case DEEP_COLD_OCEAN:
case DEEP_FROZEN_OCEAN:
case DEEP_LUKEWARM_OCEAN:
case FROZEN_OCEAN:
case LUKEWARM_OCEAN:
case WARM_OCEAN:
return 60;
case SWAMP:
return 20;
default:
return 6;
}
}
}

View File

@ -3,8 +3,11 @@ package io.github.thebusybiscuit.slimefun4.implementation.resources;
import org.bukkit.World.Environment;
import org.bukkit.block.Biome;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.utils.biomes.BiomeMap;
/**
* A {@link GEOResource} which consists of small chunks of Uranium.
@ -12,19 +15,35 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
* @author TheBusyBiscuit
*
*/
class UraniumResource extends SlimefunResource {
class UraniumResource extends AbstractResource {
private static final int DEFAULT_OVERWORLD_VALUE = 4;
private final BiomeMap<Integer> biomes;
UraniumResource() {
super("uranium", "Small Chunks of Uranium", SlimefunItems.SMALL_URANIUM, 2, true);
MinecraftVersion version = Slimefun.getMinecraftVersion();
if (version.isAtLeast(MinecraftVersion.MINECRAFT_1_17)) {
// 1.17+ introduced cave biomes
biomes = getBiomeMap(this, "/biome-maps/uranium_v1.17.json");
} else if (version.isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
// 1.16+ introduced Nether biomes
biomes = getBiomeMap(this, "/biome-maps/uranium_v1.16.json");
} else {
biomes = getBiomeMap(this, "/biome-maps/uranium_v1.14.json");
}
}
@Override
public int getDefaultSupply(Environment environment, Biome biome) {
if (environment == Environment.NORMAL) {
return 5;
}
if (environment != Environment.NORMAL) {
return 0;
} else {
return biomes.getOrDefault(biome, DEFAULT_OVERWORLD_VALUE);
}
}
}

View File

@ -20,7 +20,8 @@ public final class PatternUtils {
public static final Pattern SLASH_SEPARATOR = Pattern.compile(" / ");
public static final Pattern MINECRAFT_MATERIAL = Pattern.compile("minecraft:[a-z_]+");
public static final Pattern MINECRAFT_NAMESPACEDKEY = Pattern.compile("minecraft:[a-z0-9/._-]+");
public static final Pattern MINECRAFT_TAG = Pattern.compile("#minecraft:[a-z_]+");
public static final Pattern SLIMEFUN_TAG = Pattern.compile("#slimefun:[a-z_]+");

View File

@ -504,11 +504,13 @@ public final class SlimefunUtils {
}
/**
* Helper method to check if an Inventory is empty (has no items in "storage"). If the MC version is 1.16 or above
* Helper method to check if an Inventory is empty (has no items in "storage").
* If the MC version is 1.16 or above
* this will call {@link Inventory#isEmpty()} (Which calls MC code resulting in a faster method).
*
* @param inventory
* The {@link Inventory} to check.
*
* @return True if the inventory is empty and false otherwise
*/
public static boolean isInventoryEmpty(@Nonnull Inventory inventory) {

View File

@ -30,6 +30,11 @@ public final class WorldUtils {
public static int getMinHeight(@Nonnull World world) {
Validate.notNull(world, "World cannot be null!");
return Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16) ? world.getMinHeight() : 0;
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
return world.getMinHeight();
} else {
// Default to zero for pre-1.16 worlds
return 0;
}
}
}

View File

@ -0,0 +1,46 @@
package io.github.thebusybiscuit.slimefun4.utils.biomes;
import javax.annotation.Nonnull;
import com.google.gson.JsonElement;
/**
* A simple functional interface for converting a {@link JsonElement} into the desired data type
* needed for your {@link BiomeMap}.
*
* @author TheBusyBiscuit
*
* @param <T>
* Your target data type
*
* @see BiomeMap
*/
@FunctionalInterface
public interface BiomeDataConverter<T> {
/**
* Override this method and provide a way to convert a {@link JsonElement} into your
* desired data type.
* <p>
* For primitive data values, you can also just use the following method references:
*
* <ul>
* <li>JsonElement::getAsString</li>
* <li>JsonElement::getAsInt</li>
* <li>JsonElement::getAsDouble</li>
* <li>JsonElement::getAsFloat</li>
* <li>JsonElement::getAsLong</li>
* <li>JsonElement::getAsBoolean</li>
* </ul>
*
* or similar.
*
* @param jsonElement
* The {@link JsonElement} to convert
*
* @return Your desired data type.
*/
@Nonnull
T convert(@Nonnull JsonElement jsonElement);
}

View File

@ -0,0 +1,162 @@
package io.github.thebusybiscuit.slimefun4.utils.biomes;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.EnumMap;
import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import org.apache.commons.lang.Validate;
import org.bukkit.Keyed;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Biome;
import com.google.gson.JsonElement;
import io.github.thebusybiscuit.slimefun4.api.exceptions.BiomeMapException;
import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
/**
* {@link BiomeMap}s are used to map data values to {@link Biome} constants.
* <p>
* We heavily utilise this method of data mapping for {@link GEOResource}s, especially
* when supporting multiple versions of Minecraft. This way, we can have different {@link BiomeMap}s
* for different versions of Minecraft, in case {@link Biome} names change in-between versions.
* <p>
* The data type can be any type of {@link Object}.
* The most common type is {@link Integer}, if you are using complex objects and try to read
* your {@link BiomeMap} from a {@link JsonElement}, make sure to provide an adequate
* {@link BiomeDataConverter} to convert the raw json data.
*
* @author TheBusyBiscuit
*
* @param <T>
* The stored data type
*/
public class BiomeMap<T> implements Keyed {
/**
* Our internal {@link EnumMap} holding all the data.
*/
private final Map<Biome, T> dataMap = new EnumMap<>(Biome.class);
/**
* The {@link NamespacedKey} to identify this {@link BiomeMap}.
*/
private final NamespacedKey namespacedKey;
/**
* This constructs a new {@link BiomeMap} with the given {@link NamespacedKey}.
*
* @param namespacedKey
* The {@link NamespacedKey} for this {@link BiomeMap}
*/
@ParametersAreNonnullByDefault
public BiomeMap(NamespacedKey namespacedKey) {
Validate.notNull(namespacedKey, "The key must not be null.");
this.namespacedKey = namespacedKey;
}
public @Nullable T get(@Nonnull Biome biome) {
Validate.notNull(biome, "The biome shall not be null.");
return dataMap.get(biome);
}
public @Nonnull T getOrDefault(@Nonnull Biome biome, T defaultValue) {
Validate.notNull(biome, "The biome should not be null.");
return dataMap.getOrDefault(biome, defaultValue);
}
public boolean containsKey(@Nonnull Biome biome) {
Validate.notNull(biome, "The biome must not be null.");
return dataMap.containsKey(biome);
}
public boolean containsValue(@Nonnull T value) {
Validate.notNull(value, "The value must not be null.");
return dataMap.containsValue(value);
}
/**
* This returns whether this {@link BiomeMap} is empty.
* An empty {@link BiomeMap} contains no biomes or values.
*
* @return Whether this {@link BiomeMap} is empty.
*/
public boolean isEmpty() {
return dataMap.isEmpty();
}
public boolean put(@Nonnull Biome biome, @Nonnull T value) {
Validate.notNull(biome, "The biome should not be null.");
Validate.notNull(value, "Values cannot be null.");
return dataMap.put(biome, value) == null;
}
public void putAll(@Nonnull Map<Biome, T> map) {
Validate.notNull(map, "The map should not be null.");
dataMap.putAll(map);
}
public void putAll(@Nonnull BiomeMap<T> map) {
Validate.notNull(map, "The map should not be null.");
dataMap.putAll(map.dataMap);
}
public boolean remove(@Nonnull Biome biome) {
Validate.notNull(biome, "The biome cannot be null.");
return dataMap.remove(biome) != null;
}
/**
* {@inheritDoc}
*/
@Override
public @Nonnull NamespacedKey getKey() {
return namespacedKey;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return "BiomeMap " + dataMap.toString();
}
@ParametersAreNonnullByDefault
public static <T> @Nonnull BiomeMap<T> fromJson(NamespacedKey key, String json, BiomeDataConverter<T> valueConverter) throws BiomeMapException {
// All parameters are validated by the Parser.
BiomeMapParser<T> parser = new BiomeMapParser<>(key, valueConverter);
parser.read(json);
return parser.buildBiomeMap();
}
@ParametersAreNonnullByDefault
public static <T> @Nonnull BiomeMap<T> fromResource(NamespacedKey key, String path, BiomeDataConverter<T> valueConverter) throws BiomeMapException {
Validate.notNull(key, "The key shall not be null.");
Validate.notNull(path, "The path should not be null!");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(Slimefun.class.getResourceAsStream(path), StandardCharsets.UTF_8))) {
return fromJson(key, reader.lines().collect(Collectors.joining("")), valueConverter);
} catch (IOException x) {
throw new BiomeMapException(key, x);
}
}
}

View File

@ -0,0 +1,210 @@
package io.github.thebusybiscuit.slimefun4.utils.biomes;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.apache.commons.lang.Validate;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Biome;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;
import io.github.bakedlibs.dough.common.CommonPatterns;
import io.github.thebusybiscuit.slimefun4.api.exceptions.BiomeMapException;
import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
/**
* The {@link BiomeMapParser} allows you to parse json data into a {@link BiomeMap}.
*
* @author TheBusyBiscuit
*
* @param <T>
* The data type of the resulting {@link BiomeMap}
*
* @see BiomeMap
*/
class BiomeMapParser<T> {
private static final String VALUE_KEY = "value";
private static final String BIOMES_KEY = "biomes";
private final NamespacedKey key;
private final BiomeDataConverter<T> valueConverter;
private final Map<Biome, T> map = new EnumMap<>(Biome.class);
/**
* This flag specifies whether the parsing is "lenient" or not.
* A lenient parser will not throw a {@link BiomeMapException} if the {@link Biome}
* could not be found.
* The default value is false.
*/
private boolean isLenient = false;
/**
* This constructs a new {@link BiomeMapParser}.
* <p>
* To parse data, use the {@link #read(JsonArray)} or {@link #read(String)} method.
*
* @param key
* The {@link NamespacedKey} for the resulting {@link BiomeMap}
* @param valueConverter
* A function to convert {@link JsonElement}s into your desired data type
*/
@ParametersAreNonnullByDefault
BiomeMapParser(NamespacedKey key, BiomeDataConverter<T> valueConverter) {
Validate.notNull(key, "The key shall not be null.");
Validate.notNull(valueConverter, "You must provide a Function to convert raw json values to your desired data type.");
this.key = key;
this.valueConverter = valueConverter;
}
/**
* This method sets the "lenient" flag for this parser.
* <p>
* A lenient parser will not throw a {@link BiomeMapException} if the {@link Biome}
* could not be found.
* The default value is false.
*
* @param isLenient
* Whether this parser should be lenient or not.
*/
void setLenient(boolean isLenient) {
this.isLenient = isLenient;
}
/**
* This method returns whether this parser is flagged as "lenient".
* <p>
* A lenient parser will not throw a {@link BiomeMapException} if the {@link Biome}
* could not be found.
* The default value is false.
*
* @return Whether this parser is lenient or not.
*/
boolean isLenient() {
return isLenient;
}
void read(@Nonnull String json) throws BiomeMapException {
Validate.notNull(json, "The JSON string should not be null!");
JsonArray root = null;
try {
JsonParser parser = new JsonParser();
root = parser.parse(json).getAsJsonArray();
} catch (IllegalStateException | JsonParseException x) {
throw new BiomeMapException(key, x);
}
/*
* We don't include this in our try/catch, as this type of exception
* is already specified in the throws-declaration.
*/
read(root);
}
void read(@Nonnull JsonArray json) throws BiomeMapException {
Validate.notNull(json, "The JSON Array should not be null!");
for (JsonElement element : json) {
if (element instanceof JsonObject) {
readEntry(element.getAsJsonObject());
} else {
throw new BiomeMapException(key, "Unexpected array element: " + element.getClass().getSimpleName() + " - " + element.toString());
}
}
}
private void readEntry(@Nonnull JsonObject entry) throws BiomeMapException {
Validate.notNull(entry, "The JSON entry should not be null!");
/*
* Check if the entry has a "value" element.
* The data type is irrelevant here, any JsonElement is supported (in theory).
* If you write a converter for it, you can also serialize complex objects this way.
*/
if (entry.has(VALUE_KEY)) {
T value = valueConverter.convert(entry.get(VALUE_KEY));
// Check if the entry has a "biomes" element of type JsonArray.
if (entry.has(BIOMES_KEY) && entry.get(BIOMES_KEY).isJsonArray()) {
Set<Biome> biomes = readBiomes(entry.get(BIOMES_KEY).getAsJsonArray());
// Loop through all biome strings in this array
for (Biome biome : biomes) {
T prev = map.put(biome, value);
// Check for duplicates
if (prev != null) {
throw new BiomeMapException(key, "Biome '" + biome.getKey() + "' is registered twice");
}
}
} else {
throw new BiomeMapException(key, "Entry is missing a 'biomes' child of type array.");
}
} else {
throw new BiomeMapException(key, "Entry is missing a 'value' child.");
}
}
private @Nonnull Set<Biome> readBiomes(@Nonnull JsonArray array) throws BiomeMapException {
Validate.notNull(array, "The JSON array should not be null!");
Set<Biome> biomes = EnumSet.noneOf(Biome.class);
for (JsonElement element : array) {
if (element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) {
String value = element.getAsString();
if (PatternUtils.MINECRAFT_NAMESPACEDKEY.matcher(value).matches()) {
String formattedValue = CommonPatterns.COLON.split(value)[1].toUpperCase(Locale.ROOT);
try {
Biome biome = Biome.valueOf(formattedValue);
biomes.add(biome);
} catch (IllegalArgumentException x) {
// Lenient Parsers will ignore unknown biomes
if (isLenient) {
continue;
}
throw new BiomeMapException(key, "The Biome '" + value + "' does not exist!");
}
} else {
// The regular expression did not match
throw new BiomeMapException(key, "Could not recognize value '" + value + "'");
}
} else {
throw new BiomeMapException(key, "Unexpected array element: " + element.getClass().getSimpleName() + " - " + element.toString());
}
}
return biomes;
}
/**
* This method builds a {@link BiomeMap} based on the parsed data.
* <p>
* Make sure to parse data via {@link #read(JsonArray)} or {@link #read(String)}
* before calling this method! Otherwise the resulting {@link BiomeMap} will be empty.
*
* @return The resulting {@link BiomeMap}
*/
@Nonnull
BiomeMap<T> buildBiomeMap() {
BiomeMap<T> biomeMap = new BiomeMap<>(key);
biomeMap.putAll(map);
return biomeMap;
}
}

View File

@ -0,0 +1,5 @@
/**
* This package contains classes centered around our {@link io.github.thebusybiscuit.slimefun4.utils.biomes.BiomeMap}
* utility.
*/
package io.github.thebusybiscuit.slimefun4.utils.biomes;

View File

@ -241,7 +241,12 @@ public enum SlimefunTag implements Tag<Material> {
/**
* All materials which benefit from the luck multiplier of {@link EnhancedFurnace}
*/
ENHANCED_FURNACE_LUCK_MATERIALS;
ENHANCED_FURNACE_LUCK_MATERIALS,
/**
* All materials that are affected by gravity.
*/
GRAVITY_AFFECTED_BLOCKS;
/**
* Lookup table for tag names.

View File

@ -134,7 +134,7 @@ public class TagParser implements Keyed {
@ParametersAreNonnullByDefault
private void parsePrimitiveValue(String value, Set<Material> materials, Set<Tag<Material>> tags, boolean throwException) throws TagMisconfigurationException {
if (PatternUtils.MINECRAFT_MATERIAL.matcher(value).matches()) {
if (PatternUtils.MINECRAFT_NAMESPACEDKEY.matcher(value).matches()) {
// Match the NamespacedKey against Materials
Material material = Material.matchMaterial(value);

View File

@ -0,0 +1,8 @@
[
{
"value" : 32,
"biomes" : [
"minecraft:nether"
]
}
]

View File

@ -0,0 +1,22 @@
[
{
"value" : 32,
"biomes" : [
"minecraft:nether_wastes",
"minecraft:soul_sand_valley"
]
},
{
"value" : 48,
"biomes" : [
"minecraft:crimson_forest",
"minecraft:warped_forest"
]
},
{
"value" : 64,
"biomes" : [
"minecraft:basalt_deltas"
]
}
]

View File

@ -0,0 +1,89 @@
[
{
"value" : 6,
"biomes" : [
"minecraft:beach",
"minecraft:stone_shore"
]
},
{
"value" : 16,
"biomes" : [
"minecraft:river"
]
},
{
"value" : 20,
"biomes" : [
"minecraft:swamp",
"minecraft:swamp_hills"
]
},
{
"value" : 24,
"biomes" : [
"minecraft:ice_spikes",
"minecraft:frozen_ocean",
"minecraft:frozen_river"
]
},
{
"value" : 40,
"biomes" : [
"minecraft:badlands",
"minecraft:badlands_plateau",
"minecraft:wooded_badlands_plateau",
"minecraft:eroded_badlands",
"minecraft:modified_badlands_plateau",
"minecraft:modified_wooded_badlands_plateau"
]
},
{
"value" : 45,
"biomes" : [
"minecraft:desert",
"minecraft:desert_hills",
"minecraft:desert_lakes"
]
},
{
"value" : 64,
"biomes" : [
"minecraft:ocean",
"minecraft:cold_ocean",
"minecraft:warm_ocean",
"minecraft:lukewarm_ocean"
]
},
{
"value" : 72,
"biomes" : [
"minecraft:deep_ocean",
"minecraft:deep_cold_ocean",
"minecraft:deep_warm_ocean",
"minecraft:deep_lukewarm_ocean"
]
},
{
"value" : 20,
"biomes" : [
"minecraft:mountains",
"minecraft:gravelly_mountains",
"minecraft:mountain_edge"
]
},
{
"value" : 16,
"biomes" : [
"minecraft:snowy_mountains",
"minecraft:snowy_tundra"
]
},
{
"value" : 20,
"biomes" : [
"minecraft:mushroom_fields",
"minecraft:mushroom_field_shore"
]
}
]

View File

@ -0,0 +1,30 @@
[
{
"value" : 20,
"biomes" : [
"minecraft:swamp",
"minecraft:swamp_hills"
]
},
{
"value" : 40,
"biomes" : [
"minecraft:beach",
"minecraft:gravelly_mountains",
"minecraft:stone_shore"
]
},
{
"value" : 60,
"biomes" : [
"minecraft:ocean",
"minecraft:cold_ocean",
"minecraft:warm_ocean",
"minecraft:lukewarm_ocean",
"minecraft:deep_ocean",
"minecraft:deep_cold_ocean",
"minecraft:deep_warm_ocean",
"minecraft:deep_lukewarm_ocean"
]
}
]

View File

@ -0,0 +1,41 @@
[
{
"value" : 5,
"biomes" : [
"minecraft:desert",
"minecraft:beach",
"minecraft:stone_shore"
]
},
{
"value" : 8,
"biomes" : [
"minecraft:mountains",
"minecraft:wooded_mountains",
"minecraft:desert_hills",
"minecraft:wooded_hills",
"minecraft:taiga_hills",
"minecraft:mountain_edge",
"minecraft:jungle_hills",
"minecraft:gravelly_mountains",
"minecraft:taiga_mountains",
"minecraft:tall_birch_hills",
"minecraft:dark_forest_hills",
"minecraft:snowy_taiga_mountains",
"minecraft:giant_spruce_taiga_hills",
"minecraft:modified_gravelly_mountains",
"minecraft:bamboo_jungle_hills"
]
},
{
"value" : 12,
"biomes" : [
"minecraft:badlands",
"minecraft:wooded_badlands_plateau",
"minecraft:modified_wooded_badlands_plateau",
"minecraft:modified_badlands_plateau",
"minecraft:eroded_badlands",
"minecraft:badlands_plateau"
]
}
]

View File

@ -0,0 +1,47 @@
[
{
"value" : 5,
"biomes" : [
"minecraft:desert",
"minecraft:beach",
"minecraft:stone_shore"
]
},
{
"value" : 8,
"biomes" : [
"minecraft:mountains",
"minecraft:wooded_mountains",
"minecraft:desert_hills",
"minecraft:wooded_hills",
"minecraft:taiga_hills",
"minecraft:mountain_edge",
"minecraft:jungle_hills",
"minecraft:gravelly_mountains",
"minecraft:taiga_mountains",
"minecraft:tall_birch_hills",
"minecraft:dark_forest_hills",
"minecraft:snowy_taiga_mountains",
"minecraft:giant_spruce_taiga_hills",
"minecraft:modified_gravelly_mountains",
"minecraft:bamboo_jungle_hills"
]
},
{
"value" : 12,
"biomes" : [
"minecraft:badlands",
"minecraft:wooded_badlands_plateau",
"minecraft:modified_wooded_badlands_plateau",
"minecraft:modified_badlands_plateau",
"minecraft:eroded_badlands",
"minecraft:badlands_plateau"
]
},
{
"value" : 16,
"biomes" : [
"minecraft:basalt_deltas"
]
}
]

View File

@ -0,0 +1,48 @@
[
{
"value" : 5,
"biomes" : [
"minecraft:desert",
"minecraft:beach",
"minecraft:stone_shore"
]
},
{
"value" : 8,
"biomes" : [
"minecraft:mountains",
"minecraft:wooded_mountains",
"minecraft:desert_hills",
"minecraft:wooded_hills",
"minecraft:taiga_hills",
"minecraft:mountain_edge",
"minecraft:jungle_hills",
"minecraft:gravelly_mountains",
"minecraft:taiga_mountains",
"minecraft:tall_birch_hills",
"minecraft:dark_forest_hills",
"minecraft:snowy_taiga_mountains",
"minecraft:giant_spruce_taiga_hills",
"minecraft:modified_gravelly_mountains",
"minecraft:bamboo_jungle_hills"
]
},
{
"value" : 12,
"biomes" : [
"minecraft:badlands",
"minecraft:wooded_badlands_plateau",
"minecraft:modified_wooded_badlands_plateau",
"minecraft:modified_badlands_plateau",
"minecraft:eroded_badlands",
"minecraft:badlands_plateau",
"minecraft:dripstone_caves"
]
},
{
"value" : 16,
"biomes" : [
"minecraft:basalt_deltas"
]
}
]

View File

@ -0,0 +1,15 @@
{
"values" : [
"minecraft:dragon_egg",
"minecraft:gravel",
"minecraft:sand",
"minecraft:red_sand",
"minecraft:scaffolding",
"#minecraft:anvil",
"#slimefun:concrete_powders",
{
"id" : "minecraft:pointed_dripstone",
"required" : false
}
]
}

View File

@ -1,6 +1,7 @@
{
"ADVANCED_CIRCUIT_BOARD" : "Circuit-Boards",
"ADVANCED_INDUSTRIAL_MINER" : "Industrial-Miners",
"AIR_RUNE" : "Ancient-Runes",
"ALUMINUM_BRASS_INGOT" : "Aluminum-Brass-Ingot",
"ALUMINUM_BRONZE_INGOT" : "Aluminum-Bronze-Ingot",
"ALUMINUM_DUST" : "Aluminum-Dust",
@ -8,46 +9,82 @@
"ANCIENT_ALTAR" : "Ancient-Altar",
"ANCIENT_PEDESTAL" : "Ancient-Pedestal",
"ANCIENT_RUNE_SOULBOUND" : "Soulbound-Rune",
"ANDROID_INTERFACE_FUEL" : "Android-Interfaces",
"ANDROID_INTERFACE_ITEMS" : "Android-Interfaces",
"ANDROID_MEMORY_CORE" : "Androids",
"ANIMAL_GROWTH_ACCELERATOR" : "Animal-Growth-Accelerator",
"APPLE_JUICE" : "Juices",
"ARMOR_FORGE" : "Armor-Forge",
"ARMORED_JETBOOTS" : "Jet-Boots",
"ARMORED_JETPACK" : "Jetpacks",
"AUTO_ANVIL" : "Auto-Anvil",
"AUTO_ANVIL_2" : "Auto-Anvil",
"AUTO_BREEDER" : "Auto-Breeder",
"AUTO_BREWER" : "Auto-Brewer",
"AUTO_DISENCHANTER" : "Auto-Disenchanter",
"AUTO_DISENCHANTER_2" : "Auto-Disenchanter",
"AUTO_DRIER" : "Auto-Drier",
"AUTO_ENCHANTER" : "Auto-Enchanter",
"AUTO_ENCHANTER_2" : "Auto-Enchanter",
"AUTOMATED_PANNING_MACHINE" : "Automated-Panning-Machine",
"AUTOMATED_IGNITION_CHAMBER" : "Automated-Ignition-Chamber",
"BANDAGE" : "Medical-Supplies",
"BASIC_CIRCUIT_BOARD" : "Circuit-Boards",
"BATTERY" : "Battery",
"BEE_HELMET" : "Magical-Items#bee-armor",
"BEE_WINGS" : "Magical-Items#bee-armor",
"BEE_LEGGINGS" : "Magical-Items#bee-armor",
"BEE_BOOTS" : "Magical-Items#bee-armor",
"BEEF_JERKY" : "Meat-Jerky",
"BIG_CAPACITOR" : "Energy-Capacitors",
"BILLON_INGOT" : "Billon-Ingot",
"BILLON_JETBOOTS" : "Jet-Boots",
"BILLON_JETPACK" : "Jetpacks",
"BILLON_MULTI_TOOL" : "Multi-Tools",
"BIO_REACTOR" : "Bio-Reactor",
"BIRTHDAY_CAKE" : "Birthday-Seasonal-Category",
"BLADE_OF_VAMPIRES" : "Blade-of-Vampires",
"BLANK_RUNE" : "Ancient-Runes",
"BLISTERING_INGOT" : "Blistering-Ingot",
"BLISTERING_INGOT_2" : "Blistering-Ingot",
"BLISTERING_INGOT_3" : "Blistering-Ingot",
"BLOCK_PLACER" : "Block-Placer",
"BOOK_BINDER" : "Book-Binder",
"BOOSTED_URANIUM" : "Boosted-Uranium",
"BOOTS_OF_THE_STOMPER" : "Magical-Armor#boots-of-the-stomper",
"BOUND_BACKPACK" : "Backpacks",
"BRASS_INGOT" : "Brass-Ingot",
"BROKEN_SPAWNER" : "Broken-Spawner",
"BRONZE_INGOT" : "Bronze-Ingot",
"BUCKET_OF_FUEL" : "Bucket-Of-Fuel",
"BUCKET_OF_OIL" : "Bucket-Of-Oil",
"BUTCHER_ANDROID" : "Butcher-Androids",
"BUTTER" : "Miscellaneous-Items",
"CACTUS_HELMET" : "Armor",
"CACTUS_CHESTPLATE" : "Armor",
"CACTUS_LEGGINGS" : "Armor",
"CACTUS_BOOTS" : "Armor",
"CAN" : "Miscellaneous-Items",
"CARBON" : "Carbon",
"CARBON_CHUNK" : "Carbon",
"CARBON_PRESS" : "Carbon-Press",
"CARBONDAO" : "Carbonado",
"CARBON_PRESS_2" : "Carbon-Press",
"CARBONADO" : "Carbonado",
"CARBONADO_EDGED_CAPACITOR" : "Energy-Capacitors",
"CARBONADO_EDGED_FURNACE" : "Enhanced-Furnaces",
"CARBONADO_JETBOOTS" : "Jet-Boots",
"CARBONADO_JETPACK" : "Jetpacks",
"CARBONADO_MULTI_TOOL" : "Multi-Tools",
"CARGO_INPUT" : "Input-Node",
"CARGO_MANAGER" : "Cargo-Manager",
"CARGO_MOTOR" : "Cargo-Motor",
"CARGO_NODE" : "Connector-Node",
"CARGO_OUTPUT" : "Output-Node",
"CARGO_OUTPUT_ADVANCED" : "Advanced-Output-Node",
"CARGO_NODE_INPUT" : "Input-Node",
"CARGO_NODE_OUTPUT" : "Output-Node",
"CARGO_NODE_OUTPUT_ADVANCED" : "Advanced-Output-Node",
"CARROT_JUICE" : "Juices",
"CHAIN" : "Miscellaneous-Items",
"CHARGING_BENCH" : "Charging-Bench",
"CHEESE" : "Miscellaneous-Items",
"CHICKEN_JERKY" : "Meat-Jerky",
"CHRISTMAS_MILK" : "Christmas-Items",
"CHRISTMAS_CHOCOLATE_MILK" : "Christmas-Items",
@ -63,12 +100,13 @@
"CHRISTMAS_CHOCOLATE_APPLE" : "Christmas-Items",
"CHRISTMAS_PRESENT" : "Christmas-Items",
"CIRCUIT_BOARD" : "Circuit-Board",
"CLOTH" : "Miscellaneous-Items",
"COAL_GENERATOR" : "Coal-Generator",
"COAL_GENERATOR_2" : "Coal-Generator",
"COBALT_INGOT" : "Cobalt-Ingot",
"COBALT_PICKAXE" : "Cobalt-Pickaxe",
"COMBUSTION_REACTOR" : "Combustion-Reactor",
"COMMON_TALISMAN" : "Talismans",
"COMMON_TALISMAN" : "Magical-Items#common-talisman",
"COMPOSTER" : "Composter",
"COMPRESSED_CARBON" : "Carbon",
"COMPRESSOR" : "Compressor",
@ -79,31 +117,65 @@
"COPPER_WIRE" : "Copper-Wire",
"CORINTHIAN_BRONZE_INGOT" : "Corinthian-Bronze-Ingot",
"CROP_GROWTH_ACCELERATOR" : "Crop-Growth-Accelerator",
"CROP_GROWTH_ACCELERATOR_2" : "Crop-Growth-Accelerator",
"CRUCIBLE" : "Crucible",
"CRUSHED_ORE" : "Miscellaneous-Items",
"DAMASCUS_STEEL_BOOTS" : "Armor",
"DAMASCUS_STEEL_CHESTPLATE" : "Armor",
"DAMASCUS_STEEL_HELMET" : "Armor",
"DAMASCUS_STEEL_INGOT" : "Damascus-Steel-Ingot",
"DAMASCUS_STEEL_JETBOOTS" : "Jet-Boots",
"DAMASCUS_STEEL_JETPACK" : "Jetpacks",
"DAMASCUS_STEEL_MULTI_TOOL" : "Multi-Tools",
"DAMASCUS_STEEL_LEGGINGS" : "Armor",
"DIET_COOKIE" : "Diet-Cookie",
"DUCT_TAPE" : "Miscellaneous-Items",
"DURALUMIN_INGOT" : "Duralumin-Ingot",
"DURALUMIN_JETBOOTS" : "Jet-Boots",
"DURALUMIN_JETPACK" : "Jetpacks",
"DURALUMIN_MULTI_TOOL" : "Multi-Tools",
"EARTH_RUNE" : "Ancient-Runes",
"ELECTRIC_DUST_WASHER" : "Electric-Dust-Washer",
"ELECTRIC_DUST_WASHER_2" : "Electric-Dust-Washer",
"ELECTRIC_DUST_WASHER_3" : "Electric-Dust-Washer",
"ELECTRIC_GOLD_PAN" : "Electric-Gold-Pan",
"ELECTRIC_GOLD_PAN_2" : "Electric-Gold-Pan",
"ELECTRIC_GOLD_PAN_3" : "Electric-Gold-Pan",
"ELECTRIC_FURNACE" : "Electric-Furnace",
"ELECTRIC_FURNACE_2" : "Electric-Furnace",
"ELECTRIC_FURNACE_3" : "Electric-Furnace",
"ELECTRIC_INGOT_FACTORY" : "Electric-Ingot-Factory",
"ELECTRIC_INGOT_FACTORY_2" : "Electric-Ingot-Factory",
"ELECTRIC_INGOT_FACTORY_3" : "Electric-Ingot-Factory",
"ELECTRIC_INGOT_PULVERIZER" : "Electric-Ingot-Pulverizer",
"ELECTRIC_MOTOR" : "Electric-Motor",
"ELECTRIC_ORE_GRINDER" : "Electric-Ore-Grinder",
"ELECTRIC_ORE_GRINDER_2" : "Electric-Ore-Grinder",
"ELECTRIC_ORE_GRINDER_3" : "Electric-Ore-Grinder",
"ELECTRIC_PRESS" : "Electric-Press",
"ELECTRIC_PRESS_2" : "Electric-Press",
"ELECTRIC_SMELTERY" : "Electric-Smeltery",
"ELECTRIC_SMELTERY_2" : "Electric-Smeltery",
"ELECTRIFIED_CRUCIBLE" : "Electrified-Crucible",
"ELECTRIFIED_CRUCIBLE_2" : "Electrified-Crucible",
"ELECTRIFIED_CRUCIBLE_3" : "Electrified-Crucible",
"ELECTRO_MAGNET" : "Electromagnet",
"ELEVATOR_PLATE" : "Elevator-Plate",
"ELYTRA" : "Elytras",
"ELYTRA_CAP" : "Magical-Armor#elytra-cap",
"ELYTRA_SCALE" : "Elytras",
"ENCHANTMENT_RUNE" : "Ancient-Runes#enchantment-rune",
"ENDER_BACKPACK" : "Ender-Backpack",
"ENDER_BOOTS" : "Magical-Armor",
"ENDER_CHESTPLATE" : "Magical-Armor",
"ENDER_HELMET" : "Magical-Armor",
"ENDER_LEGGINGS" : "Magical-Armor",
"ENDER_TALISMAN" : "Talismans",
"ENDER_LUMP_1" : "Lumps",
"ENDER_LUMP_2" : "Lumps",
"ENDER_LUMP_3" : "Lumps",
"ENDER_RUNE" : "Ancient-Runes",
"ENERGIZED_CAPACITOR" : "Energy-Capacitors",
"ENERGY_CONNECTOR" : "Energy-Connector",
"ENERGY_REGULATOR" : "Energy-Regulator",
"ENHANCED_CRAFTING_TABLE" : "Enhanced-Crafting-Table",
"ENHANCED_FURNACE" : "Enhanced-Furnaces",
@ -118,21 +190,26 @@
"ENHANCED_FURNACE_10" : "Enhanced-Furnaces",
"ENHANCED_FURNACE_11" : "Enhanced-Furnaces",
"ENRICHED_NETHER_ICE" : "Enriched-Nether-Ice",
"ESSENCE_OF_AFTERLIFE" : "Magical-Items#essence-of-afterlife",
"EXP_COLLECTOR" : "EXP-Collector",
"EXPLOSIVE_BOW" : "Bows",
"EXPLOSIVE_PICKAXE" : "Explosive-Pickaxe",
"EXPLOSIVE_SHOVEL" : "Explosive-Shovel",
"FARMER_ANDROID" : "Farmer-Androids",
"FARMER_SHOES" : "Magical-Armor#farmer-shoes",
"FERROSILICON" : "Ferrosilicon",
"FIRE_RUNE" : "Ancient-Runes",
"FISH_JERKY" : "Meat-Jerky",
"FISHERMAN_ANDROID" : "Fisherman-Androids",
"FLASK_OF_KNOWLEDGE" : "Flask-Of-Knowledge",
"FLUID_PUMP" : "Fluid-Pump",
"FOOD_COMPOSTER" : "Food-Composter",
"FOOD_COMPOSTER_2" : "Food-Composter",
"FOOD_FABRICATOR" : "Food-Fabricator",
"FOOD_FABRICATOR_2" : "Food-Fabricator",
"FORTUNE_COOKIE" : "Fortune-Cookie",
"FREEZER" : "Freezer",
"FREEZER_2" : "Freezer",
"GEO_MINER" : "GEO-Miner",
"GILDED_BACKPACK" : "Backpacks",
"GILDED_IRON" : "Gilded-Iron",
"GILDED_IRON_BOOTS" : "Armor",
"GILDED_IRON_CHESTPLATE" : "Armor",
@ -157,6 +234,7 @@
"GOLD_20K" : "Gold-Ingot",
"GOLD_22K" : "Gold-Ingot",
"GOLD_24K" : "Gold-Ingot",
"GOLD_24K_BLOCK" : "Miscellaneous-Items",
"GOLD_DUST" : "Gold-Dust",
"GOLD_PAN" : "Gold-Pan",
"GOLDEN_APPLE_JUICE" : "Juices",
@ -169,6 +247,9 @@
"GPS_TELEPORTATION_MATRIX" : "GPS-Teleporter-Matrix",
"GPS_TELEPORTER_PYLON" : "GPS-Teleporter-Pylon",
"GPS_TRANSMITTER" : "GPS-Transmitter",
"GPS_TRANSMITTER_2" : "GPS-Transmitter",
"GPS_TRANSMITTER_3" : "GPS-Transmitter",
"GPS_TRANSMITTER_4" : "GPS-Transmitter",
"GRAPPLING_HOOK" : "Grappling-Hook",
"GRANDMAS_WALKING_STICK" : "Walking-Sticks",
"GRANDPAS_WALKING_STICK" : "Walking-Sticks",
@ -177,42 +258,92 @@
"HARDENED_METAL_INGOT" : "Hardened-Metal",
"HAZMAT_CHESTPLATE" : "Hazmat-Suit",
"HAZMAT_LEGGINGS" : "Hazmat-Suit",
"HEATED_PRESSURE_CHAMBER" : "Heated-Pressure-Chamber",
"HEATED_PRESSURE_CHAMBER_2" : "Heated-Pressure-Chamber",
"HEATING_COIL" : "Heating-Coil",
"HEAVY_CREAM" : "Miscellaneous-Items",
"HERCULES_PICKAXE" : "Hercules'-Pickaxe",
"HOLOGRAM_PROJECTOR" : "Hologram-Projector",
"HOOK" : "Miscellaneous-Items",
"ICY_BOW" : "Bows",
"IGNITION_CHAMBER" : "Automatic-Ignition-Chamber",
"INDUSTRIAL_MINER" : "Industrial-Miners",
"INFERNAL_BONEMEAL" : "Infernal-Bonemeal",
"INFUSED_ELYTRA" : "Elytras",
"INFUSED_HOPPER" : "Infused-Hopper",
"INFUSED_MAGNET" : "Infused-Magnet",
"IRON_GOLEM_ASSEMBLER" : "Iron-Golem-Assembler",
"JUICER" : "Juicer",
"IRON_DUST" : "Iron-Dust",
"KELP_COOKIE" : "Kelp-Cookie",
"LARGE_BACKPACK" : "Backpacks",
"LARGE_CAPACITOR" : "Energy-Capacitors",
"LAVA_CRYSTAL" : "Magical-Items#lava-crystal",
"LAVA_GENERATOR" : "Lava-Generator",
"LAVA_GENERATOR_2" : "Lava-Generator",
"LEAD_DUST" : "Lead-Dust",
"LEAD_INGOT" : "Lead-Ingot",
"LIGHTNING_RUNE" : "Ancient-Runes",
"LUMBER_AXE" : "Lumber-Axe",
"MAGIC_EYE_OF_ENDER" : "Magic-Eye-Of-Ender",
"MAGICAL_BOOK_COVER" : "Magical-Items#magical-book-cover",
"MAGICAL_GLASS" : "Magical-Items#magical-glass",
"MAGICAL_ZOMBIE_PILLS" : "Magical-Zombie-Pills",
"MAGIC_LUMP_1" : "Lumps",
"MAGIC_LUMP_2" : "Lumps",
"MAGIC_LUMP_3" : "Lumps",
"MAGIC_SUGAR" : "Magic-Sugar",
"MAGIC_WORKBENCH" : "Magic-Workbench",
"MAGIC_ZOMBIE_PILL" : "Magic-Zombie-Pills",
"MAGNESIUM_DUST" : "Magnesium-Dust",
"MAGNESIUM_INGOT" : "Magnesium-Ingot",
"MAGNESIUM_GENERATOR" : "Magnesium-powered-Generator",
"MAGNESIUM_SALT" : "Magnesium-Salt",
"MAGNESIUM_POWERED_GENERATOR" : "Magnesium-powered-Generator",
"MAGNET" : "Magnet",
"MEDICINE" : "Medical-Supplies",
"MEDIUM_BACKPACK" : "Backpacks",
"MEDIUM_CAPACITOR" : "Energy-Capacitors",
"MELON_JUICE" : "Juices",
"MINER_ANDROID" : "Miner-Andoirds",
"MONSTER_JERKY" : "Monster-Jerky",
"MULTIMETER" : "Technical-Gadgets#multimeter",
"MUTTON_JERKY" : "Meat-Jerky",
"NECROTIC_SKULL" : "Magical-Items#necrotic-skull",
"NEPTUNIUM" : "Neptunium",
"NETHERSTAR_REACTOR" : "Reactors",
"NETHER_GOLD_PAN" : "Nether-Gold-Pan",
"NETHER_ICE" : "Nether-Ice",
"NETHER_ICE_COOLANT_CELL" : "Coolant-Cells",
"NICKEL_INGOT" : "Nickel-Ingot",
"NIGHT_VISION_GOGGLES" : "Technical-Gadgets#night-vision-goggles",
"NUCLEAR_REACTOR" : "Reactors",
"OIL_PUMP" : "Oil-Pump",
"ORE_CRUSHER" : "Ore-Crusher",
"ORE_WASHER" : "Ore-Washer",
"ORGANIC_FOOD" : "Miscellaneous-Items",
"ORGANIC_FOOD_WHEAT" : "Miscellaneous-Items",
"ORGANIC_FOOD_CARROT" : "Miscellaneous-Items",
"ORGANIC_FOOD_POTATO" : "Miscellaneous-Items",
"ORGANIC_FOOD_SEEDS" : "Miscellaneous-Items",
"ORGANIC_FOOD_BEETROOT" : "Miscellaneous-Items",
"ORGANIC_FOOD_MELON" : "Miscellaneous-Items",
"ORGANIC_FOOD_APPLE" : "Miscellaneous-Items",
"ORGANIC_FOOD_SWEET_BERRIES" : "Miscellaneous-Items",
"ORGANIC_FOOD_KELP" : "Miscellaneous-Items",
"ORGANIC_FOOD_COCOA" : "Miscellaneous-Items",
"FERTILIZER_FOOD" : "Miscellaneous-Items",
"FERTILIZER_WHEAT" : "Miscellaneous-Items",
"FERTILIZER_CARROT" : "Miscellaneous-Items",
"FERTILIZER_POTATO" : "Miscellaneous-Items",
"FERTILIZER_SEEDS" : "Miscellaneous-Items",
"FERTILIZER_BEETROOT" : "Miscellaneous-Items",
"FERTILIZER_MELON" : "Miscellaneous-Items",
"FERTILIZER_APPLE" : "Miscellaneous-Items",
"FERTILIZER_SWEET_BERRIES" : "Miscellaneous-Items",
"FERTILIZER_KELP" : "Miscellaneous-Items",
"FERTILIZER_COCOA" : "Miscellaneous-Items",
"OUTPUT_CHEST" : "Output-Chest",
"PARACHUTE" : "Technical-Gadgets#parachute",
"PICKAXE_OF_CONTAINMENT" : "Pickaxe-of-Containment",
"PICKAXE_OF_VEIN_MINING" : "Pickaxe-of-Vein-Mining",
"PICKAXE_OF_THE_SEEKER" : "Pickaxe-of-the-Seeker",
@ -220,33 +351,73 @@
"PORTABLE_CRAFTER" : "Portable-Crafter",
"PORTABLE_DUSTBIN" : "Portable-Dustbin",
"PORTABLE_GEO_SCANNER" : "Portable-Geo-Scanner",
"PORTABLE_TELEPORTER" : "Portable-Teleporter",
"PORK_JERKY" : "Meat-Jerky",
"POWER_CRYSTAL" : "Power-Crystal",
"PRESSURE_CHAMBER" : "Pressure-Chamber",
"PRODUCE_COLLECTOR" : "Produce-Collector",
"PROGRAMMABLE_ANDROID" : "Normal-Androids",
"PROGRAMMABLE_ANDROID_BUTCHER" : "Butcher-Androids",
"PROGRAMMABLE_ANDROID_FARMER" : "Farmer-Androids",
"PROGRAMMABLE_ANDROID_FISHERMAN" : "Fisherman-Androids",
"PROGRAMMABLE_ANDROID_MINER" : "Miner-Androids",
"PROGRAMMABLE_ANDROID_WOODCUTTER" : "Woodcutter-Androids",
"PROGRAMMABLE_ANDROID_2" : "Normal-Androids",
"PROGRAMMABLE_ANDROID_2_BUTCHER" : "Butcher-Androids",
"PROGRAMMABLE_ANDROID_2_FARMER" : "Farmer-Androids",
"PROGRAMMABLE_ANDROID_2_FISHERMAN" : "Fisherman-Androids",
"PROGRAMMABLE_ANDROID_3" : "Normal-Androids",
"PROGRAMMABLE_ANDROID_3_BUTCHER" : "Butcher-Androids",
"PROGRAMMABLE_ANDROID_3_FISHERMAN" : "Fisherman-Androids",
"PULVERIZED_ORE" : "Miscellaneous-Items",
"PUMPKIN_JUICE" : "Juices",
"PURE_ORE_CLUSTER" : "Miscellaneous-Items",
"RABBIT_JERKY" : "Meat-Jerky",
"RADIANT_BACKPACK" : "Backpacks",
"RAG": "Medical-Supplies",
"RAINBOW_CLAY" : "Rainbow-Blocks",
"RAINBOW_CLAY_HALLOWEEN" : "Halloween-Seasonal-Category",
"RAINBOW_CLAY_VALENTINE" : "Valentines-Day-Seasonal-Category",
"RAINBOW_CLAY_XMAS" : "Christmas-Seasonal-Category",
"RAINBOW_CONCRETE" : "Rainbow-Blocks",
"RAINBOW_CONCRETE_HALLLOWEEN" : "Halloween-Seasonal-Category",
"RAINBOW_CONCRETE_VALENTINE" : "Valentines-Day-Seasonal-Category",
"RAINBOW_CONCRETE_XMAS" : "Christmas-Seasonal-Category",
"RAINBOW_GLASS" : "Rainbow-Blocks",
"RAINBOW_GLASS_HALLOWEEN" : "Halloween-Seasonal-Category",
"RAINBOW_GLASS_VALENTINE" : "Valentines-Day-Seasonal-Category",
"RAINBOW_GLASS_XMAS" : "Christmas-Seasonal-Category",
"RAINBOW_GLASS_PANE" : "Rainbow-Blocks",
"RAINBOW_GLASS_PANE_HALLOWEEN" : "Halloween-Seasonal-Category",
"RAINBOW_GLASS_PANE_VALENTINE" : "Valentines-Day-Seasonal-Category",
"RAINBOW_GLASS_PANE_XMAS" : "Christmas-Seasonal-Category",
"RAINBOW_GLAZED_TERRACOTTA" : "Rainbow-Blocks",
"RAINBOW_GLAZED_TERRACOTTA_HALLOWEEN" : "Halloween-Seasonal-Category",
"RAINBOW_GLAZED_TERRACOTTA_VALENTINE" : "Valentines-Day-Seasonal-Category",
"RAINBOW_GLAZED_TERRACOTTA_XMAS" : "Christmas-Seasonal-Category",
"RAINBOW_RUNE" : "Ancient-Runes",
"RAINBOW_WOOL" : "Rainbow-Blocks",
"RAINBOW_WOOL_HALLOWEEN" : "Halloween-Seasonal-Category",
"RAINBOW_WOOL_VALENTINE" : "Valentines-Day-Seasonal-Category",
"RAINBOW_WOOL_XMAS" : "Christmas-Seasonal-Category",
"REACTOR_COOLANT_CELL" : "Coolant-Cells",
"RAW_CARBONADO" : "Carbonado",
"REACTOR_ACCESS_PORT" : "Reactors#reactor-access-port",
"REACTOR_COLLANT_CELL" : "Coolant-Cells",
"REDSTONE_ALLOY" : "Redstone-Alloy-Ingot",
"REFINERY" : "Refinery",
"REINFORCED_ALLOY_BOOTS" : "Armor",
"REINFORCED_ALLOY_CHESTPLATE" : "Armor",
"REINFORCED_ALLOY_HELMET" : "Armor",
"REINFORCED_ALLOY_INGOT" : "Reinforced-Alloy-Ingot",
"REINFORCED_ALLOY_JETBOOTS" : "Jet-Boots",
"REINFORCED_ALLOY_JETPACK" : "Jetpacks",
"REINFORCED_ALLOY_MULTI_TOOL" : "Multi-Tools",
"REINFORCED_ALLOY_LEGGINGS" : "Armor",
"REINFORCED_FURNACE" : "Enhanced-Furnaces",
"REPAIRED_SPAWNER" : "Reinforced-Spawner",
"REINFORCED_PLATE" : "Miscellaneous-Items",
"REINFORCED_SPAWNER" : "Reinforced-Spawner",
"RUBBER_BOOTS" : "Hazmat-Suit",
"SALT" : "Miscellaneous-Items",
"SCUBA_HELMET" : "Hazmat-Suit",
"SCROLL_OF_DIMENSIONAL_TELEPOSITION" : "Scroll-of-Dimensional-Teleposition",
"SEISMIC_AXE" : "Seismic-Axe",
@ -254,7 +425,9 @@
"SILICON" : "Silicon",
"SILVER_DUST" : "Silver-Dust",
"SILVER_INGOT" : "Silver-Ingot",
"SMALL_BACKPACK" : "Backpacks",
"SMALL_CAPACITOR" : "Energy-Capacitors",
"SMALL_UURANIUM" : "Miscellaneous-Items",
"SMELTERS_PICKAXE" : "Smelter's-Pickaxe",
"SMELTERY" : "Smeltery",
"SLIME_BOOTS" : "Magical-Armor",
@ -269,8 +442,12 @@
"SOLAR_GENERATOR_2" : "Solar-Generator",
"SOLAR_GENERATOR_3" : "Solar-Generator",
"SOLAR_GENERATOR_4" : "Solar-Generator",
"SOLAR_HELMET" : "Technical-Gadgets#solar-helmet",
"SOLAR_PANEL" : "Solar-Panel",
"SOLDER_INGOT" : "Solder-Ingot",
"SOLDER_JETBOOTS" : "Jet-Boots",
"SOLDER_JETPACK" : "Jetpacks",
"SOLDER_MULTI_TOOL" : "Multi-Tools",
"SOULBOUND_AXE" : "Soulbound-Weapons",
"SOULBOUND_BOOTS" : "Soulbound-Armor",
"SOULBOUND_BOW" : "Soulbound-Weapons",
@ -280,28 +457,53 @@
"SOULBOUND_HOE" : "Soulbound-Weapons",
"SOULBOUND_LEGGINGS" : "Soulbound-Armor",
"SOULBOUND_PICKAXE" : "Soulbound-Weapons",
"SOULBOUND_RUNE" : "Ancient-Runes#soulbound-rune",
"SOULBOUND_SHOVEL" : "Soulbound-Weapons",
"SOULBOUND_SWORD" : "Soulbound-Weapons",
"SOULBOUND_TRIDENT" : "Soulbound-Weapons",
"SPLINT" : "Medical-Supplies",
"STAFF_ELEMENTAL" : "Elemental-Staves",
"STAFF_ELEMENTAL_WIND" : "Elemental-Staves",
"STAFF_ELEMENTAL_FIRE" : "Elemental-Staves",
"STAFF_ELEMENTAL_WATER" : "Elemental-Staves",
"STAFF_ELEMENTAL_STORM" : "Elemental-Staves",
"STEEL_INGOT" : "Steel-Ingot",
"STEEL_JETBOOTS" : "Jet-Boots",
"STEEL_JETPACK" : "Jetpacks",
"STEEL_MULTI_TOOL" : "Multi-Tools",
"STEEL_PLATE" : "Miscellaneous-Items",
"STEEL_THRUSTER" : "Steel-Thruster",
"STONE_CHUNK" : "Miscellaneous-Items",
"STRANGE_NETHER_GOO" : "Magical-Items#strange-nether-goo",
"SULFATE" : "Sulfate",
"SYNTHETIC_DIAMOND" : "Synthetic-Diamond",
"SYNTHETIC_EMERALD" : "Synthetic-Emerald",
"SYNTHETIC_SAPPHIRE" : "Synthetic-Sapphire",
"SYNTHETIC_SHULKER_SHELL" : "Magical-Items#synthetic-shulker-shell",
"SWEET_BERRY_JUICE" : "Juices",
"SWORD_OF_BEHEADING" : "Sword-of-Beheading",
"TABLE_SAW" : "Table-Saw",
"TALISMAN_ANVIL" : "Talismans",
"TELEPORTER" : "Teleporter",
"TIN_DUST" : "Tin-Dust",
"TIN_INGOT" : "Tin-Ingot",
"TINY_URANIUM" : "Miscellaneous-Items",
"TOME_OF_KNOWLEDGE_SHARING" : "Tome-Of-Knowledge-Sharing",
"TOTEM_OF_UNDYING" : "Totem-Of-Undying",
"TRASH_CAN" : "Trash-Can",
"TRASH_CAN_BLOCK" : "Trash-Can",
"TREE_GROWTH_ACCELERATOR" : "Tree-Growth-Accelerator",
"TRIDENT" : "Magical-Gadgets",
"URANIUM" : "Uranium",
"VILLAGER_RUNE" : "Ancient-Runes",
"VITAMINS" : "Medical-Supplies",
"WATER_RUNE" : "Ancient-Runes",
"WHEAT_FLOUR" : "Miscellaneous-Items",
"WITHER_ASSEMBLER" : "Wither-Assembler",
"WITHER_PROOF_OBSIDIAN" : "Wither-Proof-Blocks",
"WITHER_PROOF_GLASS" : "Wither-Proof-Blocks",
"WOODCUTTER_ANDROID" : "Woodcutter-Androids",
"WOVEN_BACKPACK" : "Backpacks",
"XP_COLLECTOR" : "EXP-Collector",
"ZINC_DUST" : "Zinc-Dust",
"ZINC_INGOT" : "Zinc-Ingot"
}

View File

@ -78,7 +78,7 @@ class TestResourceRegistration {
Assertions.assertNotEquals(0, resource.getDefaultSupply(Environment.NORMAL, Biome.BEACH));
Assertions.assertTrue(resource.getDefaultSupply(Environment.NORMAL, Biome.DESERT) > 10);
// Assertions.assertTrue(resource.getDefaultSupply(Environment.NORMAL, Biome.MOUNTAINS) > 10);
// Assertions.assertTrue(resource.getDefaultSupply(Environment.NORMAL, Biome.MOUNTAINS) > 10);
Assertions.assertTrue(resource.getDefaultSupply(Environment.NORMAL, Biome.ICE_SPIKES) > 10);
Assertions.assertTrue(resource.getDefaultSupply(Environment.NORMAL, Biome.BADLANDS) > 10);
Assertions.assertTrue(resource.getDefaultSupply(Environment.NORMAL, Biome.OCEAN) > 10);
@ -115,8 +115,8 @@ class TestResourceRegistration {
Assertions.assertEquals(0, resource.getDefaultSupply(Environment.NETHER, Biome.NETHER_WASTES));
Assertions.assertEquals(0, resource.getDefaultSupply(Environment.THE_END, Biome.THE_END));
Assertions.assertNotEquals(0, resource.getDefaultSupply(Environment.NORMAL, Biome.COLD_OCEAN));
Assertions.assertTrue(resource.getDefaultSupply(Environment.NORMAL, Biome.BEACH) > 10);
Assertions.assertTrue(resource.getDefaultSupply(Environment.NORMAL, Biome.OCEAN) > 10);
Assertions.assertTrue(resource.getDefaultSupply(Environment.NORMAL, Biome.SWAMP) > 10);

View File

@ -0,0 +1,115 @@
package io.github.thebusybiscuit.slimefun4.utils.biomes;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Biome;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import com.google.gson.JsonElement;
import io.github.thebusybiscuit.slimefun4.api.exceptions.BiomeMapException;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import be.seeseemelk.mockbukkit.MockBukkit;
class TestBiomeMap {
private static final BiomeDataConverter<String> AS_STRING = JsonElement::getAsString;
private static final BiomeDataConverter<Integer> AS_INT = JsonElement::getAsInt;
private static Slimefun plugin;
private static NamespacedKey key;
@BeforeAll
public static void load() {
MockBukkit.mock();
plugin = MockBukkit.load(Slimefun.class);
key = new NamespacedKey(plugin, "test");
}
@AfterAll
public static void unload() {
MockBukkit.unmock();
}
@Test
@DisplayName("Test BiomeMap#getKey")
void testKeyed() {
BiomeMap<String> biomes = new BiomeMap<>(key);
Assertions.assertEquals(key, biomes.getKey());
}
@Test
@DisplayName("Test BiomeMap#toString")
void testToString() {
BiomeMap<String> biomes = new BiomeMap<>(key);
Assertions.assertTrue(biomes.toString().startsWith("BiomeMap"));
}
@Test
@DisplayName("Test different value converters")
void testValueConversion() {
Biome biome = Biome.OCEAN;
String stringValue = "hello world";
BiomeMap<String> stringMap = createBiomeMap(AS_STRING, "[{\"value\": \"" + stringValue + "\", \"biomes\": [\"" + biome.getKey() + "\"]}]");
Assertions.assertEquals(stringValue, stringMap.get(biome));
int intValue = 1024;
BiomeMap<Integer> intMap = createBiomeMap(AS_INT, "[{\"value\": \"" + intValue + "\", \"biomes\": [\"" + biome.getKey() + "\"]}]");
Assertions.assertEquals(intValue, intMap.get(biome));
}
@Test
@DisplayName("Test working BiomeMap from JSON")
void testBiomeMapFromJson() {
Biome biome1 = Biome.JUNGLE;
Biome biome2 = Biome.OCEAN;
Biome biome3 = Biome.DESERT;
BiomeMap<Integer> biomes = createBiomeMap(AS_INT, "[{\"value\":1,\"biomes\":[\"" + biome1.getKey() + "\", \"" + biome2.getKey() + "\"]}, {\"value\":2, \"biomes\":[\"" + biome3.getKey() + "\"]}]");
Assertions.assertTrue(biomes.containsKey(biome1));
Assertions.assertEquals(1, biomes.get(biome1));
Assertions.assertTrue(biomes.containsKey(biome2));
Assertions.assertEquals(1, biomes.get(biome2));
Assertions.assertTrue(biomes.containsKey(biome3));
Assertions.assertEquals(2, biomes.get(biome3));
}
@Test
@DisplayName("Test working BiomeMap manually")
void testManualBiomeMap() {
BiomeMap<String> biomes = new BiomeMap<>(key);
Biome biome = Biome.OCEAN;
String value = "Under the sea";
Assertions.assertTrue(biomes.put(biome, value));
Assertions.assertTrue(biomes.containsKey(biome));
Assertions.assertEquals(value, biomes.get(biome));
Assertions.assertTrue(biomes.remove(biome));
Assertions.assertFalse(biomes.containsKey(biome));
}
@ParametersAreNonnullByDefault
private @Nonnull <T> BiomeMap<T> createBiomeMap(BiomeDataConverter<T> function, String json) {
BiomeMapParser<T> parser = new BiomeMapParser<>(key, function);
try {
parser.read(json);
} catch (BiomeMapException e) {
Assertions.fail(e);
}
return parser.buildBiomeMap();
}
}

View File

@ -0,0 +1,175 @@
package io.github.thebusybiscuit.slimefun4.utils.biomes;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.MethodSource;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import be.seeseemelk.mockbukkit.MockBukkit;
/**
* This test checks if biome maps work across multiple versions of Minecraft.
* A similar test can be written for Material Tags :?
*
* @author TheBusyBiscuit
*
*/
class TestBiomeMapCompatibility {
private static final Map<MinecraftVersion, JsonArray> compatibilityMap = new EnumMap<>(MinecraftVersion.class);
@BeforeAll
public static void load() {
MockBukkit.mock();
for (MinecraftVersion version : MinecraftVersion.values()) {
if (!version.isVirtual()) {
loadBiomes(version);
}
}
}
@AfterAll
public static void unload() {
MockBukkit.unmock();
}
private static void loadBiomes(@Nonnull MinecraftVersion version) {
String path = "/biomes/" + version.getName() + ".json";
if (Slimefun.class.getResource(path) == null) {
return;
}
try (BufferedReader reader = new BufferedReader(new InputStreamReader(Slimefun.class.getResourceAsStream(path), StandardCharsets.UTF_8))) {
JsonParser parser = new JsonParser();
JsonArray biomes = parser.parse(reader.lines().collect(Collectors.joining(""))).getAsJsonArray();
compatibilityMap.put(version, biomes);
} catch (IOException x) {
x.printStackTrace();
}
}
@ParameterizedTest(name = "Test if {0} has a biome resource")
@EnumSource(value = MinecraftVersion.class)
void testMissingBiomeResources(@Nonnull MinecraftVersion version) {
if (!version.isVirtual()) {
Assertions.assertTrue(compatibilityMap.containsKey(version));
}
}
@ParameterizedTest(name = "Test if biome-map {0}.json is compatible with {1}")
@MethodSource("biomeMaps")
@ParametersAreNonnullByDefault
void testCompatibilities(String name, MinecraftVersion version) {
assertCompatibility(name, version);
}
/**
* We manually specify here which biome map works on which minecraft versions.
*
* @return A {@link Stream} of {@link Arguments} for our unit test.
*/
private static @Nonnull Stream<Arguments> biomeMaps() {
Map<String, MinecraftVersion[]> testCases = new HashMap<>();
// @formatter:off
testCases.put("nether_ice_v1.14", new MinecraftVersion[] {
MinecraftVersion.MINECRAFT_1_14,
MinecraftVersion.MINECRAFT_1_15
});
testCases.put("nether_ice_v1.16", new MinecraftVersion[] {
MinecraftVersion.MINECRAFT_1_16,
MinecraftVersion.MINECRAFT_1_17
});
testCases.put("oil_v1.14", new MinecraftVersion[] {
MinecraftVersion.MINECRAFT_1_14,
MinecraftVersion.MINECRAFT_1_15,
MinecraftVersion.MINECRAFT_1_16,
MinecraftVersion.MINECRAFT_1_17
});
testCases.put("salt_v1.14", new MinecraftVersion[] {
MinecraftVersion.MINECRAFT_1_14,
MinecraftVersion.MINECRAFT_1_15,
MinecraftVersion.MINECRAFT_1_16,
MinecraftVersion.MINECRAFT_1_17
});
testCases.put("uranium_v1.14", new MinecraftVersion[] {
MinecraftVersion.MINECRAFT_1_14,
MinecraftVersion.MINECRAFT_1_15
});
testCases.put("uranium_v1.16", new MinecraftVersion[] {
MinecraftVersion.MINECRAFT_1_16
});
testCases.put("uranium_v1.17", new MinecraftVersion[] {
MinecraftVersion.MINECRAFT_1_17
});
// @formatter:on
return testCases.entrySet().stream().flatMap(entry -> {
return Arrays.stream(entry.getValue()).map(version -> Arguments.of(entry.getKey(), version));
});
}
@ParametersAreNonnullByDefault
private void assertCompatibility(String name, MinecraftVersion version) {
JsonArray allBiomes = compatibilityMap.get(version);
String path = "/biome-maps/" + name + ".json";
try (BufferedReader reader = new BufferedReader(new InputStreamReader(Slimefun.class.getResourceAsStream(path), StandardCharsets.UTF_8))) {
JsonParser parser = new JsonParser();
JsonArray root = parser.parse(reader.lines().collect(Collectors.joining(""))).getAsJsonArray();
for (JsonElement element : root) {
JsonArray biomes = element.getAsJsonObject().getAsJsonArray("biomes");
checkBiomes(biomes, allBiomes, version);
}
} catch (IOException x) {
Assertions.fail(x);
}
}
@ParametersAreNonnullByDefault
private void checkBiomes(JsonArray biomes, JsonArray allBiomes, MinecraftVersion version) {
for (JsonElement biome : biomes) {
/*
* Assert that this biome exists within the list of all biomes
* for this version of Minecraft.
*/
Assertions.assertTrue(allBiomes.contains(biome), "Biome \"" + biome.getAsString() + "\" does not exist on Minecraft " + version.getName());
}
}
}

View File

@ -0,0 +1,135 @@
package io.github.thebusybiscuit.slimefun4.utils.biomes;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Biome;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import com.google.gson.JsonElement;
import io.github.thebusybiscuit.slimefun4.api.exceptions.BiomeMapException;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import be.seeseemelk.mockbukkit.MockBukkit;
class TestBiomeMapParser {
private static final BiomeDataConverter<String> AS_STRING = JsonElement::getAsString;
private static final BiomeDataConverter<Integer> AS_INT = JsonElement::getAsInt;
private static Slimefun plugin;
private static NamespacedKey key;
@BeforeAll
public static void load() {
MockBukkit.mock();
plugin = MockBukkit.load(Slimefun.class);
key = new NamespacedKey(plugin, "test");
}
@AfterAll
public static void unload() {
MockBukkit.unmock();
}
@Test
@DisplayName("Test JSON Parsing Error handling")
void testInvalidJson() {
assertMisconfiguration(AS_STRING, "");
assertMisconfiguration(AS_STRING, "1234");
assertMisconfiguration(AS_STRING, "hello world");
assertMisconfiguration(AS_STRING, "{}");
}
@Test
@DisplayName("Test Array not having proper children")
void testInvalidArrayChildren() {
assertMisconfiguration(AS_STRING, "[1, 2, 3]");
assertMisconfiguration(AS_STRING, "[[1], [2]]");
assertMisconfiguration(AS_STRING, "[\"foo\", \"bar\"]");
}
@Test
@DisplayName("Test Array entries being misconfigured")
void testInvalidEntries() {
assertMisconfiguration(AS_STRING, "[{}]");
assertMisconfiguration(AS_STRING, "[{\"id\": \"one\"}]");
}
@Test
@DisplayName("Test Array entries being incomplete")
void testIncompleteEntries() {
assertMisconfiguration(AS_STRING, "[{\"value\": \"cool\"}]");
assertMisconfiguration(AS_STRING, "[{\"biomes\": []}]");
}
@Test
@DisplayName("Test Biome entry being misconfigured")
void testInvalidBiomeEntry() {
assertMisconfiguration(AS_STRING, "[{\"value\": \"hello\", \"biomes\": {}}]");
assertMisconfiguration(AS_STRING, "[{\"value\": \"hello\", \"biomes\": 1234}]");
assertMisconfiguration(AS_STRING, "[{\"value\": \"hello\", \"biomes\": \"I am Groot.\"}]");
}
@Test
@DisplayName("Test unknown Biomes")
void testUnknownBiomes() {
assertMisconfiguration(AS_INT, "[{\"value\": 1, \"biomes\": [1, 2, 3]}]");
assertMisconfiguration(AS_INT, "[{\"value\": 1, \"biomes\": [\"hello world\"]}]");
assertMisconfiguration(AS_INT, "[{\"value\": 1, \"biomes\": [\"slimefun:slime_forest\"]}]");
assertMisconfiguration(AS_INT, "[{\"value\": 1, \"biomes\": [\"minecraft:walshy_desert\"]}]");
}
@Test
@DisplayName("Test double Biome registration")
void testDoubleBiomes() {
Biome biome = Biome.OCEAN;
assertMisconfiguration(AS_INT, "[{\"value\": 1, \"biomes\": [\"" + biome.getKey() + "\"]}, {\"value\": 2, \"biomes\": [\"" + biome.getKey() + "\"]}]");
}
@Test
@DisplayName("Test BiomeMapParser being not lenient by default")
void testParserNotLenientByDefault() {
BiomeMapParser<Integer> parser = new BiomeMapParser<>(key, AS_INT);
// Test default value
Assertions.assertFalse(parser.isLenient());
}
@ParameterizedTest
@ValueSource(booleans = { true, false })
@DisplayName("Test lenient parser")
void testLenientParsing(boolean isLenient) {
BiomeMapParser<Integer> parser = new BiomeMapParser<>(key, AS_INT);
parser.setLenient(isLenient);
Assertions.assertEquals(isLenient, parser.isLenient());
/*
* I picked a random String here.
* If this biome will exist in Minecraft one day... then you saw it here first, folks ;D
*/
String json = "[{\"value\": 2048, \"biomes\": [\"minecraft:thebusybiscuits_wonderland\"]}]";
if (isLenient) {
Assertions.assertDoesNotThrow(() -> parser.read(json));
} else {
Assertions.assertThrows(BiomeMapException.class, () -> parser.read(json));
}
}
@ParametersAreNonnullByDefault
private <T> void assertMisconfiguration(BiomeDataConverter<T> function, String json) {
BiomeMapParser<T> parser = new BiomeMapParser<>(key, function);
Assertions.assertThrows(BiomeMapException.class, () -> parser.read(json));
}
}

View File

@ -0,0 +1,77 @@
[
"minecraft:ocean",
"minecraft:plains",
"minecraft:desert",
"minecraft:mountains",
"minecraft:forest",
"minecraft:taiga",
"minecraft:swamp",
"minecraft:river",
"minecraft:nether",
"minecraft:the_end",
"minecraft:frozen_ocean",
"minecraft:frozen_river",
"minecraft:snowy_tundra",
"minecraft:snowy_mountains",
"minecraft:mushroom_fields",
"minecraft:mushroom_field_shore",
"minecraft:beach",
"minecraft:desert_hills",
"minecraft:wooded_hills",
"minecraft:taiga_hills",
"minecraft:mountain_edge",
"minecraft:jungle",
"minecraft:jungle_hills",
"minecraft:jungle_edge",
"minecraft:deep_ocean",
"minecraft:stone_shore",
"minecraft:snowy_beach",
"minecraft:birch_forest",
"minecraft:birch_forest_hills",
"minecraft:dark_forest",
"minecraft:snowy_taiga",
"minecraft:snowy_taiga_hills",
"minecraft:giant_tree_taiga",
"minecraft:giant_tree_taiga_hills",
"minecraft:wooded_mountains",
"minecraft:savanna",
"minecraft:savanna_plateau",
"minecraft:badlands",
"minecraft:wooded_badlands_plateau",
"minecraft:badlands_plateau",
"minecraft:small_end_islands",
"minecraft:end_midlands",
"minecraft:end_highlands",
"minecraft:end_barrens",
"minecraft:warm_ocean",
"minecraft:lukewarm_ocean",
"minecraft:cold_ocean",
"minecraft:deep_warm_ocean",
"minecraft:deep_lukewarm_ocean",
"minecraft:deep_cold_ocean",
"minecraft:deep_frozen_ocean",
"minecraft:the_void",
"minecraft:sunflower_plains",
"minecraft:desert_lakes",
"minecraft:gravelly_mountains",
"minecraft:flower_forest",
"minecraft:taiga_mountains",
"minecraft:swamp_hills",
"minecraft:ice_spikes",
"minecraft:modified_jungle",
"minecraft:modified_jungle_edge",
"minecraft:tall_birch_forest",
"minecraft:tall_birch_hills",
"minecraft:dark_forest_hills",
"minecraft:snowy_taiga_mountains",
"minecraft:giant_spruce_taiga",
"minecraft:giant_spruce_taiga_hills",
"minecraft:modified_gravelly_mountains",
"minecraft:shattered_savanna",
"minecraft:shattered_savanna_plateau",
"minecraft:eroded_badlands",
"minecraft:modified_wooded_badlands_plateau",
"minecraft:modified_badlands_plateau",
"minecraft:bamboo_jungle",
"minecraft:bamboo_jungle_hills"
]

View File

@ -0,0 +1,77 @@
[
"minecraft:ocean",
"minecraft:plains",
"minecraft:desert",
"minecraft:mountains",
"minecraft:forest",
"minecraft:taiga",
"minecraft:swamp",
"minecraft:river",
"minecraft:nether",
"minecraft:the_end",
"minecraft:frozen_ocean",
"minecraft:frozen_river",
"minecraft:snowy_tundra",
"minecraft:snowy_mountains",
"minecraft:mushroom_fields",
"minecraft:mushroom_field_shore",
"minecraft:beach",
"minecraft:desert_hills",
"minecraft:wooded_hills",
"minecraft:taiga_hills",
"minecraft:mountain_edge",
"minecraft:jungle",
"minecraft:jungle_hills",
"minecraft:jungle_edge",
"minecraft:deep_ocean",
"minecraft:stone_shore",
"minecraft:snowy_beach",
"minecraft:birch_forest",
"minecraft:birch_forest_hills",
"minecraft:dark_forest",
"minecraft:snowy_taiga",
"minecraft:snowy_taiga_hills",
"minecraft:giant_tree_taiga",
"minecraft:giant_tree_taiga_hills",
"minecraft:wooded_mountains",
"minecraft:savanna",
"minecraft:savanna_plateau",
"minecraft:badlands",
"minecraft:wooded_badlands_plateau",
"minecraft:badlands_plateau",
"minecraft:small_end_islands",
"minecraft:end_midlands",
"minecraft:end_highlands",
"minecraft:end_barrens",
"minecraft:warm_ocean",
"minecraft:lukewarm_ocean",
"minecraft:cold_ocean",
"minecraft:deep_warm_ocean",
"minecraft:deep_lukewarm_ocean",
"minecraft:deep_cold_ocean",
"minecraft:deep_frozen_ocean",
"minecraft:the_void",
"minecraft:sunflower_plains",
"minecraft:desert_lakes",
"minecraft:gravelly_mountains",
"minecraft:flower_forest",
"minecraft:taiga_mountains",
"minecraft:swamp_hills",
"minecraft:ice_spikes",
"minecraft:modified_jungle",
"minecraft:modified_jungle_edge",
"minecraft:tall_birch_forest",
"minecraft:tall_birch_hills",
"minecraft:dark_forest_hills",
"minecraft:snowy_taiga_mountains",
"minecraft:giant_spruce_taiga",
"minecraft:giant_spruce_taiga_hills",
"minecraft:modified_gravelly_mountains",
"minecraft:shattered_savanna",
"minecraft:shattered_savanna_plateau",
"minecraft:eroded_badlands",
"minecraft:modified_wooded_badlands_plateau",
"minecraft:modified_badlands_plateau",
"minecraft:bamboo_jungle",
"minecraft:bamboo_jungle_hills"
]

View File

@ -0,0 +1,81 @@
[
"minecraft:ocean",
"minecraft:plains",
"minecraft:desert",
"minecraft:mountains",
"minecraft:forest",
"minecraft:taiga",
"minecraft:swamp",
"minecraft:river",
"minecraft:nether_wastes",
"minecraft:the_end",
"minecraft:frozen_ocean",
"minecraft:frozen_river",
"minecraft:snowy_tundra",
"minecraft:snowy_mountains",
"minecraft:mushroom_fields",
"minecraft:mushroom_field_shore",
"minecraft:beach",
"minecraft:desert_hills",
"minecraft:wooded_hills",
"minecraft:taiga_hills",
"minecraft:mountain_edge",
"minecraft:jungle",
"minecraft:jungle_hills",
"minecraft:jungle_edge",
"minecraft:deep_ocean",
"minecraft:stone_shore",
"minecraft:snowy_beach",
"minecraft:birch_forest",
"minecraft:birch_forest_hills",
"minecraft:dark_forest",
"minecraft:snowy_taiga",
"minecraft:snowy_taiga_hills",
"minecraft:giant_tree_taiga",
"minecraft:giant_tree_taiga_hills",
"minecraft:wooded_mountains",
"minecraft:savanna",
"minecraft:savanna_plateau",
"minecraft:badlands",
"minecraft:wooded_badlands_plateau",
"minecraft:badlands_plateau",
"minecraft:small_end_islands",
"minecraft:end_midlands",
"minecraft:end_highlands",
"minecraft:end_barrens",
"minecraft:warm_ocean",
"minecraft:lukewarm_ocean",
"minecraft:cold_ocean",
"minecraft:deep_warm_ocean",
"minecraft:deep_lukewarm_ocean",
"minecraft:deep_cold_ocean",
"minecraft:deep_frozen_ocean",
"minecraft:the_void",
"minecraft:sunflower_plains",
"minecraft:desert_lakes",
"minecraft:gravelly_mountains",
"minecraft:flower_forest",
"minecraft:taiga_mountains",
"minecraft:swamp_hills",
"minecraft:ice_spikes",
"minecraft:modified_jungle",
"minecraft:modified_jungle_edge",
"minecraft:tall_birch_forest",
"minecraft:tall_birch_hills",
"minecraft:dark_forest_hills",
"minecraft:snowy_taiga_mountains",
"minecraft:giant_spruce_taiga",
"minecraft:giant_spruce_taiga_hills",
"minecraft:modified_gravelly_mountains",
"minecraft:shattered_savanna",
"minecraft:shattered_savanna_plateau",
"minecraft:eroded_badlands",
"minecraft:modified_wooded_badlands_plateau",
"minecraft:modified_badlands_plateau",
"minecraft:bamboo_jungle",
"minecraft:bamboo_jungle_hills",
"minecraft:soul_sand_valley",
"minecraft:crimson_forest",
"minecraft:warped_forest",
"minecraft:basalt_deltas"
]

View File

@ -0,0 +1,83 @@
[
"minecraft:ocean",
"minecraft:plains",
"minecraft:desert",
"minecraft:mountains",
"minecraft:forest",
"minecraft:taiga",
"minecraft:swamp",
"minecraft:river",
"minecraft:nether_wastes",
"minecraft:the_end",
"minecraft:frozen_ocean",
"minecraft:frozen_river",
"minecraft:snowy_tundra",
"minecraft:snowy_mountains",
"minecraft:mushroom_fields",
"minecraft:mushroom_field_shore",
"minecraft:beach",
"minecraft:desert_hills",
"minecraft:wooded_hills",
"minecraft:taiga_hills",
"minecraft:mountain_edge",
"minecraft:jungle",
"minecraft:jungle_hills",
"minecraft:jungle_edge",
"minecraft:deep_ocean",
"minecraft:stone_shore",
"minecraft:snowy_beach",
"minecraft:birch_forest",
"minecraft:birch_forest_hills",
"minecraft:dark_forest",
"minecraft:snowy_taiga",
"minecraft:snowy_taiga_hills",
"minecraft:giant_tree_taiga",
"minecraft:giant_tree_taiga_hills",
"minecraft:wooded_mountains",
"minecraft:savanna",
"minecraft:savanna_plateau",
"minecraft:badlands",
"minecraft:wooded_badlands_plateau",
"minecraft:badlands_plateau",
"minecraft:small_end_islands",
"minecraft:end_midlands",
"minecraft:end_highlands",
"minecraft:end_barrens",
"minecraft:warm_ocean",
"minecraft:lukewarm_ocean",
"minecraft:cold_ocean",
"minecraft:deep_warm_ocean",
"minecraft:deep_lukewarm_ocean",
"minecraft:deep_cold_ocean",
"minecraft:deep_frozen_ocean",
"minecraft:the_void",
"minecraft:sunflower_plains",
"minecraft:desert_lakes",
"minecraft:gravelly_mountains",
"minecraft:flower_forest",
"minecraft:taiga_mountains",
"minecraft:swamp_hills",
"minecraft:ice_spikes",
"minecraft:modified_jungle",
"minecraft:modified_jungle_edge",
"minecraft:tall_birch_forest",
"minecraft:tall_birch_hills",
"minecraft:dark_forest_hills",
"minecraft:snowy_taiga_mountains",
"minecraft:giant_spruce_taiga",
"minecraft:giant_spruce_taiga_hills",
"minecraft:modified_gravelly_mountains",
"minecraft:shattered_savanna",
"minecraft:shattered_savanna_plateau",
"minecraft:eroded_badlands",
"minecraft:modified_wooded_badlands_plateau",
"minecraft:modified_badlands_plateau",
"minecraft:bamboo_jungle",
"minecraft:bamboo_jungle_hills",
"minecraft:soul_sand_valley",
"minecraft:crimson_forest",
"minecraft:warped_forest",
"minecraft:basalt_deltas",
"minecraft:dripstone_caves",
"minecraft:lush_caves"
]

View File

@ -0,0 +1,63 @@
[
"minecraft:ocean",
"minecraft:plains",
"minecraft:desert",
"minecraft:windswept_hills",
"minecraft:forest",
"minecraft:taiga",
"minecraft:swamp",
"minecraft:river",
"minecraft:nether_wastes",
"minecraft:the_end",
"minecraft:frozen_ocean",
"minecraft:frozen_river",
"minecraft:snowy_plains",
"minecraft:mushroom_fields",
"minecraft:beach",
"minecraft:jungle",
"minecraft:sparse_jungle",
"minecraft:deep_ocean",
"minecraft:stony_shore",
"minecraft:snowy_beach",
"minecraft:birch_forest",
"minecraft:dark_forest",
"minecraft:snowy_taiga",
"minecraft:old_growth_pine_taiga",
"minecraft:windswept_forest",
"minecraft:savanna",
"minecraft:savanna_plateau",
"minecraft:badlands",
"minecraft:wooded_badlands",
"minecraft:small_end_islands",
"minecraft:end_midlands",
"minecraft:end_highlands",
"minecraft:end_barrens",
"minecraft:warm_ocean",
"minecraft:lukewarm_ocean",
"minecraft:cold_ocean",
"minecraft:deep_lukewarm_ocean",
"minecraft:deep_cold_ocean",
"minecraft:deep_frozen_ocean",
"minecraft:the_void",
"minecraft:sunflower_plains",
"minecraft:windswept_gravelly_hills",
"minecraft:flower_forest",
"minecraft:ice_spikes",
"minecraft:old_growth_birch_forest",
"minecraft:old_growth_spruce_taiga",
"minecraft:windswept_savanna",
"minecraft:eroded_badlands",
"minecraft:bamboo_jungle",
"minecraft:soul_sand_valley",
"minecraft:crimson_forest",
"minecraft:warped_forest",
"minecraft:basalt_deltas",
"minecraft:dripstone_caves",
"minecraft:lush_caves",
"minecraft:meadow",
"minecraft:grove",
"minecraft:snowy_slopes",
"minecraft:frozen_peaks",
"minecraft:jagged_peaks",
"minecraft:stony_peaks"
]