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

Merge branch 'master' into performance/cobblestone

This commit is contained in:
TheBusyBiscuit 2020-10-10 13:49:10 +02:00 committed by GitHub
commit d63d6189a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
100 changed files with 2276 additions and 644 deletions

View File

@ -4,9 +4,6 @@ on:
push: push:
branches: branches:
- master - master
pull_request:
branches:
- master
jobs: jobs:
build: build:

View File

@ -37,6 +37,8 @@
* Added Elytra Cap * Added Elytra Cap
* Added Planks to Sticks recipe to the Table Saw * Added Planks to Sticks recipe to the Table Saw
* Added "slimefun.gps.bypass" permission to open GPS devices anywhere * Added "slimefun.gps.bypass" permission to open GPS devices anywhere
* (API) Added custom tags for developers
* The range of the Seeker Pickaxe is now configurable
#### Changes #### Changes
* Improved Auto-Updater (Multi-Threading and more) * Improved Auto-Updater (Multi-Threading and more)
@ -70,6 +72,8 @@
* Fixed #2391 * Fixed #2391
* Fixed #2403 * Fixed #2403
* Fixed #2405 * Fixed #2405
* Fixed #2412
* Fixed #2238
## Release Candidate 16 (07 Sep 2020) ## Release Candidate 16 (07 Sep 2020)
https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#16 https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#16

View File

@ -262,6 +262,7 @@
<includes> <includes>
<include>*</include> <include>*</include>
<include>tags/*</include>
<include>languages/*</include> <include>languages/*</include>
</includes> </includes>
</resource> </resource>
@ -344,7 +345,7 @@
<dependency> <dependency>
<groupId>com.konghq</groupId> <groupId>com.konghq</groupId>
<artifactId>unirest-java</artifactId> <artifactId>unirest-java</artifactId>
<version>3.11.00</version> <version>3.11.01</version>
<scope>compile</scope> <scope>compile</scope>
<exclusions> <exclusions>
<exclusion> <exclusion>

View File

@ -50,7 +50,7 @@ public enum MinecraftVersion {
*/ */
UNIT_TEST("Unit Test Environment"); UNIT_TEST("Unit Test Environment");
public static final MinecraftVersion[] values = values(); public static final MinecraftVersion[] valuesCache = values();
private final String name; private final String name;
private final String prefix; private final String prefix;

View File

@ -0,0 +1,34 @@
package io.github.thebusybiscuit.slimefun4.api.exceptions;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.NamespacedKey;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
/**
* An {@link TagMisconfigurationException} is thrown whenever a {@link SlimefunTag}
* contains illegal, invalid or unknown values.
*
* @author TheBusyBiscuit
*
*/
public class TagMisconfigurationException extends Exception {
private static final long serialVersionUID = 5412127960821774280L;
/**
* This constructs a new {@link TagMisconfigurationException} for the given
* {@link SlimefunTag}'s {@link NamespacedKey} with the provided context.
*
* @param key
* The {@link NamespacedKey} of our {@link SlimefunTag}
* @param message
* The message to display
*/
@ParametersAreNonnullByDefault
public TagMisconfigurationException(NamespacedKey key, String message) {
super("Tag '" + key + "' has been misconfigured: " + message);
}
}

View File

@ -132,7 +132,13 @@ public class ItemSetting<T> {
Object configuredValue = SlimefunPlugin.getItemCfg().getValue(item.getID() + '.' + getKey()); Object configuredValue = SlimefunPlugin.getItemCfg().getValue(item.getID() + '.' + getKey());
if (defaultValue.getClass().isInstance(configuredValue)) { if (defaultValue.getClass().isInstance(configuredValue)) {
this.value = (T) configuredValue; if (validateInput((T) configuredValue)) {
this.value = (T) configuredValue;
} else {
Slimefun.getLogger().log(Level.WARNING, "Slimefun has found an invalid config setting in your Items.yml!");
Slimefun.getLogger().log(Level.WARNING, " at \"{0}.{1}\"", new Object[] { item.getID(), getKey() });
Slimefun.getLogger().log(Level.WARNING, "{0} is not a valid input!", configuredValue);
}
} else { } else {
this.value = defaultValue; this.value = defaultValue;
String found = configuredValue == null ? "null" : configuredValue.getClass().getSimpleName(); String found = configuredValue == null ? "null" : configuredValue.getClass().getSimpleName();
@ -144,4 +150,10 @@ public class ItemSetting<T> {
} }
} }
@Override
public String toString() {
T currentValue = this.value != null ? this.value : defaultValue;
return getClass().getSimpleName() + " {" + getKey() + " = " + currentValue + " (default: " + getDefaultValue() + ")";
}
} }

View File

@ -0,0 +1,52 @@
package io.github.thebusybiscuit.slimefun4.api.items.settings;
import javax.annotation.ParametersAreNonnullByDefault;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
/**
* This variation of {@link ItemSetting} allows you to define an {@link Integer} range
* and enforces this range using the {@link #validateInput(Integer)} method.
*
* @author TheBusyBiscuit
*
* @see ItemSetting
*
*/
public class IntRangeSetting extends ItemSetting<Integer> {
private final int min;
private final int max;
@ParametersAreNonnullByDefault
public IntRangeSetting(String key, int min, int defaultValue, int max) {
super(key, defaultValue);
this.min = min;
this.max = max;
}
@Override
public boolean validateInput(Integer input) {
return super.validateInput(input) && input >= min && input <= max;
}
/**
* This returns the minimum value of this {@link IntRangeSetting}.
*
* @return The minimum value
*/
public int getMinimum() {
return min;
}
/**
* This returns the maximum value of this {@link IntRangeSetting}.
*
* @return The maximum value
*/
public int getMaximum() {
return max;
}
}

View File

@ -0,0 +1,77 @@
package io.github.thebusybiscuit.slimefun4.api.items.settings;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Material;
import org.bukkit.Tag;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
/**
* This variation of {@link ItemSetting} allows you to define a default {@link Tag}.
* The {@link Tag} will be translated into a {@link String} {@link List} which the user
* can then configure as they wish.
*
* It also validates all inputs to be a valid {@link Material}.
*
* @author TheBusyBiscuit
*
* @see ItemSetting
*
*/
public class MaterialTagSetting extends ItemSetting<List<String>> {
private final Tag<Material> defaultTag;
@ParametersAreNonnullByDefault
public MaterialTagSetting(String key, Tag<Material> defaultTag) {
super(key, getAsStringList(defaultTag));
this.defaultTag = defaultTag;
}
/**
* This {@link Tag} holds the default values for this {@link MaterialTagSetting}.
*
* @return The default {@link Tag}
*/
@Nonnull
public Tag<Material> getDefaultTag() {
return defaultTag;
}
@Override
public boolean validateInput(List<String> input) {
if (input != null) {
for (String value : input) {
Material material = Material.matchMaterial(value);
// This value is not a valid material, the setting is not valid.
if (material == null) {
return false;
}
}
return true;
} else {
return false;
}
}
/**
* Internal method to turn a {@link Tag} into a {@link List} of {@link String Strings}.
*
* @param tag
* Our {@link Tag}
* @return The {@link String} {@link List}
*/
@Nonnull
private static List<String> getAsStringList(@Nonnull Tag<Material> tag) {
return tag.getValues().stream().map(Material::name).collect(Collectors.toList());
}
}

View File

@ -0,0 +1,4 @@
/**
* This package contains various sub classes of {@link io.github.thebusybiscuit.slimefun4.api.items.ItemSetting}.
*/
package io.github.thebusybiscuit.slimefun4.api.items.settings;

View File

@ -28,13 +28,14 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.BackpackListe
*/ */
public class PlayerBackpack { public class PlayerBackpack {
private static final String CONFIG_PREFIX = "backpacks.";
private final PlayerProfile profile; private final PlayerProfile profile;
private final int id; private final int id;
private final Config cfg; private final Config cfg;
private Inventory inventory; private Inventory inventory;
private int size; private int size;
private static final String CONFIG_PREFIX = "backpacks.";
/** /**
* This constructor loads an existing Backpack * This constructor loads an existing Backpack

View File

@ -31,6 +31,6 @@ public enum SlimefunGuideLayout {
*/ */
CHEAT_SHEET; CHEAT_SHEET;
public static final SlimefunGuideLayout[] values = values(); public static final SlimefunGuideLayout[] valuesCache = values();
} }

View File

@ -98,7 +98,7 @@ class GuideLayoutOption implements SlimefunGuideOption<SlimefunGuideLayout> {
@Override @Override
public Optional<SlimefunGuideLayout> getSelectedOption(Player p, ItemStack guide) { public Optional<SlimefunGuideLayout> getSelectedOption(Player p, ItemStack guide) {
for (SlimefunGuideLayout layout : SlimefunGuideLayout.values) { for (SlimefunGuideLayout layout : SlimefunGuideLayout.valuesCache) {
if (SlimefunUtils.isItemSimilar(guide, SlimefunGuide.getItem(layout), true, false)) { if (SlimefunUtils.isItemSimilar(guide, SlimefunGuide.getItem(layout), true, false)) {
return Optional.of(layout); return Optional.of(layout);
} }

View File

@ -85,7 +85,7 @@ public abstract class SlimefunLocalization extends Localization implements Keyed
protected abstract void addLanguage(@Nonnull String id, @Nonnull String texture); protected abstract void addLanguage(@Nonnull String id, @Nonnull String texture);
protected void loadEmbeddedLanguages() { protected void loadEmbeddedLanguages() {
for (SupportedLanguage lang : SupportedLanguage.values) { for (SupportedLanguage lang : SupportedLanguage.valuesCache) {
if (lang.isReadyForRelease() || SlimefunPlugin.getUpdater().getBranch() != SlimefunBranch.STABLE) { if (lang.isReadyForRelease() || SlimefunPlugin.getUpdater().getBranch() != SlimefunBranch.STABLE) {
addLanguage(lang.getLanguageId(), lang.getTexture()); addLanguage(lang.getLanguageId(), lang.getTexture());
} }

View File

@ -58,7 +58,7 @@ enum SupportedLanguage {
MACEDONIAN("mk", false, "a0e0b0b5d87a855466980a101a757bcdb5f77d9f7287889f3efa998ee0472fc0"), MACEDONIAN("mk", false, "a0e0b0b5d87a855466980a101a757bcdb5f77d9f7287889f3efa998ee0472fc0"),
TAGALOG("tl", true, "9306c0c1ce6a9c61bb42a572c49e6d0ed20e0e6b3d122cc64c339cbf78e9e937"); TAGALOG("tl", true, "9306c0c1ce6a9c61bb42a572c49e6d0ed20e0e6b3d122cc64c339cbf78e9e937");
public static final SupportedLanguage[] values = values(); public static final SupportedLanguage[] valuesCache = values();
private final String id; private final String id;
private final boolean releaseReady; private final boolean releaseReady;

View File

@ -31,7 +31,7 @@ public enum PerformanceRating implements Predicate<Float> {
HURTFUL(ChatColor.DARK_RED, 500), HURTFUL(ChatColor.DARK_RED, 500),
BAD(ChatColor.DARK_RED, Float.MAX_VALUE); BAD(ChatColor.DARK_RED, Float.MAX_VALUE);
public static final PerformanceRating[] values = values(); public static final PerformanceRating[] valuesCache = values();
private final ChatColor color; private final ChatColor color;
private final float threshold; private final float threshold;

View File

@ -296,7 +296,7 @@ public class SlimefunProfiler {
public PerformanceRating getPerformance() { public PerformanceRating getPerformance() {
float percentage = getPercentageOfTick(); float percentage = getPercentageOfTick();
for (PerformanceRating rating : PerformanceRating.values) { for (PerformanceRating rating : PerformanceRating.valuesCache) {
if (rating.test(percentage)) { if (rating.test(percentage)) {
return rating; return rating;
} }

View File

@ -30,6 +30,7 @@ import io.github.thebusybiscuit.cscorelib2.protection.ProtectionManager;
import io.github.thebusybiscuit.cscorelib2.reflection.ReflectionUtils; import io.github.thebusybiscuit.cscorelib2.reflection.ReflectionUtils;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon; import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
import io.github.thebusybiscuit.slimefun4.api.exceptions.TagMisconfigurationException;
import io.github.thebusybiscuit.slimefun4.api.gps.GPSNetwork; import io.github.thebusybiscuit.slimefun4.api.gps.GPSNetwork;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.SlimefunRegistry; import io.github.thebusybiscuit.slimefun4.core.SlimefunRegistry;
@ -99,6 +100,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.setup.SlimefunItemSetup
import io.github.thebusybiscuit.slimefun4.implementation.tasks.ArmorTask; import io.github.thebusybiscuit.slimefun4.implementation.tasks.ArmorTask;
import io.github.thebusybiscuit.slimefun4.implementation.tasks.SlimefunStartupTask; import io.github.thebusybiscuit.slimefun4.implementation.tasks.SlimefunStartupTask;
import io.github.thebusybiscuit.slimefun4.implementation.tasks.TickerTask; import io.github.thebusybiscuit.slimefun4.implementation.tasks.TickerTask;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import me.mrCookieSlime.CSCoreLibPlugin.CSCoreLib; import me.mrCookieSlime.CSCoreLibPlugin.CSCoreLib;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
@ -175,7 +177,6 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
registry.load(config); registry.load(config);
} else if (getServer().getPluginManager().isPluginEnabled("CS-CoreLib")) { } else if (getServer().getPluginManager().isPluginEnabled("CS-CoreLib")) {
long timestamp = System.nanoTime(); long timestamp = System.nanoTime();
PaperLib.suggestPaper(this); PaperLib.suggestPaper(this);
// We wanna ensure that the Server uses a compatible version of Minecraft // We wanna ensure that the Server uses a compatible version of Minecraft
@ -228,6 +229,9 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
getLogger().log(Level.INFO, "Loading GEO-Resources..."); getLogger().log(Level.INFO, "Loading GEO-Resources...");
GEOResourcesSetup.setup(); GEOResourcesSetup.setup();
getLogger().log(Level.INFO, "Loading Tags...");
loadTags();
getLogger().log(Level.INFO, "Loading items..."); getLogger().log(Level.INFO, "Loading items...");
loadItems(); loadItems();
@ -310,7 +314,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
String currentVersion = ReflectionUtils.getVersion(); String currentVersion = ReflectionUtils.getVersion();
if (currentVersion.startsWith("v")) { if (currentVersion.startsWith("v")) {
for (MinecraftVersion version : MinecraftVersion.values) { for (MinecraftVersion version : MinecraftVersion.valuesCache) {
if (version.matches(currentVersion)) { if (version.matches(currentVersion)) {
minecraftVersion = version; minecraftVersion = version;
return false; return false;
@ -337,7 +341,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
private Collection<String> getSupportedVersions() { private Collection<String> getSupportedVersions() {
List<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();
for (MinecraftVersion version : MinecraftVersion.values) { for (MinecraftVersion version : MinecraftVersion.valuesCache) {
if (version != MinecraftVersion.UNKNOWN) { if (version != MinecraftVersion.UNKNOWN) {
list.add(version.getName()); list.add(version.getName());
} }
@ -489,6 +493,16 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
new PlayerProfileListener(this); new PlayerProfileListener(this);
} }
private void loadTags() {
for (SlimefunTag tag : SlimefunTag.valuesCache) {
try {
tag.reload();
} catch (TagMisconfigurationException e) {
getLogger().log(Level.SEVERE, e, () -> "Failed to load Tag: " + tag.name());
}
}
}
private void loadItems() { private void loadItems() {
try { try {
SlimefunItemSetup.setup(this); SlimefunItemSetup.setup(this);

View File

@ -4,12 +4,12 @@ import java.util.concurrent.ThreadLocalRandom;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.Tag;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.collections.RandomizedSet; import io.github.thebusybiscuit.cscorelib2.collections.RandomizedSet;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
@ -25,7 +25,7 @@ public class FisherAndroid extends ProgrammableAndroid {
super(category, tier, item, recipeType, recipe); super(category, tier, item, recipeType, recipe);
// Fish // Fish
for (Material fish : MaterialCollections.getAllFishItems()) { for (Material fish : Tag.ITEMS_FISHES.getValues()) {
fishingLoot.add(new ItemStack(fish), 25); fishingLoot.add(new ItemStack(fish), 25);
} }

View File

@ -146,18 +146,18 @@ enum Instruction {
}); });
private static final Map<String, Instruction> nameLookup = new HashMap<>(); private static final Map<String, Instruction> nameLookup = new HashMap<>();
public static final Instruction[] values = values(); public static final Instruction[] valuesCache = values();
static {
for (Instruction instruction : valuesCache) {
nameLookup.put(instruction.name(), instruction);
}
}
private final ItemStack item; private final ItemStack item;
private final AndroidType type; private final AndroidType type;
private final AndroidAction method; private final AndroidAction method;
static {
for (Instruction instruction : values) {
nameLookup.put(instruction.name(), instruction);
}
}
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
Instruction(AndroidType type, HeadTexture head, @Nullable AndroidAction method) { Instruction(AndroidType type, HeadTexture head, @Nullable AndroidAction method) {
this.type = type; this.type = type;
@ -198,7 +198,7 @@ enum Instruction {
* @return The {@link Instruction} or null if it does not exist. * @return The {@link Instruction} or null if it does not exist.
*/ */
@Nullable @Nullable
public static Instruction getFromCache(@Nonnull String value) { public static Instruction getInstruction(@Nonnull String value) {
Validate.notNull(value, "An Instruction cannot be null!"); Validate.notNull(value, "An Instruction cannot be null!");
return nameLookup.get(value); return nameLookup.get(value);
} }

View File

@ -15,12 +15,12 @@ import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.api.events.AndroidMineEvent; import io.github.thebusybiscuit.slimefun4.api.events.AndroidMineEvent;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.InfiniteBlockGenerator; import io.github.thebusybiscuit.slimefun4.utils.InfiniteBlockGenerator;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.BlockStorage;
@ -48,7 +48,7 @@ public class MinerAndroid extends ProgrammableAndroid {
protected void dig(Block b, BlockMenu menu, Block block) { protected void dig(Block b, BlockMenu menu, Block block) {
Collection<ItemStack> drops = block.getDrops(effectivePickaxe); Collection<ItemStack> drops = block.getDrops(effectivePickaxe);
if (!MaterialCollections.getAllUnbreakableBlocks().contains(block.getType()) && !drops.isEmpty()) { if (!SlimefunTag.UNBREAKABLE_MATERIALS.isTagged(block.getType()) && !drops.isEmpty()) {
OfflinePlayer owner = Bukkit.getOfflinePlayer(UUID.fromString(BlockStorage.getLocationInfo(b.getLocation(), "owner"))); OfflinePlayer owner = Bukkit.getOfflinePlayer(UUID.fromString(BlockStorage.getLocationInfo(b.getLocation(), "owner")));
if (SlimefunPlugin.getProtectionManager().hasPermission(owner, block.getLocation(), ProtectableAction.BREAK_BLOCK)) { if (SlimefunPlugin.getProtectionManager().hasPermission(owner, block.getLocation(), ProtectableAction.BREAK_BLOCK)) {
@ -72,7 +72,7 @@ public class MinerAndroid extends ProgrammableAndroid {
protected void moveAndDig(Block b, BlockMenu menu, BlockFace face, Block block) { protected void moveAndDig(Block b, BlockMenu menu, BlockFace face, Block block) {
Collection<ItemStack> drops = block.getDrops(effectivePickaxe); Collection<ItemStack> drops = block.getDrops(effectivePickaxe);
if (!MaterialCollections.getAllUnbreakableBlocks().contains(block.getType()) && !drops.isEmpty()) { if (!SlimefunTag.UNBREAKABLE_MATERIALS.isTagged(block.getType()) && !drops.isEmpty()) {
OfflinePlayer owner = Bukkit.getOfflinePlayer(UUID.fromString(BlockStorage.getLocationInfo(b.getLocation(), "owner"))); OfflinePlayer owner = Bukkit.getOfflinePlayer(UUID.fromString(BlockStorage.getLocationInfo(b.getLocation(), "owner")));
if (SlimefunPlugin.getProtectionManager().hasPermission(owner, block.getLocation(), ProtectableAction.BREAK_BLOCK)) { if (SlimefunPlugin.getProtectionManager().hasPermission(owner, block.getLocation(), ProtectableAction.BREAK_BLOCK)) {

View File

@ -257,7 +257,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
return false; return false;
}); });
} else { } else {
Instruction instruction = Instruction.getFromCache(script[i]); Instruction instruction = Instruction.getInstruction(script[i]);
if (instruction == null) { if (instruction == null) {
SlimefunPlugin.instance().getLogger().log(Level.WARNING, "Failed to parse Android instruction: {0}, maybe your server is out of date?", script[i]); SlimefunPlugin.instance().getLogger().log(Level.WARNING, "Failed to parse Android instruction: {0}, maybe your server is out of date?", script[i]);
@ -493,7 +493,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
protected List<Instruction> getValidScriptInstructions() { protected List<Instruction> getValidScriptInstructions() {
List<Instruction> list = new ArrayList<>(); List<Instruction> list = new ArrayList<>();
for (Instruction part : Instruction.values) { for (Instruction part : Instruction.valuesCache) {
if (part == Instruction.START || part == Instruction.REPEAT) { if (part == Instruction.START || part == Instruction.REPEAT) {
continue; continue;
} }
@ -646,7 +646,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
} }
BlockStorage.addBlockInfo(b, "fuel", String.valueOf(fuel - 1)); BlockStorage.addBlockInfo(b, "fuel", String.valueOf(fuel - 1));
Instruction instruction = Instruction.getFromCache(script[index]); Instruction instruction = Instruction.getInstruction(script[index]);
if (instruction == null) { if (instruction == null) {
SlimefunPlugin.instance().getLogger().log(Level.WARNING, "Failed to parse Android instruction: {0}, maybe your server is out of date?", script[index]); SlimefunPlugin.instance().getLogger().log(Level.WARNING, "Failed to parse Android instruction: {0}, maybe your server is out of date?", script[index]);

View File

@ -1,6 +1,9 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.backpacks; package io.github.thebusybiscuit.slimefun4.implementation.items.backpacks;
import org.bukkit.Material; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -9,6 +12,7 @@ import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.BackpackListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.BackpackListener;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
@ -28,6 +32,7 @@ public class SlimefunBackpack extends SimpleSlimefunItem<ItemUseHandler> {
private final int size; private final int size;
@ParametersAreNonnullByDefault
public SlimefunBackpack(int size, Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public SlimefunBackpack(int size, Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);
@ -55,9 +60,9 @@ public class SlimefunBackpack extends SimpleSlimefunItem<ItemUseHandler> {
* *
* @return Whether the given {@link ItemStack} is allowed to be put into this {@link SlimefunBackpack} * @return Whether the given {@link ItemStack} is allowed to be put into this {@link SlimefunBackpack}
*/ */
public boolean isItemAllowed(ItemStack item, SlimefunItem itemAsSlimefunItem) { public boolean isItemAllowed(@Nonnull ItemStack item, @Nullable SlimefunItem itemAsSlimefunItem) {
// Shulker Boxes are not allowed! // Shulker Boxes are not allowed!
if (item.getType() == Material.SHULKER_BOX || item.getType().toString().endsWith("_SHULKER_BOX")) { if (SlimefunTag.SHULKER_BOXES.isTagged(item.getType())) {
return false; return false;
} }

View File

@ -2,7 +2,6 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.blocks;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Effect; import org.bukkit.Effect;
@ -18,14 +17,15 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.api.events.BlockPlacerPlaceEvent; import io.github.thebusybiscuit.slimefun4.api.events.BlockPlacerPlaceEvent;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.api.items.settings.MaterialTagSetting;
import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable; import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockDispenseHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockDispenseHandler;
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import io.papermc.lib.features.blockstatesnapshot.BlockStateSnapshotResult; import io.papermc.lib.features.blockstatesnapshot.BlockStateSnapshotResult;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
@ -47,7 +47,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
*/ */
public class BlockPlacer extends SlimefunItem { public class BlockPlacer extends SlimefunItem {
private final ItemSetting<List<String>> blacklist = new ItemSetting<>("unplaceable-blocks", MaterialCollections.getAllUnbreakableBlocks().stream().map(Material::name).collect(Collectors.toList())); private final ItemSetting<List<String>> blacklist = new MaterialTagSetting("unplaceable-blocks", SlimefunTag.UNBREAKABLE_MATERIALS);
public BlockPlacer(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public BlockPlacer(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);
@ -72,10 +72,13 @@ public class BlockPlacer extends SlimefunItem {
private BlockDispenseHandler onBlockDispense() { private BlockDispenseHandler onBlockDispense() {
return (e, dispenser, facedBlock, machine) -> { return (e, dispenser, facedBlock, machine) -> {
if (!hasPermission(dispenser, facedBlock)) { if (!hasPermission(dispenser, facedBlock)) {
e.setCancelled(true);
return; return;
} }
if (isShulkerBox(e.getItem().getType())) { Material material = e.getItem().getType();
if (SlimefunTag.SHULKER_BOXES.isTagged(material)) {
// Since vanilla Dispensers can already place Shulker boxes, we // Since vanilla Dispensers can already place Shulker boxes, we
// simply fallback to the vanilla behaviour. // simply fallback to the vanilla behaviour.
return; return;
@ -83,7 +86,14 @@ public class BlockPlacer extends SlimefunItem {
e.setCancelled(true); e.setCancelled(true);
if (facedBlock.isEmpty() && e.getItem().getType().isBlock() && !isBlacklisted(e.getItem().getType())) { if (!material.isBlock() || SlimefunTag.BLOCK_PLACER_IGNORED_MATERIALS.isTagged(material)) {
// Some materials cannot be reliably placed, like beds, it would look
// kinda wonky, so we just ignore these altogether.
// The event has already been cancelled too, so they won't drop.
return;
}
if (facedBlock.isEmpty() && !isBlacklisted(material)) {
SlimefunItem item = SlimefunItem.getByItem(e.getItem()); SlimefunItem item = SlimefunItem.getByItem(e.getItem());
if (item != null) { if (item != null) {
@ -123,10 +133,6 @@ public class BlockPlacer extends SlimefunItem {
return SlimefunPlugin.getProtectionManager().hasPermission(player, target, ProtectableAction.PLACE_BLOCK); return SlimefunPlugin.getProtectionManager().hasPermission(player, target, ProtectableAction.PLACE_BLOCK);
} }
private boolean isShulkerBox(Material type) {
return type == Material.SHULKER_BOX || type.name().endsWith("_SHULKER_BOX");
}
private boolean isBlacklisted(Material type) { private boolean isBlacklisted(Material type) {
for (String blockType : blacklist.getValue()) { for (String blockType : blacklist.getValue()) {
if (type.toString().equals(blockType)) { if (type.toString().equals(blockType)) {

View File

@ -17,13 +17,13 @@ import org.bukkit.block.data.Waterlogged;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.BlockStorage;
@ -67,7 +67,7 @@ public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements Rec
items.add(new ItemStack(Material.WATER_BUCKET)); items.add(new ItemStack(Material.WATER_BUCKET));
} }
for (Material sapling : MaterialCollections.getAllTerracottaColors()) { for (Material sapling : SlimefunTag.TERRACOTTA.getValues()) {
items.add(new ItemStack(sapling, 12)); items.add(new ItemStack(sapling, 12));
items.add(new ItemStack(Material.LAVA_BUCKET)); items.add(new ItemStack(Material.LAVA_BUCKET));
} }

View File

@ -1,19 +1,14 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines; package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines;
import java.util.EnumSet;
import java.util.Set;
import org.bukkit.Material;
import org.bukkit.Particle; import org.bukkit.Particle;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.data.Ageable; import org.bukkit.block.data.Ageable;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper; import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.BlockStorage;
@ -22,24 +17,11 @@ import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
public abstract class CropGrowthAccelerator extends AbstractGrowthAccelerator { public abstract class CropGrowthAccelerator extends AbstractGrowthAccelerator {
private final Set<Material> crops = EnumSet.noneOf(Material.class);
// We wanna strip the Slimefun Item id here // We wanna strip the Slimefun Item id here
private static final ItemStack organicFertilizer = new ItemStackWrapper(SlimefunItems.FERTILIZER); private static final ItemStack organicFertilizer = new ItemStackWrapper(SlimefunItems.FERTILIZER);
public CropGrowthAccelerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public CropGrowthAccelerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);
crops.add(Material.WHEAT);
crops.add(Material.POTATOES);
crops.add(Material.CARROTS);
crops.add(Material.NETHER_WART);
crops.add(Material.BEETROOTS);
crops.add(Material.COCOA);
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) {
crops.add(Material.SWEET_BERRY_BUSH);
}
} }
public abstract int getEnergyConsumption(); public abstract int getEnergyConsumption();
@ -62,7 +44,7 @@ public abstract class CropGrowthAccelerator extends AbstractGrowthAccelerator {
for (int z = -getRadius(); z <= getRadius(); z++) { for (int z = -getRadius(); z <= getRadius(); z++) {
Block block = b.getRelative(x, 0, z); Block block = b.getRelative(x, 0, z);
if (crops.contains(block.getType()) && grow(b, inv, block)) { if (SlimefunTag.CROP_GROWTH_ACCELERATOR_BLOCKS.isTagged(block.getType()) && grow(b, inv, block)) {
return; return;
} }
} }

View File

@ -4,7 +4,7 @@ import org.bukkit.Material;
import org.bukkit.Tag; import org.bukkit.Tag;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections; import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
@ -22,7 +22,7 @@ public abstract class ElectrifiedCrucible extends AContainer {
registerRecipe(8, new ItemStack[] { new ItemStack(Material.BUCKET), new ItemStack(Material.TERRACOTTA, 12) }, new ItemStack[] { new ItemStack(Material.LAVA_BUCKET) }); registerRecipe(8, new ItemStack[] { new ItemStack(Material.BUCKET), new ItemStack(Material.TERRACOTTA, 12) }, new ItemStack[] { new ItemStack(Material.LAVA_BUCKET) });
registerRecipe(10, new ItemStack[] { new ItemStack(Material.BUCKET), new ItemStack(Material.OBSIDIAN) }, new ItemStack[] { new ItemStack(Material.LAVA_BUCKET) }); registerRecipe(10, new ItemStack[] { new ItemStack(Material.BUCKET), new ItemStack(Material.OBSIDIAN) }, new ItemStack[] { new ItemStack(Material.LAVA_BUCKET) });
for (Material terracotta : MaterialCollections.getAllTerracottaColors().getAsArray()) { for (Material terracotta : SlimefunTag.TERRACOTTA.getValues()) {
registerRecipe(8, new ItemStack[] { new ItemStack(Material.BUCKET), new ItemStack(terracotta, 12) }, new ItemStack[] { new ItemStack(Material.LAVA_BUCKET) }); registerRecipe(8, new ItemStack[] { new ItemStack(Material.BUCKET), new ItemStack(terracotta, 12) }, new ItemStack[] { new ItemStack(Material.LAVA_BUCKET) });
} }

View File

@ -3,6 +3,7 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.food;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.api.items.settings.IntRangeSetting;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemConsumptionHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.ItemConsumptionHandler;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
@ -20,7 +21,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
*/ */
public class MeatJerky extends SimpleSlimefunItem<ItemConsumptionHandler> { public class MeatJerky extends SimpleSlimefunItem<ItemConsumptionHandler> {
private final ItemSetting<Integer> saturation = new ItemSetting<>("saturation-level", 6); private final ItemSetting<Integer> saturation = new IntRangeSetting("saturation-level", 0, 6, Integer.MAX_VALUE);
public MeatJerky(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public MeatJerky(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);

View File

@ -53,10 +53,10 @@ public class MagicalZombiePills extends SimpleSlimefunItem<EntityInteractHandler
Player p = e.getPlayer(); Player p = e.getPlayer();
if (entity instanceof ZombieVillager) { if (entity instanceof ZombieVillager) {
useItem(p); useItem(p, item);
healZombieVillager((ZombieVillager) entity, p); healZombieVillager((ZombieVillager) entity, p);
} else if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16) && entity instanceof PigZombie) { } else if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16) && entity instanceof PigZombie) {
useItem(p); useItem(p, item);
healZombifiedPiglin((PigZombie) entity); healZombifiedPiglin((PigZombie) entity);
} }
}; };
@ -71,7 +71,7 @@ public class MagicalZombiePills extends SimpleSlimefunItem<EntityInteractHandler
return PlayerRightClickEvent::cancel; return PlayerRightClickEvent::cancel;
} }
private void useItem(@Nonnull Player p) { private void useItem(@Nonnull Player p, @Nonnull ItemStack item) {
if (p.getGameMode() != GameMode.CREATIVE) { if (p.getGameMode() != GameMode.CREATIVE) {
ItemUtils.consumeItem(item, false); ItemUtils.consumeItem(item, false);
} }

View File

@ -7,6 +7,7 @@ import org.bukkit.entity.LivingEntity;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.api.items.settings.IntRangeSetting;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
@ -24,7 +25,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
*/ */
public class TelepositionScroll extends SimpleSlimefunItem<ItemUseHandler> { public class TelepositionScroll extends SimpleSlimefunItem<ItemUseHandler> {
private final ItemSetting<Integer> radius = new ItemSetting<>("radius", 10); private final ItemSetting<Integer> radius = new IntRangeSetting("radius", 1, 10, Integer.MAX_VALUE);
public TelepositionScroll(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public TelepositionScroll(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);

View File

@ -12,6 +12,7 @@ import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.implementation.settings.TalismanEnchantment;
import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;

View File

@ -4,6 +4,7 @@ import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent; import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.api.items.settings.IntRangeSetting;
import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable; import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
import io.github.thebusybiscuit.slimefun4.core.attributes.RandomMobDrop; import io.github.thebusybiscuit.slimefun4.core.attributes.RandomMobDrop;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
@ -15,7 +16,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class BasicCircuitBoard extends SimpleSlimefunItem<ItemUseHandler> implements NotPlaceable, RandomMobDrop { public class BasicCircuitBoard extends SimpleSlimefunItem<ItemUseHandler> implements NotPlaceable, RandomMobDrop {
private final ItemSetting<Boolean> dropSetting = new ItemSetting<>("drop-from-golems", true); private final ItemSetting<Boolean> dropSetting = new ItemSetting<>("drop-from-golems", true);
private final ItemSetting<Integer> chance = new ItemSetting<>("golem-drop-chance", 75); private final ItemSetting<Integer> chance = new IntRangeSetting("golem-drop-chance", 0, 75, 100);
public BasicCircuitBoard(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public BasicCircuitBoard(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);

View File

@ -4,6 +4,7 @@ import org.bukkit.entity.Piglin;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.api.items.settings.IntRangeSetting;
import io.github.thebusybiscuit.slimefun4.core.attributes.PiglinBarterDrop; import io.github.thebusybiscuit.slimefun4.core.attributes.PiglinBarterDrop;
import io.github.thebusybiscuit.slimefun4.implementation.items.magical.VillagerRune; import io.github.thebusybiscuit.slimefun4.implementation.items.magical.VillagerRune;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
@ -23,7 +24,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
*/ */
public class StrangeNetherGoo extends SlimefunItem implements PiglinBarterDrop { public class StrangeNetherGoo extends SlimefunItem implements PiglinBarterDrop {
private final ItemSetting<Integer> chance = new ItemSetting<>("barter-chance", 7); private final ItemSetting<Integer> chance = new IntRangeSetting("barter-chance", 0, 7, 100);
public StrangeNetherGoo(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public StrangeNetherGoo(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);

View File

@ -23,6 +23,7 @@ import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.api.items.settings.IntRangeSetting;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
@ -33,7 +34,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class Smeltery extends AbstractSmeltery { public class Smeltery extends AbstractSmeltery {
private final BlockFace[] faces = { BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST }; private final BlockFace[] faces = { BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST };
private final ItemSetting<Integer> fireBreakingChance = new ItemSetting<>("fire-breaking-chance", 34); private final ItemSetting<Integer> fireBreakingChance = new IntRangeSetting("fire-breaking-chance", 0, 34, 100);
public Smeltery(Category category, SlimefunItemStack item) { public Smeltery(Category category, SlimefunItemStack item) {
super(category, item, new ItemStack[] { null, new ItemStack(Material.NETHER_BRICK_FENCE), null, new ItemStack(Material.NETHER_BRICKS), new CustomItem(Material.DISPENSER, "Dispenser (Facing up)"), new ItemStack(Material.NETHER_BRICKS), null, new ItemStack(Material.FLINT_AND_STEEL), null }, BlockFace.DOWN); super(category, item, new ItemStack[] { null, new ItemStack(Material.NETHER_BRICK_FENCE), null, new ItemStack(Material.NETHER_BRICKS), new CustomItem(Material.DISPENSER, "Dispenser (Facing up)"), new ItemStack(Material.NETHER_BRICKS), null, new ItemStack(Material.FLINT_AND_STEEL), null }, BlockFace.DOWN);

View File

@ -7,7 +7,6 @@ import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@ -22,8 +21,10 @@ import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlockMachine; import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlockMachine;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
@ -209,14 +210,11 @@ public class IndustrialMiner extends MultiBlockMachine {
* @return Whether this {@link IndustrialMiner} is capable of mining this {@link Material} * @return Whether this {@link IndustrialMiner} is capable of mining this {@link Material}
*/ */
public boolean canMine(Material type) { public boolean canMine(Material type) {
if (type.name().endsWith("_ORE")) { if (SlimefunTag.INDUSTRIAL_MINER_ORES.isTagged(type)) {
return true; return true;
} else if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) { } else if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
if (type == Material.GILDED_BLACKSTONE) { return type == Material.ANCIENT_DEBRIS && canMineAncientDebris.getValue();
return true;
} else if (type == Material.ANCIENT_DEBRIS) {
return canMineAncientDebris.getValue();
}
} }
return false; return false;

View File

@ -1,6 +1,7 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.tools; package io.github.thebusybiscuit.slimefun4.implementation.items.tools;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -12,6 +13,7 @@ import java.util.concurrent.ThreadLocalRandom;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Effect; import org.bukkit.Effect;
import org.bukkit.GameMode; import org.bukkit.GameMode;
@ -24,8 +26,6 @@ import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import io.github.thebusybiscuit.cscorelib2.config.Config;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.events.ClimbingPickLaunchEvent; import io.github.thebusybiscuit.slimefun4.api.events.ClimbingPickLaunchEvent;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
@ -34,6 +34,8 @@ import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.implementation.settings.ClimbableSurface;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
@ -49,53 +51,110 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
*/ */
public class ClimbingPick extends SimpleSlimefunItem<ItemUseHandler> implements DamageableItem, RecipeDisplayItem { public class ClimbingPick extends SimpleSlimefunItem<ItemUseHandler> implements DamageableItem, RecipeDisplayItem {
private static final double BASE_POWER = 1; private static final double STRONG_SURFACE_DEFAULT = 1.0;
private static final double WEAK_SURFACE_DEFAULT = 0.6;
private static final double MAX_DISTANCE = 4.4; private static final double MAX_DISTANCE = 4.4;
private static final double EFFICIENCY_MODIFIER = 0.125;
private static final long COOLDOWN = 4;
private final ItemSetting<Boolean> dualWielding = new ItemSetting<>("dual-wielding", true); private final ItemSetting<Boolean> dualWielding = new ItemSetting<>("dual-wielding", true);
private final ItemSetting<Boolean> damageOnUse = new ItemSetting<>("damage-on-use", true); private final ItemSetting<Boolean> damageOnUse = new ItemSetting<>("damage-on-use", true);
private final Map<Material, Double> materialSpeeds; private final Map<Material, ClimbableSurface> surfaces = new EnumMap<>(Material.class);
private final Set<UUID> users = new HashSet<>(); private final Set<UUID> users = new HashSet<>();
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public ClimbingPick(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public ClimbingPick(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);
addItemSetting(dualWielding, damageOnUse); addItemSetting(dualWielding, damageOnUse);
addDefaultSurfaces();
}
String cfgKey = getID() + ".launch-amounts."; /**
Config itemCfg = SlimefunPlugin.getItemCfg(); * This method adds every surface that is climbable by default.
materialSpeeds = new EnumMap<>(Material.class); */
protected void addDefaultSurfaces() {
for (Material mat : MaterialCollections.getAllIceBlocks()) { // These are "strong" surfaces, they will give you the biggest boost
materialSpeeds.put(mat, itemCfg.getOrSetDefault(cfgKey + mat.name(), 1.0)); for (Material surface : SlimefunTag.CLIMBING_PICK_STRONG_SURFACES.getValues()) {
addSurface(surface, STRONG_SURFACE_DEFAULT);
} }
for (Material mat : MaterialCollections.getAllConcretePowderColors()) { // These are "weak" surfaces, you can still climb them but they don't have
materialSpeeds.put(mat, itemCfg.getOrSetDefault(cfgKey + mat.name(), 1.0)); // such a high boost as the "strong" surfaces
} for (Material surface : SlimefunTag.CLIMBING_PICK_WEAK_SURFACES.getValues()) {
addSurface(surface, WEAK_SURFACE_DEFAULT);
for (Material mat : MaterialCollections.getAllTerracottaColors()) {
materialSpeeds.put(mat, itemCfg.getOrSetDefault(cfgKey + mat.name(), 1.0));
}
materialSpeeds.put(Material.GRAVEL, itemCfg.getOrSetDefault(cfgKey + Material.GRAVEL.name(), 0.4));
materialSpeeds.put(Material.SAND, itemCfg.getOrSetDefault(cfgKey + Material.SAND.name(), 0.4));
materialSpeeds.put(Material.STONE, itemCfg.getOrSetDefault(cfgKey + Material.STONE.name(), 0.6));
materialSpeeds.put(Material.DIORITE, itemCfg.getOrSetDefault(cfgKey + Material.DIORITE.name(), 0.6));
materialSpeeds.put(Material.GRANITE, itemCfg.getOrSetDefault(cfgKey + Material.GRANITE.name(), 0.6));
materialSpeeds.put(Material.ANDESITE, itemCfg.getOrSetDefault(cfgKey + Material.ANDESITE.name(), 0.6));
materialSpeeds.put(Material.NETHERRACK, itemCfg.getOrSetDefault(cfgKey + Material.NETHERRACK.name(), 0.6));
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
materialSpeeds.put(Material.BLACKSTONE, itemCfg.getOrSetDefault(cfgKey + Material.BLACKSTONE.name(), 0.6));
materialSpeeds.put(Material.BASALT, itemCfg.getOrSetDefault(cfgKey + Material.BASALT.name(), 0.7));
} }
} }
protected void addSurface(@Nonnull Material type, double defaultValue) {
ClimbableSurface surface = new ClimbableSurface(type, defaultValue);
addItemSetting(surface);
surfaces.put(type, surface);
}
/**
* This returns whether the {@link ClimbingPick} needs to be held in both
* arms to work.
*
* @return Whether dual wielding is enabled
*/
public boolean isDualWieldingEnabled() { public boolean isDualWieldingEnabled() {
return dualWielding.getValue(); return dualWielding.getValue();
} }
/**
* This method returns a {@link Collection} of every {@link ClimbableSurface} the
* {@link ClimbingPick} can climb.
*
* @return A {@link Collection} of every {@link ClimbableSurface}
*/
@Nonnull
public Collection<ClimbableSurface> getClimbableSurfaces() {
return surfaces.values();
}
/**
* This returns the climbing speed for a given {@link Material}.
*
* @param type
* The {@link Material}
*
* @return The climbing speed for this {@link Material} or 0.
*/
public double getClimbingSpeed(@Nonnull Material type) {
Validate.notNull(type, "The surface cannot be null");
ClimbableSurface surface = surfaces.get(type);
if (surface != null) {
return surface.getValue();
} else {
return 0;
}
}
/**
* This returns the climbing speed for a given {@link Material} and the used {@link ItemStack}.
*
* @param item
* the {@link ClimbingPick}'s {@link ItemStack}
* @param type
* The {@link Material}
*
* @return The climbing speed or 0.
*/
public double getClimbingSpeed(@Nonnull ItemStack item, @Nonnull Material type) {
double speed = getClimbingSpeed(type);
if (speed > 0) {
int efficiencyLevel = item.getEnchantmentLevel(Enchantment.DIG_SPEED);
if (efficiencyLevel > 0) {
speed += efficiencyLevel * EFFICIENCY_MODIFIER;
}
}
return speed;
}
@Override @Override
public ItemUseHandler getItemHandler() { public ItemUseHandler getItemHandler() {
return e -> { return e -> {
@ -106,7 +165,7 @@ public class ClimbingPick extends SimpleSlimefunItem<ItemUseHandler> implements
Block block = e.getClickedBlock().get(); Block block = e.getClickedBlock().get();
Player p = e.getPlayer(); Player p = e.getPlayer();
// Check if the Player is standing close to the wall // Check if the Player is standing close enough to the wall
if (p.getLocation().distanceSquared(block.getLocation().add(0.5, 0.5, 0.5)) > MAX_DISTANCE) { if (p.getLocation().distanceSquared(block.getLocation().add(0.5, 0.5, 0.5)) > MAX_DISTANCE) {
return; return;
} }
@ -118,11 +177,9 @@ public class ClimbingPick extends SimpleSlimefunItem<ItemUseHandler> implements
} }
// Top and bottom faces won't be allowed // Top and bottom faces won't be allowed
if (e.getClickedFace() == BlockFace.DOWN || e.getClickedFace() == BlockFace.UP) { if (e.getClickedFace() != BlockFace.DOWN && e.getClickedFace() != BlockFace.UP) {
return; climb(p, e.getHand(), e.getItem(), block);
} }
climb(p, e.getHand(), e.getItem(), block);
}; };
} }
@ -138,19 +195,13 @@ public class ClimbingPick extends SimpleSlimefunItem<ItemUseHandler> implements
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
private void climb(Player p, EquipmentSlot hand, ItemStack item, Block block) { private void climb(Player p, EquipmentSlot hand, ItemStack item, Block block) {
double power = materialSpeeds.getOrDefault(block.getType(), 0.0); double power = getClimbingSpeed(item, block.getType());
if (power > 0.05) { if (power > 0.05) {
// Prevent players from spamming this // Prevent players from spamming this item by enforcing a cooldown
if (users.add(p.getUniqueId())) { if (users.add(p.getUniqueId())) {
int efficiencyLevel = item.getEnchantmentLevel(Enchantment.DIG_SPEED); SlimefunPlugin.runSync(() -> users.remove(p.getUniqueId()), COOLDOWN);
Vector velocity = new Vector(0, power, 0);
if (efficiencyLevel != 0) {
power += efficiencyLevel * 0.1;
}
SlimefunPlugin.runSync(() -> users.remove(p.getUniqueId()), 4L);
Vector velocity = new Vector(0, power * BASE_POWER, 0);
ClimbingPickLaunchEvent event = new ClimbingPickLaunchEvent(p, velocity, this, item, block); ClimbingPickLaunchEvent event = new ClimbingPickLaunchEvent(p, velocity, this, item, block);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
@ -215,7 +266,7 @@ public class ClimbingPick extends SimpleSlimefunItem<ItemUseHandler> implements
public List<ItemStack> getDisplayRecipes() { public List<ItemStack> getDisplayRecipes() {
List<ItemStack> display = new ArrayList<>(); List<ItemStack> display = new ArrayList<>();
for (Material mat : materialSpeeds.keySet()) { for (Material mat : surfaces.keySet()) {
display.add(new ItemStack(mat)); display.add(new ItemStack(mat));
} }

View File

@ -4,9 +4,9 @@ import org.bukkit.block.Block;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialTools;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
@ -29,7 +29,7 @@ public class ExplosiveShovel extends ExplosiveTool {
@Override @Override
protected boolean canBreak(Player p, Block b) { protected boolean canBreak(Player p, Block b) {
return MaterialTools.getBreakableByShovel().contains(b.getType()) && SlimefunPlugin.getProtectionManager().hasPermission(p, b.getLocation(), ProtectableAction.BREAK_BLOCK); return SlimefunTag.EXPLOSIVE_SHOVEL_BLOCKS.isTagged(b.getType()) && SlimefunPlugin.getProtectionManager().hasPermission(p, b.getLocation(), ProtectableAction.BREAK_BLOCK);
} }
} }

View File

@ -13,7 +13,6 @@ import org.bukkit.event.block.BlockExplodeEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.core.attributes.DamageableItem; import io.github.thebusybiscuit.slimefun4.core.attributes.DamageableItem;
@ -21,6 +20,7 @@ import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler; import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler;
@ -111,7 +111,7 @@ class ExplosiveTool extends SimpleSlimefunItem<ToolUseHandler> implements NotPla
protected boolean canBreak(Player p, Block b) { protected boolean canBreak(Player p, Block b) {
if (b.isEmpty() || b.isLiquid()) { if (b.isEmpty() || b.isLiquid()) {
return false; return false;
} else if (MaterialCollections.getAllUnbreakableBlocks().contains(b.getType())) { } else if (SlimefunTag.UNBREAKABLE_MATERIALS.isTagged(b.getType())) {
return false; return false;
} else if (!b.getWorld().getWorldBorder().isInside(b.getLocation())) { } else if (!b.getWorld().getWorldBorder().isInside(b.getLocation())) {
return false; return false;

View File

@ -6,6 +6,9 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Effect; import org.bukkit.Effect;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@ -43,6 +46,7 @@ public class GoldPan extends SimpleSlimefunItem<ItemUseHandler> implements Recip
private final RandomizedSet<ItemStack> randomizer = new RandomizedSet<>(); private final RandomizedSet<ItemStack> randomizer = new RandomizedSet<>();
private final Set<GoldPanDrop> drops = new HashSet<>(); private final Set<GoldPanDrop> drops = new HashSet<>();
@ParametersAreNonnullByDefault
public GoldPan(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public GoldPan(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);
@ -51,7 +55,13 @@ public class GoldPan extends SimpleSlimefunItem<ItemUseHandler> implements Recip
addItemHandler(onEntityInteract()); addItemHandler(onEntityInteract());
} }
protected Material getInput() { /**
* This method returns the target {@link Material} for this {@link GoldPan}.
*
* @return The {@link Material} this {@link GoldPan} can be used on
*/
@Nonnull
protected Material getTargetMaterial() {
return Material.GRAVEL; return Material.GRAVEL;
} }
@ -84,6 +94,13 @@ public class GoldPan extends SimpleSlimefunItem<ItemUseHandler> implements Recip
} }
} }
/**
* This returns a random output {@link ItemStack} that can be obtained via
* this {@link GoldPan}.
*
* @return a random {@link ItemStack} obtained by this {@link GoldPan}
*/
@Nonnull
public ItemStack getRandomOutput() { public ItemStack getRandomOutput() {
return randomizer.getRandom(); return randomizer.getRandom();
} }
@ -101,7 +118,7 @@ public class GoldPan extends SimpleSlimefunItem<ItemUseHandler> implements Recip
if (block.isPresent()) { if (block.isPresent()) {
Block b = block.get(); Block b = block.get();
if (b.getType() == getInput() && SlimefunPlugin.getProtectionManager().hasPermission(e.getPlayer(), b.getLocation(), ProtectableAction.BREAK_BLOCK)) { if (b.getType() == getTargetMaterial() && SlimefunPlugin.getProtectionManager().hasPermission(e.getPlayer(), b.getLocation(), ProtectableAction.BREAK_BLOCK)) {
ItemStack output = getRandomOutput(); ItemStack output = getRandomOutput();
b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, b.getType()); b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, b.getType());
@ -133,7 +150,7 @@ public class GoldPan extends SimpleSlimefunItem<ItemUseHandler> implements Recip
for (GoldPanDrop drop : drops) { for (GoldPanDrop drop : drops) {
if (drop.getValue() > 0) { if (drop.getValue() > 0) {
recipes.add(new ItemStack(getInput())); recipes.add(new ItemStack(getTargetMaterial()));
recipes.add(drop.getOutput()); recipes.add(drop.getOutput());
} }
} }

View File

@ -16,6 +16,7 @@ import org.bukkit.util.Vector;
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils; import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.api.items.settings.IntRangeSetting;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
@ -38,7 +39,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class GrapplingHook extends SimpleSlimefunItem<ItemUseHandler> { public class GrapplingHook extends SimpleSlimefunItem<ItemUseHandler> {
private final ItemSetting<Boolean> consumeOnUse = new ItemSetting<>("consume-on-use", true); private final ItemSetting<Boolean> consumeOnUse = new ItemSetting<>("consume-on-use", true);
private final ItemSetting<Integer> despawnTicks = new ItemSetting<>("despawn-seconds", 60); private final ItemSetting<Integer> despawnTicks = new IntRangeSetting("despawn-seconds", 0, 60, Integer.MAX_VALUE);
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public GrapplingHook(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public GrapplingHook(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {

View File

@ -12,7 +12,6 @@ import org.bukkit.block.data.Orientable;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.blocks.Vein; import io.github.thebusybiscuit.cscorelib2.blocks.Vein;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable; import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
@ -49,7 +48,7 @@ public class LumberAxe extends SimpleSlimefunItem<ItemUseHandler> implements Not
private ToolUseHandler onBlockBreak() { private ToolUseHandler onBlockBreak() {
return (e, tool, fortune, drops) -> { return (e, tool, fortune, drops) -> {
if (MaterialCollections.getAllLogs().contains(e.getBlock().getType())) { if (Tag.LOGS.isTagged(e.getBlock().getType())) {
List<Block> logs = Vein.find(e.getBlock(), MAX_BROKEN, b -> Tag.LOGS.isTagged(b.getType())); List<Block> logs = Vein.find(e.getBlock(), MAX_BROKEN, b -> Tag.LOGS.isTagged(b.getType()));
if (logs.contains(e.getBlock())) { if (logs.contains(e.getBlock())) {

View File

@ -17,7 +17,7 @@ public class NetherGoldPan extends GoldPan {
} }
@Override @Override
protected Material getInput() { protected Material getTargetMaterial() {
return Material.SOUL_SAND; return Material.SOUL_SAND;
} }

View File

@ -1,24 +1,41 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.tools; package io.github.thebusybiscuit.slimefun4.implementation.items.tools;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Event.Result; import org.bukkit.event.Event.Result;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.api.items.settings.IntRangeSetting;
import io.github.thebusybiscuit.slimefun4.core.attributes.DamageableItem; import io.github.thebusybiscuit.slimefun4.core.attributes.DamageableItem;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/**
* The {@link PickaxeOfTheSeeker} will make you face the nearest ore upon right clicking.
*
* @author TheBusyBiscuit
*
*/
public class PickaxeOfTheSeeker extends SimpleSlimefunItem<ItemUseHandler> implements DamageableItem { public class PickaxeOfTheSeeker extends SimpleSlimefunItem<ItemUseHandler> implements DamageableItem {
private final ItemSetting<Integer> maxRange = new IntRangeSetting("max-range", 1, 5, Integer.MAX_VALUE);
@ParametersAreNonnullByDefault
public PickaxeOfTheSeeker(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public PickaxeOfTheSeeker(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);
addItemSetting(maxRange);
} }
@Override @Override
@ -42,21 +59,35 @@ public class PickaxeOfTheSeeker extends SimpleSlimefunItem<ItemUseHandler> imple
float yaw = alpha2 > 90 ? (180 - alpha1) : alpha1; float yaw = alpha2 > 90 ? (180 - alpha1) : alpha1;
float pitch = (float) ((-Math.atan((closest.getY() - 0.5 - p.getLocation().getY()) / Math.sqrt(l * l + w * w))) * 180 / Math.PI); float pitch = (float) ((-Math.atan((closest.getY() - 0.5 - p.getLocation().getY()) / Math.sqrt(l * l + w * w))) * 180 / Math.PI);
p.teleport(new Location(p.getWorld(), p.getLocation().getX(), p.getLocation().getY(), p.getLocation().getZ(), yaw, pitch)); // We could teleport them asynchronously here...
// But we're only changing the pitch and yaw anyway.
Location loc = new Location(p.getWorld(), p.getLocation().getX(), p.getLocation().getY(), p.getLocation().getZ(), yaw, pitch);
p.teleport(loc);
} }
damageItem(p, e.getItem()); damageItem(p, e.getItem());
}; };
} }
private Block findClosestOre(Player p) { @Nullable
private Block findClosestOre(@Nonnull Player p) {
Block start = p.getLocation().getBlock();
Block closest = null; Block closest = null;
double lastDistance = Double.MAX_VALUE;
int range = maxRange.getValue();
for (int x = -4; x <= 4; x++) { for (int x = -range; x <= range; x++) {
for (int y = -4; y <= 4; y++) { for (int y = -range; y <= range; y++) {
for (int z = -4; z <= 4; z++) { for (int z = -range; z <= range; z++) {
if (MaterialCollections.getAllOres().contains(p.getLocation().add(x, y, z).getBlock().getType()) && (closest == null || p.getLocation().distanceSquared(closest.getLocation()) > p.getLocation().distanceSquared(p.getLocation().add(x, y, z)))) { Block block = start.getRelative(x, y, z);
closest = p.getLocation().getBlock().getRelative(x, y, z);
if (SlimefunTag.PICKAXE_OF_THE_SEEKER_BLOCKS.isTagged(block.getType())) {
double distance = block.getLocation().distanceSquared(start.getLocation());
if (closest == null || distance < lastDistance) {
closest = block;
lastDistance = distance;
}
} }
} }
} }

View File

@ -2,6 +2,8 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.tools;
import java.util.List; import java.util.List;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Effect; import org.bukkit.Effect;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@ -11,12 +13,13 @@ import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.blocks.Vein; import io.github.thebusybiscuit.cscorelib2.blocks.Vein;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.api.items.settings.IntRangeSetting;
import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
@ -31,32 +34,25 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
*/ */
public class PickaxeOfVeinMining extends SimpleSlimefunItem<ToolUseHandler> { public class PickaxeOfVeinMining extends SimpleSlimefunItem<ToolUseHandler> {
private final ItemSetting<Integer> maxBlocks = new ItemSetting<Integer>("max-blocks", 16) { private final ItemSetting<Integer> maxBlocks = new IntRangeSetting("max-blocks", 1, 16, Integer.MAX_VALUE);
@Override
public boolean validateInput(Integer input) {
// We do not wanna allow any negative values here
return super.validateInput(input) && input.intValue() > 0;
}
};
@ParametersAreNonnullByDefault
public PickaxeOfVeinMining(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public PickaxeOfVeinMining(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);
addItemSetting(maxBlocks); addItemSetting(maxBlocks);
} }
@Override @Override
public ToolUseHandler getItemHandler() { public ToolUseHandler getItemHandler() {
return (e, tool, fortune, drops) -> { return (e, tool, fortune, drops) -> {
if (MaterialCollections.getAllOres().contains(e.getBlock().getType())) { if (SlimefunTag.PICKAXE_OF_VEIN_MINING_BLOCKS.isTagged(e.getBlock().getType())) {
List<Block> blocks = Vein.find(e.getBlock(), maxBlocks.getValue(), MaterialCollections.getAllOres()); List<Block> blocks = Vein.find(e.getBlock(), maxBlocks.getValue(), b -> SlimefunTag.PICKAXE_OF_VEIN_MINING_BLOCKS.isTagged(b.getType()));
breakBlocks(e.getPlayer(), blocks, fortune, tool); breakBlocks(e.getPlayer(), blocks, fortune, tool);
} }
}; };
} }
@ParametersAreNonnullByDefault
private void breakBlocks(Player p, List<Block> blocks, int fortune, ItemStack tool) { private void breakBlocks(Player p, List<Block> blocks, int fortune, ItemStack tool) {
for (Block b : blocks) { for (Block b : blocks) {
if (SlimefunPlugin.getProtectionManager().hasPermission(p, b.getLocation(), ProtectableAction.BREAK_BLOCK)) { if (SlimefunPlugin.getProtectionManager().hasPermission(p, b.getLocation(), ProtectableAction.BREAK_BLOCK)) {
@ -65,7 +61,6 @@ public class PickaxeOfVeinMining extends SimpleSlimefunItem<ToolUseHandler> {
if (tool.containsEnchantment(Enchantment.SILK_TOUCH)) { if (tool.containsEnchantment(Enchantment.SILK_TOUCH)) {
b.getWorld().dropItemNaturally(b.getLocation(), new ItemStack(b.getType())); b.getWorld().dropItemNaturally(b.getLocation(), new ItemStack(b.getType()));
} else { } else {
for (ItemStack drop : b.getDrops(tool)) { for (ItemStack drop : b.getDrops(tool)) {
b.getWorld().dropItemNaturally(b.getLocation(), drop.getType().isBlock() ? drop : new CustomItem(drop, fortune)); b.getWorld().dropItemNaturally(b.getLocation(), drop.getType().isBlock() ? drop : new CustomItem(drop, fortune));
} }

View File

@ -3,23 +3,32 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.tools;
import java.util.Collection; import java.util.Collection;
import java.util.Optional; import java.util.Optional;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Effect; import org.bukkit.Effect;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections;
import io.github.thebusybiscuit.slimefun4.core.attributes.DamageableItem; import io.github.thebusybiscuit.slimefun4.core.attributes.DamageableItem;
import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/**
* The {@link SmeltersPickaxe} automatically smelts any ore you mine.
*
* @author TheBusyBiscuit
*
*/
public class SmeltersPickaxe extends SimpleSlimefunItem<ToolUseHandler> implements DamageableItem { public class SmeltersPickaxe extends SimpleSlimefunItem<ToolUseHandler> implements DamageableItem {
@ParametersAreNonnullByDefault
public SmeltersPickaxe(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public SmeltersPickaxe(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);
} }
@ -27,12 +36,14 @@ public class SmeltersPickaxe extends SimpleSlimefunItem<ToolUseHandler> implemen
@Override @Override
public ToolUseHandler getItemHandler() { public ToolUseHandler getItemHandler() {
return (e, tool, fortune, drops) -> { return (e, tool, fortune, drops) -> {
if (MaterialCollections.getAllOres().contains(e.getBlock().getType()) && !BlockStorage.hasBlockInfo(e.getBlock())) { Block b = e.getBlock();
Collection<ItemStack> blockDrops = e.getBlock().getDrops(getItem());
if (SlimefunTag.SMELTERS_PICKAXE_BLOCKS.isTagged(b.getType()) && !BlockStorage.hasBlockInfo(b)) {
Collection<ItemStack> blockDrops = b.getDrops(getItem());
for (ItemStack drop : blockDrops) { for (ItemStack drop : blockDrops) {
if (drop != null && drop.getType() != Material.AIR) { if (drop != null && drop.getType() != Material.AIR) {
smelt(e.getBlock(), drop, fortune); smelt(b, drop, fortune);
drops.add(drop); drops.add(drop);
} }
} }
@ -42,6 +53,7 @@ public class SmeltersPickaxe extends SimpleSlimefunItem<ToolUseHandler> implemen
}; };
} }
@ParametersAreNonnullByDefault
private void smelt(Block b, ItemStack drop, int fortune) { private void smelt(Block b, ItemStack drop, int fortune) {
Optional<ItemStack> furnaceOutput = SlimefunPlugin.getMinecraftRecipeService().getFurnaceOutput(drop); Optional<ItemStack> furnaceOutput = SlimefunPlugin.getMinecraftRecipeService().getFurnaceOutput(drop);

View File

@ -1,5 +1,7 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.weapons; package io.github.thebusybiscuit.slimefun4.implementation.items.weapons;
import java.util.Collection;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Particle; import org.bukkit.Particle;
import org.bukkit.Sound; import org.bukkit.Sound;
@ -11,12 +13,11 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.api.items.settings.IntRangeSetting;
import io.github.thebusybiscuit.slimefun4.core.handlers.BowShootHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.BowShootHandler;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
import java.util.Collection;
/** /**
* The {@link ExplosiveBow} is a {@link SlimefunBow} which creates a fake explosion when it hits * The {@link ExplosiveBow} is a {@link SlimefunBow} which creates a fake explosion when it hits
* a {@link LivingEntity}. Any nearby {@link LivingEntity LivingEntities} get pushed away and * a {@link LivingEntity}. Any nearby {@link LivingEntity LivingEntities} get pushed away and
@ -30,14 +31,7 @@ import java.util.Collection;
*/ */
public class ExplosiveBow extends SlimefunBow { public class ExplosiveBow extends SlimefunBow {
private final ItemSetting<Integer> range = new ItemSetting<Integer>("explosion-range", 3) { private final ItemSetting<Integer> range = new IntRangeSetting("explosion-range", 1, 3, Integer.MAX_VALUE);
@Override
public boolean validateInput(Integer input) {
return super.validateInput(input) && input > 0;
}
};
public ExplosiveBow(Category category, SlimefunItemStack item, ItemStack[] recipe) { public ExplosiveBow(Category category, SlimefunItemStack item, ItemStack[] recipe) {
super(category, item, recipe); super(category, item, recipe);

View File

@ -14,6 +14,7 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.inventory.meta.SkullMeta;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.api.items.settings.IntRangeSetting;
import io.github.thebusybiscuit.slimefun4.core.handlers.EntityKillHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.EntityKillHandler;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
@ -22,11 +23,11 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class SwordOfBeheading extends SimpleSlimefunItem<EntityKillHandler> { public class SwordOfBeheading extends SimpleSlimefunItem<EntityKillHandler> {
private final ItemSetting<Integer> chanceZombie = new ItemSetting<>("chance.ZOMBIE", 40); private final ItemSetting<Integer> chanceZombie = new IntRangeSetting("chance.ZOMBIE", 0, 40, 100);
private final ItemSetting<Integer> chanceSkeleton = new ItemSetting<>("chance.SKELETON", 40); private final ItemSetting<Integer> chanceSkeleton = new IntRangeSetting("chance.SKELETON", 0, 40, 100);
private final ItemSetting<Integer> chanceWitherSkeleton = new ItemSetting<>("chance.WITHER_SKELETON", 25); private final ItemSetting<Integer> chanceWitherSkeleton = new IntRangeSetting("chance.WITHER_SKELETON", 0, 25, 100);
private final ItemSetting<Integer> chanceCreeper = new ItemSetting<>("chance.CREEPER", 40); private final ItemSetting<Integer> chanceCreeper = new IntRangeSetting("chance.CREEPER", 0, 40, 100);
private final ItemSetting<Integer> chancePlayer = new ItemSetting<>("chance.PLAYER", 70); private final ItemSetting<Integer> chancePlayer = new IntRangeSetting("chance.PLAYER", 0, 70, 100);
public SwordOfBeheading(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public SwordOfBeheading(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);

View File

@ -7,6 +7,7 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.api.items.settings.IntRangeSetting;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.VampireBladeListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.VampireBladeListener;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
@ -25,7 +26,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class VampireBlade extends SlimefunItem { public class VampireBlade extends SlimefunItem {
private static final double HEALING_AMOUNT = 4.0; private static final double HEALING_AMOUNT = 4.0;
private final ItemSetting<Integer> chance = new ItemSetting<>("chance", 45); private final ItemSetting<Integer> chance = new IntRangeSetting("chance", 0, 45, 100);
public VampireBlade(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { public VampireBlade(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe); super(category, item, recipeType, recipe);

View File

@ -1,11 +1,9 @@
package io.github.thebusybiscuit.slimefun4.implementation.listeners; package io.github.thebusybiscuit.slimefun4.implementation.listeners;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Random; import java.util.Random;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -13,7 +11,6 @@ import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
@ -30,6 +27,7 @@ import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler;
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler; import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason;
@ -49,18 +47,8 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
*/ */
public class BlockListener implements Listener { public class BlockListener implements Listener {
// Materials that require a Block under it, e.g. Pressure Plates
private final Set<Material> sensitiveMaterials = EnumSet.noneOf(Material.class);
public BlockListener(@Nonnull SlimefunPlugin plugin) { public BlockListener(@Nonnull SlimefunPlugin plugin) {
plugin.getServer().getPluginManager().registerEvents(this, plugin); plugin.getServer().getPluginManager().registerEvents(this, plugin);
sensitiveMaterials.add(Material.CAKE);
sensitiveMaterials.add(Material.STONE_PRESSURE_PLATE);
sensitiveMaterials.add(Material.LIGHT_WEIGHTED_PRESSURE_PLATE);
sensitiveMaterials.add(Material.HEAVY_WEIGHTED_PRESSURE_PLATE);
sensitiveMaterials.addAll(Tag.SAPLINGS.getValues());
sensitiveMaterials.addAll(Tag.WOODEN_PRESSURE_PLATES.getValues());
} }
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
@ -175,7 +163,7 @@ public class BlockListener implements Listener {
private void checkForSensitiveBlockAbove(Player p, Block b) { private void checkForSensitiveBlockAbove(Player p, Block b) {
Block blockAbove = b.getRelative(BlockFace.UP); Block blockAbove = b.getRelative(BlockFace.UP);
if (sensitiveMaterials.contains(blockAbove.getType())) { if (SlimefunTag.SENSITIVE_MATERIALS.isTagged(blockAbove.getType())) {
SlimefunItem sfItem = BlockStorage.check(blockAbove); SlimefunItem sfItem = BlockStorage.check(blockAbove);
if (sfItem != null && !sfItem.useVanillaBlockBreaking()) { if (sfItem != null && !sfItem.useVanillaBlockBreaking()) {

View File

@ -4,7 +4,6 @@ import javax.annotation.Nonnull;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.data.type.Piston; import org.bukkit.block.data.type.Piston;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
@ -21,6 +20,7 @@ import org.bukkit.event.player.PlayerBucketEmptyEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.BlockStorage;
/** /**
@ -86,12 +86,8 @@ public class BlockPhysicsListener implements Listener {
Block block = e.getToBlock(); Block block = e.getToBlock();
Material type = block.getType(); Material type = block.getType();
if (type == Material.PLAYER_HEAD || type == Material.PLAYER_WALL_HEAD || Tag.SAPLINGS.isTagged(type)) { if (SlimefunTag.FLUID_SENSITIVE_MATERIALS.isTagged(block.getType()) && BlockStorage.hasBlockInfo(block)) {
String item = BlockStorage.checkID(block); e.setCancelled(true);
if (item != null) {
e.setCancelled(true);
}
} }
} }

View File

@ -45,7 +45,8 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans.MagicianTalisman; import io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans.MagicianTalisman;
import io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans.Talisman; import io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans.Talisman;
import io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans.TalismanEnchantment; import io.github.thebusybiscuit.slimefun4.implementation.settings.TalismanEnchantment;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
public class TalismanListener implements Listener { public class TalismanListener implements Listener {
@ -287,7 +288,7 @@ public class TalismanListener implements Listener {
@EventHandler @EventHandler
public void onBlockBreak(BlockBreakEvent e) { public void onBlockBreak(BlockBreakEvent e) {
if (e.getBlock().getType().name().endsWith("_ORE")) { if (SlimefunTag.CAVEMAN_TALISMAN_TRIGGERS.isTagged(e.getBlock().getType())) {
Talisman.checkFor(e, SlimefunItems.TALISMAN_CAVEMAN); Talisman.checkFor(e, SlimefunItems.TALISMAN_CAVEMAN);
} }
} }

View File

@ -0,0 +1,52 @@
package io.github.thebusybiscuit.slimefun4.implementation.settings;
import javax.annotation.Nonnull;
import org.bukkit.Material;
import io.github.thebusybiscuit.slimefun4.api.events.ClimbingPickLaunchEvent;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.ClimbingPick;
/**
* This is an {@link ItemSetting}
*
* @author TheBusyBiscuit
*
* @see ClimbingPick
* @see ClimbingPickLaunchEvent
*
*/
public class ClimbableSurface extends ItemSetting<Double> {
private final Material type;
/**
* This creates a new {@link ClimbableSurface} for the given {@link Material}.
*
* @param surface
* The {@link Material} of this surface
* @param defaultValue
* The default launch amount
*/
public ClimbableSurface(@Nonnull Material surface, double defaultValue) {
super("launch-amounts." + surface.name(), defaultValue);
this.type = surface;
}
@Override
public boolean validateInput(Double input) {
return super.validateInput(input) && input >= 0;
}
/**
* This returns the {@link Material} of this surface.
*
* @return The {@link Material} of this surface
*/
@Nonnull
public Material getType() {
return type;
}
}

View File

@ -1,8 +1,11 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans; package io.github.thebusybiscuit.slimefun4.implementation.settings;
import javax.annotation.Nonnull;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans.MagicianTalisman;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.TalismanListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.TalismanListener;
/** /**
@ -17,7 +20,7 @@ public class TalismanEnchantment extends ItemSetting<Boolean> {
private final Enchantment enchantment; private final Enchantment enchantment;
private final int level; private final int level;
public TalismanEnchantment(Enchantment enchantment, int level) { public TalismanEnchantment(@Nonnull Enchantment enchantment, int level) {
super("allow-enchantments." + enchantment.getKey().getKey() + ".level." + level, true); super("allow-enchantments." + enchantment.getKey().getKey() + ".level." + level, true);
this.enchantment = enchantment; this.enchantment = enchantment;
@ -29,6 +32,7 @@ public class TalismanEnchantment extends ItemSetting<Boolean> {
* *
* @return The associated {@link Enchantment} * @return The associated {@link Enchantment}
*/ */
@Nonnull
public Enchantment getEnchantment() { public Enchantment getEnchantment() {
return enchantment; return enchantment;
} }

View File

@ -0,0 +1,6 @@
/**
* This package holds implementations of {@link io.github.thebusybiscuit.slimefun4.api.items.ItemSetting} that are for
* very specific {@link me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem SlimefunItems} and generally not
* very useful out of their context.
*/
package io.github.thebusybiscuit.slimefun4.implementation.settings;

View File

@ -47,7 +47,6 @@ public final class PostSetup {
public static void setupWiki() { public static void setupWiki() {
Slimefun.getLogger().log(Level.INFO, "Loading Wiki pages..."); Slimefun.getLogger().log(Level.INFO, "Loading Wiki pages...");
JsonParser parser = new JsonParser(); JsonParser parser = new JsonParser();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(SlimefunPlugin.class.getResourceAsStream("/wiki.json"), StandardCharsets.UTF_8))) { try (BufferedReader reader = new BufferedReader(new InputStreamReader(SlimefunPlugin.class.getResourceAsStream("/wiki.json"), StandardCharsets.UTF_8))) {

View File

@ -109,7 +109,7 @@ public enum HeadTexture {
IRON_GOLEM("89091d79ea0f59ef7ef94d7bba6e5f17f2f7d4572c44f90f76c4819a714"), IRON_GOLEM("89091d79ea0f59ef7ef94d7bba6e5f17f2f7d4572c44f90f76c4819a714"),
PIGLIN_HEAD("2882af1294a74023e6919a31d1a027310f2e142afb4667d230d155e7f21dbb41"); PIGLIN_HEAD("2882af1294a74023e6919a31d1a027310f2e142afb4667d230d155e7f21dbb41");
public static final HeadTexture[] values = values(); public static final HeadTexture[] valuesCache = values();
private final String texture; private final String texture;
@ -123,6 +123,7 @@ public enum HeadTexture {
* *
* @return The associated texture hash * @return The associated texture hash
*/ */
@Nonnull
public String getTexture() { public String getTexture() {
return texture; return texture;
} }
@ -132,6 +133,7 @@ public enum HeadTexture {
* *
* @return A custom head {@link ItemStack} * @return A custom head {@link ItemStack}
*/ */
@Nonnull
public ItemStack getAsItemStack() { public ItemStack getAsItemStack() {
return SlimefunUtils.getCustomHead(getTexture()); return SlimefunUtils.getCustomHead(getTexture());
} }

View File

@ -16,6 +16,7 @@ public final class PatternUtils {
private PatternUtils() {} private PatternUtils() {}
public static final Pattern COLON = Pattern.compile(":");
public static final Pattern SEMICOLON = Pattern.compile(";"); public static final Pattern SEMICOLON = Pattern.compile(";");
public static final Pattern HASH = Pattern.compile("#"); public static final Pattern HASH = Pattern.compile("#");
public static final Pattern COMMA = Pattern.compile(","); public static final Pattern COMMA = Pattern.compile(",");
@ -27,4 +28,8 @@ public final class PatternUtils {
public static final Pattern NUMERIC = Pattern.compile("[0-9]+"); public static final Pattern NUMERIC = Pattern.compile("[0-9]+");
public static final Pattern NUMBER_SEPARATOR = Pattern.compile("[,.]"); public static final Pattern NUMBER_SEPARATOR = Pattern.compile("[,.]");
public static final Pattern MINECRAFT_MATERIAL = Pattern.compile("minecraft:[a-z_]+");
public static final Pattern MINECRAFT_TAG = Pattern.compile("#minecraft:[a-z_]+");
public static final Pattern SLIMEFUN_TAG = Pattern.compile("#slimefun:[a-z_]+");
} }

View File

@ -0,0 +1,325 @@
package io.github.thebusybiscuit.slimefun4.utils.tags;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.apache.commons.lang.Validate;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Tag;
import org.bukkit.block.data.Waterlogged;
import io.github.thebusybiscuit.slimefun4.api.exceptions.TagMisconfigurationException;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.BlockPlacer;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.CropGrowthAccelerator;
import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.miner.IndustrialMiner;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.ClimbingPick;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.ExplosiveShovel;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.PickaxeOfTheSeeker;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.PickaxeOfVeinMining;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.SmeltersPickaxe;
/**
* This enum contains various implementations of the {@link Tag} interface.
* Most of them serve some purpose within Slimefun's implementation, some are just pure
* extensions of the default Minecraft tags.
* The actual tag files are located in the {@literal /src/main/resources/tags} directory
* and follow Minecraft's tags.json format.
*
* @author TheBusyBiscuit
*
* @see TagParser
*
*/
public enum SlimefunTag implements Tag<Material> {
/**
* Minecraft ores.
*/
ORES,
/**
* All Shulker boxes, normal and colored.
*/
SHULKER_BOXES,
/**
* All command block variants
*/
COMMAND_BLOCKS,
/**
* Every mushroom type, red, brown and nether ones.
*/
MUSHROOMS,
/**
* Every glass variant, includes both blocks and panes.
* Also stained glass and stained glass panes.
*/
GLASS,
/**
* All variants of glass, normal and stained.
*/
GLASS_BLOCKS,
/**
* All variants of glass panes, normal and stained.
*/
GLASS_PANES,
/**
* All variants of torches, normal, soulfire and redstone.
*/
TORCHES,
/**
* All terracotta variants, does not include glazed terracotta.
*/
TERRACOTTA,
/**
* All ice variants, normal, packed, blue and whatever else there is.
*/
ICE_VARIANTS,
/**
* All stone variants, normal, andesite, diorite, granite and whatever else may come.
*/
STONE_VARIANTS,
/**
* All variants of concrete powder.
* Can you believe there is no tag for this already?
*/
CONCRETE_POWDERS,
/**
* Materials which are sensitive to break.
* Things like Saplings or Pressure plates which break as well when you break
* the block beneath them.
*/
SENSITIVE_MATERIALS,
/**
* These Materials are sensitive to fluids, they cannot be {@link Waterlogged}
* and would break in contact with water.
*/
FLUID_SENSITIVE_MATERIALS,
/**
* These materials are just unbreakable, like bedrock for example.
*/
UNBREAKABLE_MATERIALS,
/**
* Materials which cannot be reliably placed using a {@link BlockPlacer}.
*/
BLOCK_PLACER_IGNORED_MATERIALS,
/**
* All materials which the {@link ExplosiveShovel} can break.
*/
EXPLOSIVE_SHOVEL_BLOCKS,
/**
* All materials (ores) which the {@link PickaxeOfVeinMining} recognizes.
*/
PICKAXE_OF_VEIN_MINING_BLOCKS,
/**
* All materials (ores) which the {@link PickaxeOfTheSeeker} recognizes.
*/
PICKAXE_OF_THE_SEEKER_BLOCKS,
/**
* All materials which the {@link SmeltersPickaxe} will try and smelt.
*/
SMELTERS_PICKAXE_BLOCKS,
/**
* All materials (ores) which the {@link IndustrialMiner} will try to mine.
*/
INDUSTRIAL_MINER_ORES,
/**
* All materials (crops) which the {@link CropGrowthAccelerator} will recognize.
*/
CROP_GROWTH_ACCELERATOR_BLOCKS,
/**
* All <strong>strong</strong> materials which the {@link ClimbingPick} is able to climb.
*/
CLIMBING_PICK_STRONG_SURFACES,
/**
* All <strong>weak</strong> materials which the {@link ClimbingPick} is able to climb.
*/
CLIMBING_PICK_WEAK_SURFACES,
/**
* This {@link SlimefunTag} holds all surfaces for the {@link ClimbingPick}.
* This is an aggregation of {@code CLIMBING_PICK_STRONG_SURFACES} and {@code CLIMBING_PICK_WEAK_SURFACES}
*/
CLIMBING_PICK_SURFACES,
/**
* All materials (ores) which trigger the Talisman of the Caveman.
*/
CAVEMAN_TALISMAN_TRIGGERS;
private static final Map<String, SlimefunTag> nameLookup = new HashMap<>();
public static final SlimefunTag[] valuesCache = values();
static {
for (SlimefunTag tag : valuesCache) {
nameLookup.put(tag.name(), tag);
}
}
private final NamespacedKey key;
private final Set<Material> includedMaterials = new HashSet<>();
private final Set<Tag<Material>> additionalTags = new HashSet<>();
/**
* This constructs a new {@link SlimefunTag}.
* The {@link NamespacedKey} will be automatically inferred using
* {@link SlimefunPlugin} and {@link #name()}.
*/
SlimefunTag() {
key = new NamespacedKey(SlimefunPlugin.instance(), name().toLowerCase(Locale.ROOT));
}
/**
* This method reloads this {@link SlimefunTag} from our resources directory.
*
* @throws TagMisconfigurationException
* This is thrown whenever a {@link SlimefunTag} could not be parsed properly
*/
public void reload() throws TagMisconfigurationException {
new TagParser(this).parse(this, (materials, tags) -> {
this.includedMaterials.clear();
this.includedMaterials.addAll(materials);
this.additionalTags.clear();
this.additionalTags.addAll(tags);
});
}
/**
* This method reloads every single {@link SlimefunTag} from the resources directory.
* It is equivalent to running {@link #reload()} on every single {@link SlimefunTag} manually.
*
* Do keep in mind though that any misconfigured {@link SlimefunTag} will abort the entire
* method and throw a {@link TagMisconfigurationException}. So one faulty {@link SlimefunTag}
* will stop the reloading process.
*
* @throws TagMisconfigurationException
* This is thrown if one of the {@link SlimefunTag SlimefunTags} could not be parsed correctly
*/
public static void reloadAll() throws TagMisconfigurationException {
for (SlimefunTag tag : valuesCache) {
tag.reload();
}
}
@Nonnull
@Override
public NamespacedKey getKey() {
return key;
}
@Override
public boolean isTagged(@Nonnull Material item) {
if (includedMaterials.contains(item)) {
return true;
} else {
// Check if any of our additional Tags contain this Materials
for (Tag<Material> tag : additionalTags) {
if (tag.isTagged(item)) {
return true;
}
}
// Now we can be sure it isn't tagged in any way
return false;
}
}
@Nonnull
@Override
public Set<Material> getValues() {
if (additionalTags.isEmpty()) {
return Collections.unmodifiableSet(includedMaterials);
} else {
Set<Material> materials = new HashSet<>(includedMaterials);
for (Tag<Material> tag : additionalTags) {
materials.addAll(tag.getValues());
}
return materials;
}
}
/**
* This returns a {@link Set} of {@link Tag Tags} which are children of this {@link SlimefunTag},
* these can be other {@link SlimefunTag SlimefunTags} or regular {@link Tag Tags}.
*
* <strong>The returned {@link Set} is immutable</strong>
*
* @return An immutable {@link Set} of all sub tags.
*/
@Nonnull
public Set<Tag<Material>> getSubTags() {
return Collections.unmodifiableSet(additionalTags);
}
/**
* This method returns an Array representation for this {@link SlimefunTag}.
*
* @return A {@link Material} array for this {@link Tag}
*/
@Nonnull
public Material[] toArray() {
return getValues().toArray(new Material[0]);
}
/**
* This returns a {@link Stream} of {@link Material Materials} for this {@link SlimefunTag}.
*
* @return A {@link Stream} of {@link Material Materials}
*/
@Nonnull
public Stream<Material> stream() {
return getValues().stream();
}
/**
* Get a value from the cache map rather than calling {@link Enum#valueOf(Class, String)}.
* This is 25-40% quicker than the standard {@link Enum#valueOf(Class, String)} depending on
* your Java version. It also means that you can avoid an IllegalArgumentException which let's
* face it is always good.
*
* @param value
* The value which you would like to look up.
*
* @return The {@link SlimefunTag} or null if it does not exist.
*/
@Nullable
public static SlimefunTag getTag(@Nonnull String value) {
Validate.notNull(value, "A tag cannot be null!");
return nameLookup.get(value);
}
}

View File

@ -0,0 +1,201 @@
package io.github.thebusybiscuit.slimefun4.utils.tags;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.Keyed;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Tag;
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 com.google.gson.JsonPrimitive;
import io.github.thebusybiscuit.slimefun4.api.exceptions.TagMisconfigurationException;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
/**
* The {@link TagParser} is responsible for parsing a JSON input into a {@link SlimefunTag}.
*
* @author TheBusyBiscuit
*
* @see SlimefunTag
*
*/
public class TagParser implements Keyed {
private final NamespacedKey key;
/**
* This constructs a new {@link TagParser}.
*
* @param key
* The {@link NamespacedKey} of the resulting {@link SlimefunTag}
*/
public TagParser(@Nonnull NamespacedKey key) {
this.key = key;
}
/**
* This constructs a new {@link TagParser} for the given {@link SlimefunTag}
*
* @param tag
* The {@link SlimefunTag} to parse inputs for
*/
TagParser(@Nonnull SlimefunTag tag) {
this(tag.getKey());
}
void parse(@Nonnull SlimefunTag tag, @Nonnull BiConsumer<Set<Material>, Set<Tag<Material>>> callback) throws TagMisconfigurationException {
String path = "/tags/" + tag.getKey().getKey() + ".json";
try (BufferedReader reader = new BufferedReader(new InputStreamReader(SlimefunPlugin.class.getResourceAsStream(path), StandardCharsets.UTF_8))) {
parse(reader.lines().collect(Collectors.joining("")), callback);
} catch (IOException x) {
throw new TagMisconfigurationException(key, x.getMessage());
}
}
/**
* This will parse the given JSON {@link String} and run the provided callback with {@link Set Sets} of
* matched {@link Material Materials} and {@link Tag Tags}.
*
* @param json
* The JSON {@link String} to parse
* @param callback
* A callback to run after successfully parsing the input
*
* @throws TagMisconfigurationException
* This is thrown whenever the given input is malformed or no adequate
* {@link Material} or {@link Tag} could be found
*/
public void parse(@Nonnull String json, @Nonnull BiConsumer<Set<Material>, Set<Tag<Material>>> callback) throws TagMisconfigurationException {
Validate.notNull(json, "Cannot parse a null String");
try {
Set<Material> materials = new HashSet<>();
Set<Tag<Material>> tags = new HashSet<>();
JsonParser parser = new JsonParser();
JsonObject root = parser.parse(json).getAsJsonObject();
JsonElement child = root.get("values");
if (child instanceof JsonArray) {
JsonArray values = child.getAsJsonArray();
for (JsonElement element : values) {
if (element instanceof JsonPrimitive && ((JsonPrimitive) element).isString()) {
// Strings will be parsed directly
parsePrimitiveValue(element.getAsString(), materials, tags);
} else if (element instanceof JsonObject) {
// JSONObjects can have a "required" property which can make
// it optional to resolve the underlying value
parseComplexValue(element.getAsJsonObject(), materials, tags);
} else {
throw new TagMisconfigurationException(key, "Unexpected value format: " + element.getClass().getSimpleName() + " - " + element.toString());
}
}
// Run the callback with the filled-in materials and tags
callback.accept(materials, tags);
} else {
// The JSON seems to be empty yet valid
throw new TagMisconfigurationException(key, "No values array specified");
}
} catch (IllegalStateException | JsonParseException x) {
throw new TagMisconfigurationException(key, x.getMessage());
}
}
@ParametersAreNonnullByDefault
private void parsePrimitiveValue(String value, Set<Material> materials, Set<Tag<Material>> tags) throws TagMisconfigurationException {
if (PatternUtils.MINECRAFT_MATERIAL.matcher(value).matches()) {
// Match the NamespacedKey against Materials
Material material = Material.matchMaterial(value);
if (material != null) {
// If the Material could be matched, simply add it to our Set
materials.add(material);
} else {
throw new TagMisconfigurationException(key, "Minecraft Material '" + value + "' seems to not exist!");
}
} else if (PatternUtils.MINECRAFT_TAG.matcher(value).matches()) {
// Get the actual Key portion and match it to item and block tags.
String keyValue = PatternUtils.COLON.split(value)[1];
NamespacedKey namespacedKey = NamespacedKey.minecraft(keyValue);
Tag<Material> itemsTag = Bukkit.getTag(Tag.REGISTRY_ITEMS, namespacedKey, Material.class);
Tag<Material> blocksTag = Bukkit.getTag(Tag.REGISTRY_BLOCKS, namespacedKey, Material.class);
if (itemsTag != null) {
// We will prioritize the item tag
tags.add(itemsTag);
} else if (blocksTag != null) {
// If no item tag exists, fall back to the block tag
tags.add(blocksTag);
} else {
// If both fail, then the tag does not exist.
throw new TagMisconfigurationException(key, "There is no '" + value + "' tag in Minecraft.");
}
} else if (PatternUtils.SLIMEFUN_TAG.matcher(value).matches()) {
// Get a SlimefunTag enum value for the given key
String keyValue = PatternUtils.COLON.split(value)[1].toUpperCase(Locale.ROOT);
SlimefunTag tag = SlimefunTag.getTag(keyValue);
if (tag != null) {
tags.add(tag);
} else {
throw new TagMisconfigurationException(key, "There is no '" + value + "' tag in Slimefun");
}
} else {
// If no RegEx pattern matched, it's malformed.
throw new TagMisconfigurationException(key, "Could not recognize value '" + value + "'");
}
}
@ParametersAreNonnullByDefault
private void parseComplexValue(JsonObject entry, Set<Material> materials, Set<Tag<Material>> tags) throws TagMisconfigurationException {
JsonElement id = entry.get("id");
JsonElement required = entry.get("required");
// Check if the entry contains elements of the correct type
if (id instanceof JsonPrimitive && ((JsonPrimitive) id).isString() && required instanceof JsonPrimitive && ((JsonPrimitive) required).isBoolean()) {
if (required.getAsBoolean()) {
// If this entry is required, parse it like normal
parsePrimitiveValue(id.getAsString(), materials, tags);
} else {
// If the entry is not required, validation will be optional
try {
parsePrimitiveValue(id.getAsString(), materials, tags);
} catch (TagMisconfigurationException x) {
// This is an optional entry, so we will ignore the validation here
}
}
} else {
throw new TagMisconfigurationException(key, "Found a JSON Object value without an id!");
}
}
@Nonnull
@Override
public NamespacedKey getKey() {
return key;
}
}

View File

@ -0,0 +1,4 @@
/**
* This package holds utilities related to the {@link io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag} enum.
*/
package io.github.thebusybiscuit.slimefun4.utils.tags;

View File

@ -2,25 +2,25 @@
slimefun: slimefun:
weapons: Fegyverek weapons: Fegyverek
tools: Eszközök tools: Eszközök
items: Hasznos Tárgyak items: Hasznos tárgyak
food: Étel food: Étel
basic_machines: Alapvető Gépek basic_machines: Alapvető gépek
electricity: Energia és Elektromosság electricity: Energia és elektromosság
gps: GPS-alapú Gépek gps: GPS-alapú gépek
armor: Páncél armor: Páncél
magical_items: Varázslatos Tárgyak magical_items: Varázslatos tárgyak
magical_gadgets: Varázslatos Kütyük magical_gadgets: Varázslatos kütyük
misc: Egyéb Tárgyak misc: Egyéb tárgyak
technical_gadgets: Technikai Kütyük technical_gadgets: Technikai kütyük
resources: Erőforrások resources: Erőforrások
cargo: Szállítmány Kezelés cargo: Szállítmánykezelés
tech_misc: Műszaki Alkatrészek tech_misc: Műszaki alkatrészek
magical_armor: Varázslatos Páncél magical_armor: Varázslatos páncél
talismans: Talizmánok (I. Szint) talismans: Talizmánok (I. szint)
ender_talismans: Ender Talizmánok (II. Szint) ender_talismans: Ender talizmánok (II. szint)
christmas: Karácsony (December) christmas: Karácsony (December)
valentines_day: Valentin Nap (Február 14.) valentines_day: Valentin nap (Február 14.)
easter: Húsvét (Április) easter: Húsvét (Április)
birthday: TheBusyBiscuit születésnapja (Október 26.) birthday: TheBusyBiscuit születésnapja (Október 26.)
halloween: Halloween (Október 31.) halloween: Halloween (Október 31.)
androids: Programozható Androidok androids: Programozható androidok

View File

@ -1,28 +1,32 @@
--- ---
commands: commands:
help: Megjeleníti ezt a súgóképernyőt help: Megjeleníti ezt a súgóképernyőt
cheat: Lehetővé teszi a Tárgyak csalását cheat: Ezzel lekérhetsz tárgyakat
give: Adj valakinek Slimefun Tárgyakat give: Slimefun tárgyak lekérése egy játékosnak
guide: Adj magadnak egy Slimefun Útmutatót guide: Slimefun Útmutató lekérése
timings: Lag-Információ a Szerverről timings: Lag-információ a szerverről
teleporter: Nézd meg a többi Játékos Útpontjait teleporter: Játékosok útpontjainak megtekintése
versions: Az összes telepített Kiegészítőt listázza versions: A kiegészítők listázása
search: Keresés egy kifejezésre az Útmutatóban search: Keresés egy kifejezésre az Útmutatóban
open_guide: A könyv használata nélkül megnyitja a Slimefun útmutatóját open_guide: A könyv használata nélkül megnyitja a Slimefun útmutatóját
stats: Néhány statisztikát mutat a Játékosról stats: Néhány statisztikát mutat egy játékosról
research: research:
description: A játékosok kutatásainak Feloldása/Visszaállítása description: A játékosok kutatásainak feloldása/visszaállítása
reset: "&cVisszaállítottad %player% Ismereteit" reset: "&cVisszaállítottad %player% ismereteit"
reset-target: "&cAz ismereteidet visszaállították" reset-target: "&cAz ismereteidet visszaállították"
backpack: backpack:
description: Lekéri egy meglévő hátizsák másolatát description: Lekéri egy meglévő hátizsák másolatát
invalid-id: "&4Az azonosító nem lehet negatív szám!" invalid-id: "&4Az azonosító nem lehet negatív szám!"
player-never-joined: "&4Nincs ilyen nevű játékos!" player-never-joined: "&4Nincs ilyen nevű játékos!"
backpack-does-not-exist: "&4A megadott hátizsák nem létezik!" backpack-does-not-exist: "&4A megadott hátizsák nem létezik!"
restored-backpack-given: "&aA hátizsákod visszaállítva és hozzáadva a leltáradhoz!" restored-backpack-given: "&aA hátizsákod visszaállítva és hozzáadva az eszköztáradhoz!"
charge:
description: Feltölti a kezedben lévő tárgyat
charge-success: Tárgy feltöltve!
not-rechargeable: Ez a tárgy nem tölthető fel!
guide: guide:
search: search:
message: "&bMit szeretnél keresni?" message: "&bMire szeretnél keresni?"
name: "&7Keresés..." name: "&7Keresés..."
tooltip: "&bKlikk egy tárgy kereséséhez" tooltip: "&bKlikk egy tárgy kereséséhez"
inventory: 'Keresés erre: %item%' inventory: 'Keresés erre: %item%'
@ -30,33 +34,46 @@ guide:
- "&bMit szeretnél keresni?" - "&bMit szeretnél keresni?"
- "&7Gépeld be a keresett kifejezést a chatbe" - "&7Gépeld be a keresett kifejezést a chatbe"
cheat: cheat:
no-multiblocks: "&4A Multiblokkban nem tudsz csalni, meg kell építened!" no-multiblocks: "&4Multiblockot nem tudsz lekérni, meg kell építened!"
languages: languages:
updated: "&aA nyelvet sikeresen átállítottad erre: &b%lang%" updated: "&aA nyelvet sikeresen átállítottad erre: &b%lang%"
translations: translations:
name: "&aHiányzik valami?" name: "&aHiányzik valami?"
lore: Kattints a saját fordítás hozzáadásához lore: Kattints saját fordítás hozzáadásához
select: Kattints a nyelv kiválasztásához select: Kattints a nyelv kiválasztásához
select-default: Kattints az alapértelmezett nyelv kiválasztásához select-default: Kattints az alapértelmezett nyelv kiválasztásához
selected-language: 'Jelenleg kiválasztva:' selected-language: 'Jelenleg kiválasztva:'
change: Kattints a nyelv kiválasztásához
description:
- "&7Már lehetőséged van kiválasztani,"
- "&7hogy a Slimefun milyen nyelven"
- "&7jelenjen meg számodra. A tárgyakat"
- "&7jelenleg nem lehet lefordítani."
title: title:
main: Slimefun Útmutató main: Slimefun Útmutató
settings: Beállítások és Információk settings: Beállítások és Információk
languages: Válaszd ki a kívánt nyelvet languages: Válaszd ki a kívánt nyelvet
credits: Slimefun4 Közreműködők credits: Slimefun4 közreműködők
wiki: Slimefun4 Wiki wiki: Slimefun4 Wiki
addons: A Slimefun4 kiegészítői addons: A Slimefun4 kiegészítői
bugs: Hibajelentések bugs: Hibajelentések
source: Forráskód source: Forráskód
versions: Telepített verziók
credits: credits:
commit: Commit commit: commit
commits: Commits commits: commits
roles: roles:
developer: "&6Fejlesztő" developer: "&6Fejlesztő"
wiki: "&3Wiki Szerkesztő" wiki: "&3Wiki szerkesztő"
resourcepack: "&cForráscsomag Művész" resourcepack: "&cForráscsomag művész"
translator: "&9Fordító" translator: "&9Fordító"
profile-link: Kattints ide, hogy meglátogasd a profilját a GitHub-on profile-link: Kattints ide, hogy meglátogasd a profilját a GitHub-on
open: Kattints a közreműködők megtekintéséhez
description:
- "&7A Slimefun egy nyílt forráskódú projekt,"
- "&7amit egy hatalmas közösség tart fenn."
- "&7Több mint &e%contributors% &7közreműködő"
- "&7dolgozott rajta az évek során."
pages: pages:
previous: Előző oldal previous: Előző oldal
next: Következő oldal next: Következő oldal
@ -65,56 +82,57 @@ guide:
versions-notice: Ezek nagyon fontosak a hibák jelentésekor! versions-notice: Ezek nagyon fontosak a hibák jelentésekor!
wiki: Tekintsd meg ezt a tárgyat a hivatalos Slimefun Wikin wiki: Tekintsd meg ezt a tárgyat a hivatalos Slimefun Wikin
recipes: recipes:
machine: Ebben a Gépben készített receptek machine: Ebben a gépben készíthető receptek
miner: Erőforrások, amelyeket ezzel a Bányásszal szerezhetsz be miner: Erőforrások, amelyeket ezzel a bányásszal szerezhetsz be
generator: Rendelkezésre álló üzemanyagtípusok generator: Rendelkezésre álló üzemanyagtípusok
gold-pan: Megszerezhető források gold-pan: Megszerezhető erőforrások
climbing-pick: Megmászható felületek
back: back:
title: Vissza title: Vissza
guide: Menj vissza a Slimefun Útmutatóba guide: Visszalépés a Slimefun Útmutatóba
settings: Menj vissza a Beállítások Panelre settings: Visszalépés a Beállítások panelre
locked: LEZÁRVA locked: LEZÁRVA
locked-category: locked-category:
- Ennek a kategóriának a feloldásához - Ennek a kategóriának a feloldásához
- fel kell oldanod az összes tárgyat a - fel kell oldanod az összes tárgyat
- következő kategóriákból - a következő kategóriákból
work-in-progress: Ez a funkció még nem készült el teljesen!
messages: messages:
not-researched: "&4Nincs elég ismereted ennek a megértéséhez" not-researched: "&4Nincs elég ismereted, hogy megértsd ezt"
not-enough-xp: "&4Nincs elég XP-d ennek a feloldásához" not-enough-xp: "&4Nincs elég XP-d ennek a feloldásához"
unlocked: '&7"%research%" &bfeloldva' unlocked: '&7"%research%" &bfeloldva'
only-players: "&4Ez a parancs csak a Játékosok számára szól" only-players: "&4Ezt a parancsot csak játékosok használhatják"
unknown-player: "&4Ismeretlen Játékos: &c%player%" unknown-player: "&4Ismeretlen játékos: &c%player%"
no-permission: "&4Nem rendelkezel a szükséges engedélyekkel ehhez" no-permission: "&4Ehhez nincs jogod"
usage: "&4Használat: &c%usage%" usage: "&4Használat: &c%usage%"
not-online: "&4%player% &cnincs online!" not-online: "&4%player% &cjelenleg nem elérhető!"
not-valid-item: "&4%item% &cnem megfelelő Tárgy!" not-valid-item: "&4%item% &cnem megfelelő tárgy!"
not-valid-amount: "&4%amount% &cnem megfelelő mennyiség : 0-nál nagyobbnak kell not-valid-amount: "&4%amount% &cnem megfelelő mennyiség: 0-nál nagyobbnak kell lennie!"
lennie!" given-item: '&bKaptál &a%amount% darab &7"%item%&7"&b-t'
given-item: '&bKaptál &a%amount% &7"%item%&7"&b-t'
give-item: '&bAdtál %player%-nek/nak &a%amount% &7"%item%&7"&b-t' give-item: '&bAdtál %player%-nek/nak &a%amount% &7"%item%&7"&b-t'
not-valid-research: "&4%research% &cnem érvényes Kutatás!" not-valid-research: "&4%research% &cnem érvényes Kutatás!"
give-research: '&bAdtál %player%-nek/nak &7"%research%&7" &bKutatást' give-research: '&bMegadtad %player% játékosnak a(z) &7"%research%&7" &bkutatást'
hungry: "&cTúl éhes vagy ehhez!" hungry: "&cTúl éhes vagy ehhez!"
mode-change: "&b%device% mód állítva erre: &9%mode%" disabled-in-world: "&4&lEz a tárgy tiltva van ebben a világban"
disabled-in-world: "&4&lEz a Tárgy tiltva van ebben a világban" disabled-item: "&4&lEz a tárgy le van tiltva! Egyáltalán hogyan szerezted?"
disabled-item: "&4&lEz a Tárgy le van tiltva! Egyáltalán hogyan szerezted?" no-tome-yourself: "&cNem használhatod a &4Tome of Knowledge&c-t magadon..."
no-tome-yourself: "&cNem tudod használni a &4Tome of Knowledge &c-t magadon..." multimeter: "&bTárolt energia: &3%stored% &b/ &3%capacity%"
multimeter: "&bTárolt Energia: &3%stored% &b/ &3%capacity%"
talisman: talisman:
anvil: "&a&oA Talizmánod megmentette az eszközöd a töréstől" anvil: "&a&oA talizmánod megmentette az eszközöd az eltöréstől"
miner: "&a&oA Talizmánod megduplázta a dobott tárgyakat" miner: "&a&oA talizmánod megduplázta a dobott tárgyakat"
hunter: "&a&oA Talizmánod megduplázta a dobott tárgyakat" hunter: "&a&oA talizmánod megduplázta a dobott tárgyakat"
lava: "&a&oA Talizmánod megmentett a halálos égéstől" lava: "&a&oA talizmánod megmentett a halálos égéstől"
water: "&a&oA Talizmánod megmentett a fulladástól" water: "&a&oA talizmánod megmentett a fulladástól"
angel: "&a&oA Talizmánod megmentett a zuhanási sérüléstől" angel: "&a&oA talizmánod megmentett a zuhanási sérüléstől"
fire: "&a&oA Talizmánod megmentett a halálra elégéstől" fire: "&a&oA talizmánod megmentett a halálra elégéstől"
magician: "&a&oA Talizmánod adott további Fejlesztéseket is" magician: "&a&oA talizmánod adott további fejlesztéseket is"
traveller: "&a&oA Talizmánod Gyors sebességet adott neked" traveller: "&a&oA talizmánod gyors sebességet adott neked"
warrior: "&a&oA Talizmánodtól növelte az Erőd egy kis időre" warrior: "&a&oA talizmánodtól növelte az erőd egy kis időre"
knight: "&a&oA Talizmánod adott 5 Másodpercre élet Regenerációt" knight: "&a&oA talizmánod adott 5 másodpercre Regenerációt"
whirlwind: "&a&oA Talizmánod visszavert egy Távolsági lövést" whirlwind: "&a&oA talizmánod visszavert egy lövedéket"
wizard: "&a&oA Talizmánod erősítette a Szerencse Szinjét, de néhány egyéb Fejlesztés wizard: "&a&oA talizmánod erősítette a Szerencse enchantot, de néhány egyéb enchantot
Szint kicsit gyengül" gyengített"
caveman: "&a&oA talizmánod adott Sietség effektet"
soulbound-rune: soulbound-rune:
fail: "&cEgyszerre csak egy tárgyat köthetsz a lelkedhez." fail: "&cEgyszerre csak egy tárgyat köthetsz a lelkedhez."
success: "&aSikeresen hozzákötötted ezt a tárgyat a lelkedhez! Megmarad, amikor success: "&aSikeresen hozzákötötted ezt a tárgyat a lelkedhez! Megmarad, amikor
@ -129,65 +147,73 @@ messages:
vagy viselj Hazmat Suit-ot!" vagy viselj Hazmat Suit-ot!"
opening-guide: "&bÚtmutató megnyitása, ez eltarthat pár másodpercig..." opening-guide: "&bÚtmutató megnyitása, ez eltarthat pár másodpercig..."
opening-backpack: "&bHátizsák megnyitása, ez eltarthat pár másodpercig..." opening-backpack: "&bHátizsák megnyitása, ez eltarthat pár másodpercig..."
no-iron-golem-heal: "&cEz nem egy Vasrúd. Ezt nem használhatod a Vasgólem gyógyítására!" no-iron-golem-heal: "&cEz nem egy vasrúd. Ezt nem használhatod a vasgólem gyógyítására!"
link-prompt: "&eKattints ide:" link-prompt: "&eKattints ide:"
diet-cookie: "&eNagyon könnyednek érzed magad..." diet-cookie: "&eNagyon könnyednek érzed magad..."
fortune-cookie: fortune-cookie:
- "&7Segítség, csapdába estem egy Szerencsesüti Gyárban!" - "&7Segítség, csapdába estem egy szerencsesüti gyárban!"
- "&7Holnap meghalsz... egy Creeper által" - "&7Holnap meghalsz... egy Creeper által"
- "&7Valamikor az életedben valami rossz fog történni!!!" - "&7Valamikor az életedben valami rossz fog történni!!!"
- "&7A következő héten észreveszed, hogy ez nem az igazi világ, hanem egy számítógépes - "&7A következő héten észreveszed, hogy ez nem az igazi világ, hanem egy számítógépes
játékban vagy" játékban vagy"
- "&7Ez a süti néhány másodperc alatt jó ízű lesz" - "&7Ez a süti néhány másodperc múlva jó ízű lesz"
- '&7Az utolsó szó, amelyet hallani fogsz, "KIÍRTANI!!!"' - '&7Az utolsó szó, amelyet hallani fogsz: "KIÍRTANI!!!"'
- "&7Bármit is teszel, ne ölelj meg egy Creepert... Kipróbáltam. Jó érzés, de nem - "&7Bármit is teszel, ne ölelj meg egy Creepert... Kipróbáltam. Jó érzés, de nem
éri meg." éri meg."
- "&742. A válasz 42." - "&742. A válasz 42."
- "&7Walshy egy nap távol tartja a bajokat." - "&7Walshy egy nap távol tartja a bajokat."
- "&7Soha ne áss egyenesen!" - "&7Soha ne áss egyenesen!"
- "&7Ez csak egy friss sebesülés!" - "&7Ez csak egy kis karcolás!"
- "&7Mindig nézd az élet jó oldalát!" - "&7Mindig nézd az élet jó oldalát!"
- "&7Ez valójában Keksz volt, és nem Süti" - "&7Ez valójában keksz volt, és nem süti"
- "&7A neon táblák VILÁGÍTANAK!" - "&7A neon táblák VILÁGÍTANAK!"
piglin-barter: "&4Slimefun tárgyakat nem cserélhetsz el a Piglinekkel." piglin-barter: "&4Slimefun tárgyakat nem cserélhetsz el piglinekkel."
enchantment-rune: enchantment-rune:
fail: "&cNem varázsolhatod el ezt a tárgyat." fail: "&cNem enchantolhatod ezt a tárgyat."
no-enchantment: "&cNem található megfelelő varázslat ehhez az tárgyhoz." no-enchantment: "&cNem található megfelelő enchant ehhez az tárgyhoz."
success: "&aSikeresen alkalmaztál egy véletlenszerű varázslatot erre a tárgyra." success: "&aSikeresen alkalmaztál egy véletlenszerű enchantot erre a tárgyra."
tape-measure: tape-measure:
no-anchor: "&cBe kell állítanod egy rögzítést, mielőtt megkezdenéd a mérést!" no-anchor: "&cBe kell állítanod egy kezdőpontot, mielőtt megkezdenéd a mérést!"
wrong-world: "&cA rögzítés úgy tűnik egy másik világban van!" wrong-world: "&cA kezdőpont úgy tűnik, hogy egy másik világban van!"
distance: "&7A mérés megtörtént. &eA távolság: %distance%" distance: "&7A mérés megtörtént. &eA távolság: %distance%"
anchor-set: "&aA rögzítés sikeresen beállítva:&e %anchor%" anchor-set: "&aA kezdőpont sikeresen beállítva:&e %anchor%"
multi-tool:
mode-change: "&b%device% mód átállítva: &9%mode%"
not-shears: "&cA Multi Tool nem használható óllóként!"
climbing-pick:
dual-wielding: "&4Mindkét kezedben Climbing Pick-et kell tartanod, hogy használhasd
őket!"
wrong-material: "&cEzt a felületet nem mászhatod meg. Nyisd meg a Slimefun Útmutatót
további információért!"
mode-change: "&b%device% mód állítva erre: &9%mode%"
machines: machines:
pattern-not-found: "&eSajnálom, nem ismerem fel ezt a Receptet. Kérlek, helyezd pattern-not-found: "&eSajnálom, nem ismerem fel ezt a receptet. Kérlek, helyezd
a Tárgyakat a megfelelő mintában az Adagolóba." a tárgyakat a megfelelő mintában az adagolóba."
unknown-material: "&eSajnálom, Nem tudtam felismerni a Tárgyat az adagolóban. Kérlek unknown-material: "&eSajnálom, nem tudtam felismerni a tárgyat az adagolóban. Kérlek
tegyél bele valamit, amit ismerek." tegyél bele valamit, amit ismerek."
wrong-item: "&eSajnálom, nem ismerem fel azt a Tárgyat, amire kattintottál velem. wrong-item: "&eSajnálom, nem ismerem fel azt a tárgyat, amire velem kattintottál.
Ellenőrizd a Recepteket, és nézd meg, mely Tárgyakat használhatod." Ellenőrizd a recepteket, és nézd meg, mely tárgyakat használhatod."
full-inventory: "&eSajnálom, tele a tárolóm!" full-inventory: "&eSajnálom, tele az eszköztáram!"
in-use: "&cEnnek a Blokknak a tárolóját éppen megnyitotta egy másik Játékos." in-use: "&cEnnek a blokknak az eszköztárát éppen megnyitotta egy másik játékos."
ignition-chamber-no-flint: "&cA Gyújtókamrából hiányzik a Kovakő és Acél." ignition-chamber-no-flint: "&cAz Ignition Chamber-ből hiányzik a kovakő és acél."
ANCIENT_ALTAR: ANCIENT_ALTAR:
not-enough-pedestals: "&4Az Oltár körül nincs elég Talapzat, ami szükséges a működéséhez not-enough-pedestals: "&4Az Altar körül nincs elég Pedestal, ami szükséges a működéséhez
&c(%pedestals% / 8)" &c(%pedestals% / 8)"
unknown-catalyst: "&4Ismeretlen Katalizátor! &cEhelyett használd a helyes Receptet!" unknown-catalyst: "&4Ismeretlen katalizátor! &cEhelyett használd a helyes receptet!"
unknown-recipe: "&4Ismeretlen Recept! &cEhelyett használd a helyes Receptet!" unknown-recipe: "&4Ismeretlen recept! &cEhelyett használd a helyes receptet!"
ANCIENT_PEDESTAL: ANCIENT_PEDESTAL:
obstructed: "&4A Talapzat el van torlaszolva! &cTávolíts el mindent, ami a talapzat obstructed: "&4A Pedestal el van torlaszolva! &cTávolíts el mindent, ami a Pedestal
felett van!" felett van!"
HOLOGRAM_PROJECTOR: HOLOGRAM_PROJECTOR:
enter-text: "&7Kérlek, írd be a kívánt Hologram Szöveget a Chatbe. &r(A színkódok enter-text: "&7Kérlek, írd be a kívánt hologram szöveget a chatre. &r(Színkódok
is használhatóak!)" is használhatóak!)"
inventory-title: Hologram Szerkesztő inventory-title: Hologram szerkesztő
ELEVATOR: ELEVATOR:
no-destinations: "&4Nem található úticél" no-destinations: "&4Nem található úticél"
pick-a-floor: "&3- Válassz emeletet -" pick-a-floor: "&3- Válassz emeletet -"
current-floor: "&eEz az emelet, amelyen jelenleg tartózkodik:" current-floor: "&eEzen az emeleten tartózkodsz:"
click-to-teleport: "&eKattints &7erre az emeletre való teleportáláshoz:" click-to-teleport: "&eKattints&7, hogy erre az emeletre teleportálj:"
enter-name: "&7Kérlek írd be a kívánt emelet nevet a Chatbe. &r(A Színkódok is enter-name: "&7Kérlek írd be a kívánt emelet nevét a chatre. &r(Színkódok is használhatóak!)"
támogatottak!)"
named: "&2Sikeresen elnevezted ezt az emeletet: &r%floor%" named: "&2Sikeresen elnevezted ezt az emeletet: &r%floor%"
TELEPORTER: TELEPORTER:
teleporting: "&3Teleportálás..." teleporting: "&3Teleportálás..."
@ -196,79 +222,81 @@ machines:
invulnerability: "&b&l30 másodperc Sérthetetlenséget kaptál!" invulnerability: "&b&l30 másodperc Sérthetetlenséget kaptál!"
gui: gui:
title: Az útpontjaid title: Az útpontjaid
tooltip: Klikk a teleportáláshoz tooltip: Kattints a teleportáláshoz
time: Becsült idő time: Becsült idő
CARGO_NODES: CARGO_NODES:
must-be-placed: "&4Ládára vagy gépre kell helyezni!" must-be-placed: "&4Ládára vagy gépre kell helyezni!"
GPS_CONTROL_PANEL: GPS_CONTROL_PANEL:
title: GPS - Vezérlőpult title: GPS - Vezérlőpult
transmitters: Transzmitter Áttekintése transmitters: Transzmitter áttekintése
waypoints: Útpont Áttekintése waypoints: Útpont áttekintése
INDUSTRIAL_MINER: INDUSTRIAL_MINER:
no-fuel: "&cAz Ipari Bányászodnak elfogyott az üzemanyaga! Tedd az üzemanyagot no-fuel: "&cAz Industrial Miner-ednek elfogyott az üzemanyaga! Tedd az üzemanyagot
a fenti ládába." a felette lévő ládába."
piston-facing: "&cAz Ipari Bányászodhoz szükségesek dugattyúk, amik felfelé néznek!" piston-facing: "&cAz Industrial Miner-edhez szükségesek dugattyúk, amik felfelé
néznek!"
piston-space: "&cA két dugattyú felett egy üres blokknak kell lennie!" piston-space: "&cA két dugattyú felett egy üres blokknak kell lennie!"
destroyed: "&cÚgy tűnik, hogy az Ipari Bányászod megsemmisült." destroyed: "&cÚgy tűnik, hogy az Industrial Miner-ed megsemmisült."
already-running: "&cEz az Ipari Bányász már fut!" already-running: "&cEz az Industrial Miner már fut!"
full-chest: "&cAz Ipari Bányász ládája tele van!" full-chest: "&cAz Industrial Miner ládája tele van!"
no-permission: "&4Úgy tűnik, hogy nincs engedélyed az Ipari Bányász üzemeltetésére no-permission: "&4Úgy tűnik, hogy nincs engedélyed Industrial Miner üzemeltetésére
itt!" itt!"
finished: Az Ipari Bányászod kész! Összesen %ores% ércet szerzett! finished: Az Industrial Miner-ed kész! Összesen %ores% ércet szerzett!
anvil: anvil:
not-working: "&4Nem használhatsz Slimefun tárgyakat az Üllőben!" not-working: "&4Nem használhatsz Slimefun tárgyakat az üllőben!"
backpack: backpack:
already-open: "&cSajnáljuk, ez a Hátizsák valahol máshol már nyitva van!" already-open: "&cSajnáljuk, ez a hátizsák valahol máshol már nyitva van!"
no-stack: "&cNem lehet halmozni a Táskákat" no-stack: "&cNem halmozhatsz hátizsákokat"
workbench: workbench:
not-enhanced: "&4Nem használhatsz Slimefun Tárgyakat normális barkácsasztalban" not-enhanced: "&4Nem használhatsz Slimefun tárgyakat barkácsasztalban"
gps: gps:
deathpoint: "&4Halálpont &7%date%" deathpoint: "&4Halálpont: &7%date%"
waypoint: waypoint:
new: "&eKérlek, add meg az új útpontot chatben. &7(A Színkódok használhatóak!)" new: "&eKérlek írd be az új útpont nevét chatre. &7(Színkódok használhatóak!)"
added: "&aSikeresen megadtad az útpontot" added: "&aSikeresen létrehoztál egy útpontot"
max: "&4Elérted a maximális útpontok számát" max: "&4Elérted a maximális útpontok számát"
duplicate: "&4Már létrehoztál egy ilyen nevű útpontot: &f%waypoint%"
insufficient-complexity: insufficient-complexity:
- "&4Nem megfelelő a GPS Hálózat Komplexitása: &c%complexity%" - "&4Nem megfelelő a GPS-hálózat komplexitása: &c%complexity%"
- "&4a) Még nem telepítetted a GPS Hálózatot" - "&4a) Még nem telepítetted a GPS-hálózatot"
- "&4b) A GPS Hálózatod nem eléggé összetett" - "&4b) A GPS-hálózatod nem eléggé összetett"
geo: geo:
scan-required: "&4GEO-Vizsgálat szükséges! &cElőbb vizsgáld meg ezt a chunkot scan-required: "&4GEO-vizsgálat szükséges! &cElőbb vizsgáld meg ezt a chunkot
a GEO-Szkennerrel!" a GEO-Scannerrel!"
inventory: inventory:
no-access: "&4Nincs hozzáférésed ehhez a blokkhoz" no-access: "&4Nincs hozzáférésed ehhez a blokkhoz"
android: android:
started: "&7Az Androidod folytatja a szkript futtatását" started: "&7Az androidod folytatja a szkript futtatását"
stopped: "&7Az Androidod szünetelteti a szkript futtatását" stopped: "&7Az androidod szünetelteti a szkript futtatását"
scripts: scripts:
already-uploaded: "&4Ezt a szkriptet már feltöltötték." already-uploaded: "&4Ezt a szkriptet már feltöltötték."
instructions: instructions:
START: "&2Szkript indítása" START: "&2Szkript indítása"
REPEAT: "&9Szkript ismétlése" REPEAT: "&9Szkript ismétlése"
WAIT: "&eVárjon 0.5s" WAIT: "&eVárj 5sodpercet"
GO_FORWARD: "&7Menj előre" GO_FORWARD: "&7Menj előre"
GO_UP: "&7Menj felfelé" GO_UP: "&7Menj felfelé"
GO_DOWN: "&7Menj lefelé" GO_DOWN: "&7Menj lefelé"
TURN_LEFT: "&7Fordulj balra" TURN_LEFT: "&7Fordulj balra"
TURN_RIGHT: "&7Fordulj jobbra" TURN_RIGHT: "&7Fordulj jobbra"
DIG_UP: "&bÁss" DIG_UP: "&bÁss felfelé"
DIG_FORWARD: "&bÁss előre" DIG_FORWARD: "&bÁss előre"
DIG_DOWN: "&bÁss le" DIG_DOWN: "&bÁss lefelé"
MOVE_AND_DIG_UP: "&bMenj és Áss felfelé" MOVE_AND_DIG_UP: "&bMenj és áss felfelé"
MOVE_AND_DIG_FORWARD: "&bMenj és Áss előre" MOVE_AND_DIG_FORWARD: "&bMenj és áss előre"
MOVE_AND_DIG_DOWN: "&bMenj és Áss lefelé" MOVE_AND_DIG_DOWN: "&bMenj és áss lefelé"
ATTACK_MOBS_ANIMALS: "&4Támadj &c(Ellenséges Élőlények és Állatok)" ATTACK_MOBS_ANIMALS: "&4Támadj &c(ellenséges élőlényeket és állatokat)"
ATTACK_MOBS: "&4Támadj &c(Ellenséges Élőlények)" ATTACK_MOBS: "&4Támadj &c(ellenséges élőlényeket)"
ATTACK_ANIMALS: "&4Támadj &c(Állatok)" ATTACK_ANIMALS: "&4Támadj &c(állatokat)"
ATTACK_ANIMALS_ADULT: "&4Támadj &c(Állatok &7[Felnőtt]&c)" ATTACK_ANIMALS_ADULT: "&4Támadj &c(&7felnőtt &cállatokat)"
CHOP_TREE: "&cVágj és Ültess" CHOP_TREE: "&cVágj fát és ültess"
CATCH_FISH: "&bFogj Halat" CATCH_FISH: "&bFogj halat"
FARM_FORWARD: "&bSzüretelj és Ültess" FARM_FORWARD: "&bSzüretelj és ültess"
FARM_DOWN: "&bSzüretelj és Ültess &7(Blokk alatt)" FARM_DOWN: "&bSzüreteljen és ültessen &7(saját maga alatt)"
FARM_EXOTIC_FORWARD: "&bFejlett Szüretelés és Ültetés" FARM_EXOTIC_FORWARD: "&bFejlett szüretelés és ültetés"
FARM_EXOTIC_DOWN: "&bFejlett Szüretelés és Ültetés &7(Blokk alatt)" FARM_EXOTIC_DOWN: "&bFejlett szüretelés és ültetés &7(saját maga alatt)"
INTERFACE_ITEMS: "&9Tegye az Eszköztár Tartalmát a csatlakozási Felületbe" INTERFACE_ITEMS: "&9Tegye az eszköztár tartalmát a csatlakozási felületbe"
INTERFACE_FUEL: "&cVegyen ki az Üzemanyagot a csatlakozási Felületről" INTERFACE_FUEL: "&cVegyen ki az üzemanyagot a csatlakozási felületről"
enter-name: enter-name:
- -
- "&eKérlek, írd be a szkript nevét" - "&eKérlek, írd be a szkript nevét"
@ -280,7 +308,7 @@ android:
already: "&4Ezt a szkriptet már értékelted!" already: "&4Ezt a szkriptet már értékelted!"
editor: Szkript Szerkesztő editor: Szkript Szerkesztő
languages: languages:
default: Szerver-Alapértelmezett default: Szerver-alapértelmezett
en: Angol en: Angol
de: Német de: Német
fr: Francia fr: Francia
@ -300,8 +328,9 @@ languages:
zh-CN: Kínai (Kína) zh-CN: Kínai (Kína)
el: Görög el: Görög
he: Héber he: Héber
pt-BR: Portugál (Brazília)
ar: Arab ar: Arab
af: Afrikánsz af: Afrikaans
da: Dán da: Dán
fi: Finn fi: Finn
uk: Ukrán uk: Ukrán
@ -312,16 +341,19 @@ languages:
th: Thai th: Thai
ro: Román ro: Román
pt: Portugál (Portugália) pt: Portugál (Portugália)
pt-BR: Portugál (Brazília)
bg: Bolgár bg: Bolgár
ko: Koreai ko: Koreai
tr: Török tr: Török
hr: Horvát hr: Horvát
mk: Macedóniai mk: Macedón
sr: Szerb sr: Szerb
be: Belorusz be: Belarusz
tl: Tagalog tl: Tagalog
brewing_stand: brewing_stand:
not-working: "&4Nem használhatsz Slimefun tárgyakat a Főzőállványban!" not-working: "&4Nem használhatsz Slimefun tárgyakat főzőállványban!"
villagers:
no-trading: "&4Nem cserélhetsz Slimefun tárgyakat falusiakkal!"
cartography_table:
not-working: "&4Nem használhatsz Slimefun tárgyakat térképasztalban."
miner: miner:
no-ores: "&eSajnálom, nem találtam semmilyen Ércet a közelben!" no-ores: "&eSajnálom, nem találtam semmilyen ércet a közelben!"

View File

@ -20,6 +20,10 @@ commands:
player-never-joined: "&4その名前のプレイヤーが見つかりません" player-never-joined: "&4その名前のプレイヤーが見つかりません"
backpack-does-not-exist: "&4指定したバックパックは存在しません" backpack-does-not-exist: "&4指定したバックパックは存在しません"
restored-backpack-given: "&aバックパックが返還されました" restored-backpack-given: "&aバックパックが返還されました"
charge:
description: 手に持っているアイテムを充電
charge-success: アイテムは充電されました!
not-rechargeable: このアイテムは充電できません!
guide: guide:
search: search:
message: "&b検索ワードをチャットで入力してください" message: "&b検索ワードをチャットで入力してください"
@ -127,6 +131,7 @@ messages:
knight: "&a&oタリスマンが再生効果を付与した" knight: "&a&oタリスマンが再生効果を付与した"
whirlwind: "&a&oタリスマンが飛び道具から身を護った" whirlwind: "&a&oタリスマンが飛び道具から身を護った"
wizard: "&a&oタリスマンが高レベルの幸運を付与したが、他のエンチャントレベルは下がってしまった" wizard: "&a&oタリスマンが高レベルの幸運を付与したが、他のエンチャントレベルは下がってしまった"
caveman: "&a&oタリスマンが採掘速度を上昇させた"
soulbound-rune: soulbound-rune:
fail: "&c一度に複数アイテムとのバインディングはできません" fail: "&c一度に複数アイテムとのバインディングはできません"
success: "&aアイテムとのバインディングが確立したリスポーン時に当該アイテムは手繰り寄せられます" success: "&aアイテムとのバインディングが確立したリスポーン時に当該アイテムは手繰り寄せられます"
@ -307,6 +312,7 @@ languages:
el: ギリシャ語 el: ギリシャ語
he: ヘブライ語 he: ヘブライ語
pt: ポルトガル語(ポルトガル) pt: ポルトガル語(ポルトガル)
pt-BR: ポルトガル語(ブラジル)
ar: アラビア語 ar: アラビア語
af: アフリカーンス語 af: アフリカーンス語
da: デンマーク語 da: デンマーク語
@ -318,7 +324,6 @@ languages:
fa: ペルシア語 fa: ペルシア語
th: タイ語 th: タイ語
ro: ルーマニア語 ro: ルーマニア語
pt-BR: ポルトガル語(ブラジル)
bg: ブルガリア語 bg: ブルガリア語
ko: 韓国語 ko: 韓国語
tr: トルコ語 tr: トルコ語
@ -331,5 +336,7 @@ brewing_stand:
not-working: "&4Slimefunアイテムは醸造台で使えません" not-working: "&4Slimefunアイテムは醸造台で使えません"
villagers: villagers:
no-trading: "&4Slimefunアイテムは村人との取引に使用できません" no-trading: "&4Slimefunアイテムは村人との取引に使用できません"
cartography_table:
not-working: "&4Slimefunアイテムは製図台を使用できません"
miner: miner:
no-ores: "&e周辺には鉱石が見つかりませんでした" no-ores: "&e周辺には鉱石が見つかりませんでした"

View File

@ -22,6 +22,10 @@ commands:
player-never-joined: "&4Bu adda bir oyuncu bulunamadı!" player-never-joined: "&4Bu adda bir oyuncu bulunamadı!"
backpack-does-not-exist: "&4Böyle bir sırt çantası yok." backpack-does-not-exist: "&4Böyle bir sırt çantası yok."
restored-backpack-given: "&aSırt çantanız bulundu ve envanterinize teslim edildi!" restored-backpack-given: "&aSırt çantanız bulundu ve envanterinize teslim edildi!"
charge:
description: Elinizdeki eşyayı şarj eder
charge-success: Eşyanız şarz edildi!
not-rechargeable: Bu eşya şarz edilemez!
guide: guide:
search: search:
message: "&bNe aramak istersiniz?" message: "&bNe aramak istersiniz?"
@ -130,6 +134,7 @@ messages:
whirlwind: "&a&oTılsımın Mermiyi yansıttı" whirlwind: "&a&oTılsımın Mermiyi yansıttı"
wizard: "&a&oTılsımın sana daha yüksek seviye Servet verdi ama başka bir Büyünün wizard: "&a&oTılsımın sana daha yüksek seviye Servet verdi ama başka bir Büyünün
seviyesini düşürmüş olabilir." seviyesini düşürmüş olabilir."
caveman: "&a&oTılsımın sana acele efekti verdi"
soulbound-rune: soulbound-rune:
fail: "&cBir seferde sadece bir eşyayı ruhuna bağlayabilirsin." fail: "&cBir seferde sadece bir eşyayı ruhuna bağlayabilirsin."
success: "&aBu eşyayı ruhuna başarıyla bağladın! Öldüğünde saklayacaksın." success: "&aBu eşyayı ruhuna başarıyla bağladın! Öldüğünde saklayacaksın."
@ -346,5 +351,7 @@ brewing_stand:
not-working: "&4Slimefun eşyalarını simya standında kullanamazsın!" not-working: "&4Slimefun eşyalarını simya standında kullanamazsın!"
villagers: villagers:
no-trading: "&4Köylülerle Slimefun eşyalarını kullanarak ticaret yapamazsın!" no-trading: "&4Köylülerle Slimefun eşyalarını kullanarak ticaret yapamazsın!"
cartography_table:
not-working: "&4Slimefun eşyalarını bir haritacılık masasında kullanamazsın!"
miner: miner:
no-ores: "&eÜzgünüm, yakınlarda herhangi bir cevher bulamadım!" no-ores: "&eÜzgünüm, yakınlarda herhangi bir cevher bulamadım!"

View File

@ -8,33 +8,33 @@ slimefun:
enhanced_crafting_table: enhanced_crafting_table:
name: Enhanced Crafting Table name: Enhanced Crafting Table
lore: lore:
- Készítsd el ezt a Tárgyat az ábra alapján - Készítsd el ezt a tárgyat az ábra alapján
- egy Enhanced Crafting Table-ben. - egy Enhanced Crafting Table-ben.
- A normális Barkácsasztal nem lesz elegendő! - A sima barkácsasztal nem lesz elegendő!
armor_forge: armor_forge:
name: Armor Forge name: Armor Forge
lore: lore:
- Készítsd el ezt a Tárgyat az ábra alapján - Készítsd el ezt a tárgyat az ábra alapján
- egy Armor Forge segítségével - egy Armor Forge segítségével
grind_stone: grind_stone:
name: Grind Stone name: Grind Stone
lore: lore:
- Készítsd el ezt a Tárgyat az ábra alapján - Készítsd el ezt a tárgyat az ábra alapján
- egy Grind Stone segítségével - egy Grind Stone segítségével
smeltery: smeltery:
name: Smeltery name: Smeltery
lore: lore:
- Készítsd el ezt a Tárgyat az ábra alapján - Készítsd el ezt a tárgyat az ábra alapján
- egy Smeltery segítségével - egy Smeltery segítségével
ore_crusher: ore_crusher:
name: Ore Crusher name: Ore Crusher
lore: lore:
- Készítsd el ezt a Tárgyat az ábra alapján - Készítsd el ezt a tárgyat az ábra alapján
- egy Ore Crusher segítségével - egy Ore Crusher segítségével
mob_drop: mob_drop:
name: Élőlény Dobja name: Élőlény dobja
lore: lore:
- Öld meg ezt az Élőlényt, - Öld meg ezt az élőlényt,
- hogy megszerezd ezt a tárgyat - hogy megszerezd ezt a tárgyat
gold_pan: gold_pan:
name: Gold Pan name: Gold Pan
@ -44,125 +44,125 @@ slimefun:
compressor: compressor:
name: Compressor name: Compressor
lore: lore:
- Készítsd el ezt a Tárgyat az ábra alapján - Készítsd el ezt a tárgyat az ábra alapján
- egy Compressor segítségével - egy Compressor segítségével
pressure_chamber: pressure_chamber:
name: Pressure Chamber name: Pressure Chamber
lore: lore:
- Készítsd el ezt a Tárgyat az ábra alapján - Készítsd el ezt a tárgyat az ábra alapján
- egy Pressure Chamber segítségével - egy Pressure Chamber segítségével
ore_washer: ore_washer:
name: Ore Washer name: Ore Washer
lore: lore:
- Készítsd el ezt a Tárgyat az ábra alapján - Készítsd el ezt a tárgyat az ábra alapján
- egy Ore Washer segítségével - egy Ore Washer segítségével
juicer: juicer:
name: Juicer name: Juicer
lore: lore:
- Készítsd el ezt a Gyümölcslevet az ábra alapján - Készítsd el ezt a gyümölcslevet az ábra alapján
- egy Juicer segítségével - egy Juicer segítségével
magic_workbench: magic_workbench:
name: Magic Workbench name: Magic Workbench
lore: lore:
- Készítsd el ezt a Tárgyat az ábra alapján - Készítsd el ezt a tárgyat az ábra alapján
- egy Magic Workbench segítségével - egy Magic Workbench segítségével
ancient_altar: ancient_altar:
name: Ancient Altar name: Ancient Altar
lore: lore:
- Készítsd el ezt a Tárgyat az ábra alapján - Készítsd el ezt a tárgyat az ábra alapján
- egy Ancient Altar segítségével. - egy Ancient Altar segítségével.
- Keress utána az Ancient Altar-nak a további információkért - Keress utána az Ancient Altar-nak a további információkért
heated_pressure_chamber: heated_pressure_chamber:
name: Heated Pressure Chamber name: Heated Pressure Chamber
lore: lore:
- Készítsd el ezt a Tárgyat az ábra alapján - Készítsd el ezt a tárgyat az ábra alapján
- egy Heated Pressure Chamber segítségével - egy Heated Pressure Chamber segítségével
food_fabricator: food_fabricator:
name: Food Fabricator name: Food Fabricator
lore: lore:
- Készítsd el ezt a Tárgyat az ábra alapján - Készítsd el ezt a tárgyat az ábra alapján
- egy Food Fabricator segítségével - egy Food Fabricator segítségével
food_composter: food_composter:
name: Food Composter name: Food Composter
lore: lore:
- Készítsd el ezt a Tárgyat az ábra alapján - Készítsd el ezt a tárgyat az ábra alapján
- egy Food Composter segítségével - egy Food Composter segítségével.
freezer: freezer:
name: Freezer name: Freezer
lore: lore:
- Készítsd el ezt a Tárgyat az ábra alapján - Készítsd el ezt a tárgyat az ábra alapján
- egy Freezer segítségével - egy Freezer segítségével.
geo_miner: geo_miner:
name: GEO Miner name: GEO Miner
lore: lore:
- Ez a tárgy összegyűjthető - Ez a tárgy összegyűjthető
- egy GEO Miner segítségével - egy GEO Miner segítségével.
nuclear_reactor: nuclear_reactor:
name: Nuclear Reactor name: Nuclear Reactor
lore: lore:
- Ez a tárgy mellékterméke - Ez a tárgy mellékterméke
- a Nuclear Reactor működésének - a Nuclear Reactor működésének.
oil_pump: oil_pump:
name: Oil Pump name: Oil Pump
lore: lore:
- Ez a tárgy összegyűjthető - Ez a tárgy összegyűjthető
- egy Oil Pump segítségével - egy Oil Pump segítségével.
pickaxe_of_containment: pickaxe_of_containment:
name: Pickaxe of Containment name: Pickaxe of Containment
lore: lore:
- Ez a blokk megszerezhető - Ez a blokk megszerezhető úgy,
- úgy, hogy egy Spawner-t kibányászol - hogy egy spawnert kibányászol
- a Pickaxe of Containment-tel - a Pickaxe of Containment-tel.
refinery: refinery:
name: Refinery name: Refinery
lore: lore:
- Készítsd el ezt a Tárgyat az ábra alapján - Készítsd el ezt a tárgyat az ábra alapján
- egy Refinery segítségével - egy Refinery segítségével.
barter_drop: barter_drop:
name: Piglinek Dobják Cserélésnél name: Piglinek dobják cserélésnél
lore: lore:
- Cseréld el a Piglenekkel Aranyrudakat, - Cserélj el piglenekkel aranyrudakat,
- hogy megszerezd ezt a tárgyat - hogy megszerezd ezt a tárgyat.
minecraft: minecraft:
shaped: shaped:
name: Barkácsrecept Forma name: Barkácsrecept forma
lore: lore:
- Készítsd el ezt a Tárgyat az ábra alapján - Készítsd el ezt a tárgyat az ábra alapján
- egy Normális Barkácsasztal segítségével. - egy sima barkácsasztal segítségével.
- A forma fontos. - A forma fontos.
shapeless: shapeless:
name: Forma Nélküli Barkácsrecept name: Forma nélküli barkácsrecept
lore: lore:
- Készítsd el ezt a Tárgyat az ábra alapján - Készítsd el ezt a tárgyat az ábra alapján
- egy Normális Barkácsasztal segítségével. - egy sima barkácsasztal segítségével.
- Ez a Recept forma nélküli. - Ez a recept forma nélküli.
furnace: furnace:
name: Kemence Recept name: Kemence recept
lore: lore:
- Olvaszd meg ezt a tárgyat egy Kemencében, - Olvaszd meg ezt a tárgyat egy kemencében,
- hogy elkészítsd a kívánt tárgyat - hogy elkészítsd a kívánt tárgyat.
blasting: blasting:
name: Kohó Recept name: Kohó recept
lore: lore:
- Olvaszd meg ezt a tárgyat egy Kohóban, - Olvaszd meg ezt a tárgyat egy kohóban,
- hogy elkészítsd a kívánt tárgyat - hogy elkészítsd a kívánt tárgyat.
smoking: smoking:
name: Füstölő Recept name: Füstölő recept
lore: lore:
- Olvaszd meg ezt a tárgyat egy Füstölőben, - Olvaszd meg ezt a tárgyat egy füstölőben,
- hogy elkészítsd a kívánt tárgyat - hogy elkészítsd a kívánt tárgyat.
campfire: campfire:
name: Tábortűz Recept name: Tábortűz recept
lore: lore:
- Olvaszd meg ezt a tárgyat egy Tábortűzön, - Olvaszd meg ezt a tárgyat tábortűzön,
- hogy elkészítsd a kívánt tárgyat - hogy elkészítsd a kívánt tárgyat.
stonecutting: stonecutting:
name: Kővágó Recept name: Kővágó recept
lore: lore:
- Készítsd el ezt a Tárgyat az ábra alapján - Készítsd el ezt a tárgyat az ábra alapján
- egy Kővágó segítségével - egy kővágó segítségével.
smithing: smithing:
name: Kovácsasztal Recept name: Kovácsasztal recept
lore: lore:
- Készítsd el ezt a Tárgyat az ábra alapján - Készítsd el ezt a tárgyat az ábra alapján
- egy Kovácsasztal segítségével - egy kovácsasztal segítségével.

View File

@ -1,242 +1,248 @@
--- ---
slimefun: slimefun:
walking_sticks: Sétapálcák walking_sticks: Sétapálcák
portable_crafter: Hordozható Barkácsoló portable_crafter: Hordozható barkácsoló
fortune_cookie: Szerencsesüti fortune_cookie: Szerencsesüti
portable_dustbin: Hordozható Kuka portable_dustbin: Hordozható szemetes
meat_jerky: Pácolt Hús meat_jerky: Pácolt hús
armor_forge: Páncél Barkácsolás armor_forge: Páncél barkácsolás
glowstone_armor: Izzókő Páncél glowstone_armor: Izzókő páncél
lumps: Rögök és Varázslat lumps: Rögök és varázslat
ender_backpack: Ender Hátizsák ender_backpack: Ender hátizsák
ender_armor: Ender Páncél ender_armor: Ender páncél
magic_eye_of_ender: Varázslatos Ender Szeme magic_eye_of_ender: Varázslatos Ender szeme
magic_sugar: Varázscukor magic_sugar: Varázscukor
monster_jerky: Pácolt Szörnyhús monster_jerky: Pácolt szörnyhús
slime_armor: Nyálka Páncél slime_armor: Nyálkás páncél
sword_of_beheading: Lefejezés Kardja sword_of_beheading: Lefejezés kardja
basic_circuit_board: Alapvető Áramköri Lap basic_circuit_board: Alapvető áramköri lap
advanced_circuit_board: Fejlett Áramköri Lap advanced_circuit_board: Fejlett áramköri lap
smeltery: Kohó smeltery: Kohó
steel: Acélkor steel: Acélkor
misc_power_items: Fontos energiával kapcsolatos tárgyak misc_power_items: Fontos energiával kapcsolatos tárgyak
battery: Az első Akkumulátorod battery: Az első akkumulátorod
steel_plate: Acéllemez steel_plate: Acéllemez
steel_thruster: Acélhajtómű steel_thruster: Acélhajtómű
parachute: Ejtőernyő parachute: Ejtőernyő
grappling_hook: Vasmacska grappling_hook: Vasmacska
jetpacks: Jetpackek jetpacks: Jetpackek
multitools: Többfunkciós Eszközök multitools: Többfunkciós eszközök
solar_panel_and_helmet: Napenergia solar_panel_and_helmet: Napenergia
elemental_staff: Elemi Pálcák elemental_staff: Elemi pálcák
grind_stone: Köszörűkő grind_stone: Köszörűkő
cactus_armor: Kaktusz Ruha cactus_armor: Kaktusz ruha
gold_pan: Aranymosó gold_pan: Aranymosó
magical_book_cover: Varázslatos Könyvkötés magical_book_cover: Varázslatos könyvkötés
slimefun_metals: Új Fémek slimefun_metals: Új fémek
ore_crusher: Érc Duplázás ore_crusher: Érc duplázás
bronze: Bronzkészítés bronze: Bronzkészítés
alloys: Speciális Ötvözetek alloys: Speciális ötvözetek
compressor_and_carbon: Szénkészítés compressor_and_carbon: Szénkészítés
gilded_iron_armor: Aranyozott Vaspáncél gilded_iron_armor: Aranyozott vaspáncél
synthetic_diamond: Szintetikus Gyémántok synthetic_diamond: Szintetikus gyémántok
pressure_chamber: Nyomáskamra pressure_chamber: Nyomáskamra
synthetic_sapphire: Szintetikus Zafírok synthetic_sapphire: Szintetikus zafírok
damascus_steel: Damaszkuszi Acél damascus_steel: Damaszkuszi acél
damascus_steel_armor: Damaszkuszi Acél Páncél damascus_steel_armor: Damaszkuszi acélpáncél
reinforced_alloy: Megerősített Ötvözet reinforced_alloy: Megerősített ötvözet
carbonado: Fekete Gyémántok carbonado: Fekete gyémántok
magic_workbench: Varázslatos Barkácsasztal magic_workbench: Varázslatos barkácsasztal
wind_staff: Szél Pálca wind_staff: Szélpálca
reinforced_armor: Megerősített Páncél reinforced_armor: Megerősített páncél
ore_washer: Ércmosó ore_washer: Ércmosó
gold_carats: Tiszta Arany gold_carats: Színarany
silicon: Szilícium-völgy silicon: Szilícium-völgy
fire_staff: Tűz Pálca fire_staff: Tűzpálca
smelters_pickaxe: Olvasztó Csákány smelters_pickaxe: Olvasztó csákány
common_talisman: Gyakori Talizmán common_talisman: Gyakori talizmán
anvil_talisman: Az Üllő Talizmánja anvil_talisman: Az Üllő talizmánja
miner_talisman: A Bányász Talizmánja miner_talisman: A Bányász talizmánja
hunter_talisman: A Vadász Talizmánja hunter_talisman: A Vadász talizmánja
lava_talisman: A Láva Járó Talizmánja lava_talisman: A Lávajáró talizmánja
water_talisman: A Vízlélegzés Talizmánja water_talisman: A Vízlélegzés talizmánja
angel_talisman: Az Angyal Talizmánja angel_talisman: Az Angyal talizmánja
fire_talisman: A Tűzoltó Talizmánja fire_talisman: A Tűzoltó talizmánja
lava_crystal: Tüzes Helyzet lava_crystal: Tüzes helyzet
magician_talisman: A Bűvész Talizmánja magician_talisman: A Bűvész talizmánja
traveller_talisman: Az Utazó Talizmánja traveller_talisman: Az Utazó talizmánja
warrior_talisman: A Harcos Talizmánja warrior_talisman: A Harcos talizmánja
knight_talisman: A Lovag Talizmánja knight_talisman: A Lovag talizmánja
gilded_iron: Fényes Vas gilded_iron: Fényes vas
synthetic_emerald: Hamis Drágakő synthetic_emerald: Hamis drágakő
chainmail_armor: Lánc Páncél chainmail_armor: Láncpáncél
whirlwind_talisman: A Forgószél Talizmánja whirlwind_talisman: A Forgószél talizmánja
wizard_talisman: A Varázsló Talizmánja wizard_talisman: A Varázsló talizmánja
lumber_axe: Fadöntő Fejsze lumber_axe: Fadöntő fejsze
hazmat_suit: Vegyvédelmi Ruha hazmat_suit: Vegyvédelmi ruha
uranium: Radioaktív uranium: Radioaktív
crushed_ore: Ércek Tisztítása crushed_ore: Ércek tisztítása
redstone_alloy: Redstone Ötvözet redstone_alloy: Redstone ötvözet
carbonado_tools: Felső Szintű Gépek carbonado_tools: Magasszintű gépek
first_aid: Elsősegély first_aid: Elsősegély
gold_armor: Fényes Páncél gold_armor: Fényes páncél
night_vision_googles: Éjjellátó Szemüvegek night_vision_googles: Éjjellátó szemüvegek
pickaxe_of_containment: Csomagtartó Csákány pickaxe_of_containment: Csomagtartó csákány
hercules_pickaxe: Herkules Csákány hercules_pickaxe: Herkules csákány
table_saw: Asztali Fűrész table_saw: Asztali fűrész
slime_steel_armor: Nyálkás Acél Páncél slime_steel_armor: Nyálkás acélpáncél
blade_of_vampires: Vámpírok Pengéje blade_of_vampires: Vámpírok pengéje
water_staff: Víz Pálca water_staff: Vízpálca
24k_gold_block: Aranyváros 24k_gold_block: Aranyváros
composter: Föld Komposztáló composter: Föld komposztáló
farmer_shoes: Farmer Cipők farmer_shoes: Farmer cipők
explosive_tools: Robbanóeszközök explosive_tools: Robbanóeszközök
automated_panning_machine: Automatizált Aranymosó automated_panning_machine: Automatizált aranymosó
boots_of_the_stomper: A Taposás Cipője boots_of_the_stomper: A Taposás cipője
pickaxe_of_the_seeker: A Kutatók Csákánya pickaxe_of_the_seeker: A Kutatók csákánya
backpacks: Hátizsákok backpacks: Hátizsákok
woven_backpack: Szőtt Hátizsák woven_backpack: Szőtt hátizsák
crucible: Olvasztótégely crucible: Olvasztótégely
gilded_backpack: Aranyozott Hátizsák gilded_backpack: Aranyozott hátizsák
armored_jetpack: Páncélozott Jetpack armored_jetpack: Páncélozott jetpack
ender_talismans: Ender Talizmánok ender_talismans: Ender talizmánok
nickel_and_cobalt: Még több Érc nickel_and_cobalt: Még több érc
magnet: Mágneses Fémek magnet: Mágneses fémek
infused_magnet: Infúziós Mágnesek infused_magnet: Infúziós mágnesek
cobalt_pickaxe: Gyors Csákány cobalt_pickaxe: Gyors csákány
essence_of_afterlife: Szellemidézés essence_of_afterlife: Szellemidézés
bound_backpack: Lélekhez Kötött Tárolás bound_backpack: Lélekhez kötött tárolás
jetboots: Sugárhajtású Csizma jetboots: Sugárhajtású csizma
armored_jetboots: Páncélozott Sugárhajtású Csizmák armored_jetboots: Páncélozott sugárhajtású csizmák
seismic_axe: Szeizmikus Fejsze seismic_axe: Szeizmikus fejsze
pickaxe_of_vein_mining: 'Ér Bányász Csákány ' pickaxe_of_vein_mining: 'Ércbányász csákány '
bound_weapons: Lélekhez Kötött Fegyverek bound_weapons: Lélekhez kötött fegyverek
bound_tools: Lélélekhez Kötött Eszközök bound_tools: Lélekhez kötött eszközök
bound_armor: Lélekhez Kötött Páncél bound_armor: Lélekhez kötött páncél
juicer: Ízletes Italok juicer: Ízletes italok
repaired_spawner: Spawnerek Javítása repaired_spawner: Spawnerek javítása
enhanced_furnace: Továbbfejlesztett Kemence enhanced_furnace: Továbbfejlesztett kemence
more_enhanced_furnaces: Jobb Kemencék more_enhanced_furnaces: Jobb kemencék
high_tier_enhanced_furnaces: Magas Szintű Kemence high_tier_enhanced_furnaces: Magasszintű kemence
reinforced_furnace: Megerősített Kemence reinforced_furnace: Megerősített kemence
carbonado_furnace: Karbonádó Szélű Kemence carbonado_furnace: Karbonádó élű kemence
electric_motor: Felmelegítés electric_motor: Felmelegítés
block_placer: Blokk Lehelyező block_placer: Blokk lehelyező
scroll_of_dimensional_teleposition: Megfordítva a dolgokat scroll_of_dimensional_teleposition: Megfordítja a dolgokat
special_bows: Robin Hood special_bows: Robin Hood
tome_of_knowledge_sharing: Megosztás a barátokkal tome_of_knowledge_sharing: Megosztás barátokkal
flask_of_knowledge: XP Tároló flask_of_knowledge: XP-tároló
hardened_glass: Robbanások Ellen hardened_glass: Robbanások ellen
golden_apple_juice: Arany Főzet golden_apple_juice: Aranyfőzet
cooler: Hordozható Italok cooler: Hordozható italok
ancient_altar: Ősi Oltár ancient_altar: Ősi oltár
wither_proof_obsidian: Wither-Védett Obszidián wither_proof_obsidian: Wither-biztos obszidián
ancient_runes: Elemi Rúnák ancient_runes: Elemi rúnák
special_runes: Lila Rúnák special_runes: Lila rúnák
infernal_bonemeal: Pokoli Csontliszt infernal_bonemeal: Pokoli csontliszt
rainbow_blocks: Szivárvány Blokkok rainbow_blocks: Szivárvány blokkok
infused_hopper: Pokoli Tölcsér infused_hopper: Infúziós tölcsér
wither_proof_glass: Wither-Védett Üveg wither_proof_glass: Wither-biztos üveg
duct_tape: Szövetbetétes Ragasztószalag duct_tape: Ragasztószalag
plastic_sheet: Műanyag plastic_sheet: Műanyag
android_memory_core: Memóriamag android_memory_core: Memóriamag
oil: Olaj oil: Olaj
fuel: Üzemanyag fuel: Üzemanyag
hologram_projector: Hologramok hologram_projector: Hologramok
capacitors: 1. Szintű Kondenzátorok capacitors: 1. szintű kondenzátorok
high_tier_capacitors: 2. Szintű Kondenzátorok high_tier_capacitors: 2. szintű kondenzátorok
solar_generators: Napenergia Erőmű solar_generators: Napenergia-erőmű
electric_furnaces: Erős Kemence electric_furnaces: Elektromos kemence
electric_ore_grinding: Zúzás és Őrlés electric_ore_grinding: Zúzás és őrlés
heated_pressure_chamber: Fűtött Nyomáskamra heated_pressure_chamber: Fűtött nyomáskamra
coal_generator: Széngenerátor coal_generator: Széngenerátor
bio_reactor: Bioreaktor bio_reactor: Bioreaktor
auto_enchanting: Automatikus Fejlesztés és Fejlesztés Törlés auto_enchanting: Automatikus enchantolás és enchant levétel
auto_anvil: Automatikus Üllő auto_anvil: Automatikus üllő
multimeter: Teljesítménymérés multimeter: Teljesítménymérés
gps_setup: Alapvető GPS Beállítás gps_setup: Alapvető GPS-beállítás
gps_emergency_transmitter: GPS Vészhelyzeti Útpont gps_emergency_transmitter: Vészhelyzeti GPS-útpont
programmable_androids: Programozható Androidok programmable_androids: Programozható androidok
android_interfaces: Android Csatlakozási Felületek android_interfaces: Android csatlakozási felületek
geo_scanner: GEO-Vizsgálatok geo_scanner: GEO-vizsgálatok
combustion_reactor: Égésreaktor combustion_reactor: Égésreaktor
teleporter: Teleportáló Alapelemek teleporter: Teleportálás alapösszetevői
teleporter_activation_plates: Teleportáló Aktiválás teleporter_activation_plates: Teleportálás aktiválása
better_solar_generators: Továbbfejlesztett Napelemes Generátorok better_solar_generators: Továbbfejlesztett napelemes generátorok
better_gps_transmitters: Továbbfejlesztett Transzmitterek better_gps_transmitters: Továbbfejlesztett transzmitterek
elevator: Liftek elevator: Liftek
energized_solar_generator: Teljes-Munkaidős Napenergia energized_solar_generator: Folyamatos napenergia
energized_gps_transmitter: Legfelső Szintű Transzmitter energized_gps_transmitter: Magasszintű transzmitter
energy_regulator: Energiahálózatok 101 energy_regulator: Energiahálózatok 101
butcher_androids: Hentes Androidok butcher_androids: Hentes androidok
organic_food: Bioélelmiszerek organic_food: Bioélelmiszerek
auto_breeder: Automatizált Etetés auto_breeder: Automatizált etetés
advanced_android: Speciális Androidok advanced_android: Fejlett androidok
advanced_butcher_android: Fejlett Androidok - Hentes advanced_butcher_android: Fejlett androidok - Hentes
advanced_fisherman_android: Fejlett Androidok - Halász advanced_fisherman_android: Fejlett androidok - Halász
animal_growth_accelerator: Az állatok Növekedésének Manipulálása animal_growth_accelerator: Az állatok növekedésének manipulálása
xp_collector: XP Gyűjtő xp_collector: XP-gyűjtő
organic_fertilizer: Organikus Trágya organic_fertilizer: Organikus trágya
crop_growth_accelerator: Növény Növekedés Gyorsító crop_growth_accelerator: Növény növekedés gyorsító
better_crop_growth_accelerator: Továbbfejlesztett Növény Növekedés Gyorsító better_crop_growth_accelerator: Továbbfejlesztett növény növekedés gyorsító
reactor_essentials: Reaktor Alapjai reactor_essentials: Reaktor alapjai
nuclear_reactor: Atomerőmű nuclear_reactor: Atomerőmű
freezer: Fagyasztó Úr freezer: Fagyasztó Úr
cargo_basics: Szállítmány Alapjai cargo_basics: Szállítmánykezelés alapjai
cargo_nodes: Szállítmány Beállítása cargo_nodes: Szállítmánykezelés beállítása
electric_ingot_machines: Elektromos Öntvénygyártás electric_ingot_machines: Elektromos öntvénygyártás
high_tier_electric_ingot_machines: Szupergyors Öntvénygyártás high_tier_electric_ingot_machines: Szupergyors öntvénygyártás
automated_crafting_chamber: Automatizált Barkácsolás automated_crafting_chamber: Automatizált barkácsolás
better_food_fabricator: Továbbfejlesztett Élelmiszergyártás better_food_fabricator: Továbbfejlesztett élelmiszergyártás
reactor_access_port: Reaktor Kölcsönhatás reactor_access_port: Reaktor hozzáférés
fluid_pump: Folyadék Szivattyú fluid_pump: Folyadék szivattyú
better_freezer: Továbbfejlesztett Fagyasztó better_freezer: Továbbfejlesztett fagyasztó
boosted_uranium: Soha Véget Nem Érő Kör boosted_uranium: Soha véget nem érő kör
trash_can: Szemetes trash_can: Szemetes
advanced_output_node: Speciális Kimeneti Csomópont advanced_output_node: Speciális kimeneti csomópont
carbon_press: Szénprés carbon_press: Szénprés
electric_smeltery: Elektromos Olvasztó electric_smeltery: Elektromos olvasztó
better_electric_furnace: Továbbfejlesztett Elektromos Kemence better_electric_furnace: Továbbfejlesztett elektromos kemence
better_carbon_press: Továbbfejlesztett Szénprés better_carbon_press: Továbbfejlesztett szénprés
empowered_android: Felhatalmazott Androidok empowered_android: Fejlesztett androidok
empowered_butcher_android: Felhatalmazott Androidok - Hentes empowered_butcher_android: Fejlesztett androidok - Hentes
empowered_fisherman_android: Felhatalmazott Androidok - Halász empowered_fisherman_android: Fejlesztett androidok - Halász
high_tier_carbon_press: Végleges Szénprés high_tier_carbon_press: Legmagasabb szintű szénprés
wither_assembler: Automatizált Wither Ö wither_assembler: Automatizált wither ö
better_heated_pressure_chamber: Továbbfejlesztett Fűtött Nyomású Kamra better_heated_pressure_chamber: Továbbfejlesztett fűtött nyomáskamra
elytra: Kitinszárnyak elytra: Kitinszárnyak
special_elytras: Speciális Kitinszárnyak special_elytras: Speciális kitinszárnyak
electric_crucible: Elektromos Olvasztótégely electric_crucible: Elektromos olvasztótégely
better_electric_crucibles: Forró Olvasztótégelyek better_electric_crucibles: Forró olvasztótégelyek
advanced_electric_smeltery: Fejlett Elektromos Olvasztómű advanced_electric_smeltery: Fejlett elektromos olvasztómű
advanced_farmer_android: Fejlett Androidok - Farmer advanced_farmer_android: Fejlesztett androidok - Farmer
lava_generator: Lávagenerátor lava_generator: Lávagenerátor
nether_ice: Nether Jéghűtő nether_ice: Netherjég hűtő
nether_star_reactor: Nethercsillag Reaktor nether_star_reactor: Nethercsillag reaktor
blistering_ingots: Hólyagos Radioaktivitás blistering_ingots: Hólyagos radioaktivitás
automatic_ignition_chamber: Automatikus Gyújtókamra automatic_ignition_chamber: Automatikus gyújtókamra
output_chest: Alapvető Gépek Kimeneti Láda output_chest: Alapvető gépek kimeneti láda
copper_wire: Hígított Vezetőképesség copper_wire: Hígított vezetőképesség
radiant_backpack: Sugárzó Hátizsák radiant_backpack: Sugárzó hátizsák
auto_drier: Egy Száraz Nap auto_drier: Egy száraz nap
diet_cookie: Diétás Süti diet_cookie: Diétás süti
storm_staff: Vihar Pálca storm_staff: Viharpálca
soulbound_rune: Lélekhez Kötött Rúna soulbound_rune: Lélekhez kötött rúna
geo_miner: GEO-Bányász geo_miner: GEO-bányász
lightning_rune: Villám Rúna lightning_rune: Villám rúna
totem_of_undying: Életmentés Toteme totem_of_undying: Életmentés toteme
charging_bench: Töltőpad charging_bench: Töltőpad
nether_gold_pan: Nether Aranymosó nether_gold_pan: Nether aranymosó
electric_press: Elektromos Prés electric_press: Elektromos prés
magnesium_generator: Energia Magnéziumból magnesium_generator: Energia magnéziumból
kelp_cookie: Ízletes Moszat kelp_cookie: Ízletes hínár
makeshift_smeltery: Improvizált Olvasztó makeshift_smeltery: Improvizált olvasztó
tree_growth_accelerator: Gyorsabb Fák tree_growth_accelerator: Gyorsabb fák
industrial_miner: Ipari Bányászat industrial_miner: Ipari bányászat
advanced_industrial_miner: Jobb Bányászat advanced_industrial_miner: Jobb bányászat
magical_zombie_pills: Zombi Átváltoztató magical_zombie_pills: Zombi átváltoztató
auto_brewer: Ipari Sörgyár auto_brewer: Ipari sörgyár
enchantment_rune: Ősi Varázslat enchantment_rune: Ősi enchantolás
lead_clothing: Ólom Ruházat lead_clothing: Ólom ruházat
tape_measure: Mérőszalag tape_measure: Mérőszalag
iron_golem_assembler: Automatizált Vasgólemek iron_golem_assembler: Automatizált vasgólemek
climbing_pick: Block Raider
shulker_shell: Szintetikus shulkerek
villager_rune: Falusiak alaphelyzetbe állítása
caveman_talisman: Az Ősember talizmánja
even_higher_tier_capacitors: 3. szintű kondenzátorok
elytra_cap: Ütközésvédelem

View File

@ -243,3 +243,6 @@ slimefun:
climbing_pick: ブロッククライミング climbing_pick: ブロッククライミング
shulker_shell: 合成シュルカー shulker_shell: 合成シュルカー
villager_rune: 村人の初期化 villager_rune: 村人の初期化
caveman_talisman: 洞窟暮らしのタリスマン
even_higher_tier_capacitors: キャパシタⅢ
elytra_cap: 衝撃緩和装備

View File

@ -243,3 +243,6 @@ slimefun:
climbing_pick: Blok Raider climbing_pick: Blok Raider
shulker_shell: Sentetik Shulkerlar shulker_shell: Sentetik Shulkerlar
villager_rune: Sıfır Köylü Ticareti villager_rune: Sıfır Köylü Ticareti
caveman_talisman: Mağara Adamı Tılsımı
even_higher_tier_capacitors: Seviye 3 Kapasitörler
elytra_cap: İniş Takımı

View File

@ -1,24 +1,24 @@
--- ---
tooltips: tooltips:
results: GEO-Vizsgálat Eredmények results: GEO-vizsgálat eredmények
chunk: Vizsgált Chunk chunk: Vizsgált chunk
world: Világ world: Világ
unit: Egység unit: egység
units: Egységek units: egység
resources: resources:
slimefun: slimefun:
oil: Olaj oil: Olaj
nether_ice: Nether Jég nether_ice: Nether jég
salt: salt:
uranium: Uránium uranium: Uránium
slimefunorechunks: slimefunorechunks:
iron_ore_chunk: Vasérc Chunk iron_ore_chunk: Vasérc chunk
gold_ore_chunk: Aranyérc Chunk gold_ore_chunk: Aranyérc chunk
copper_ore_chunk: Rézérc Chunk copper_ore_chunk: Rézérc chunk
tin_ore_chunk: Ónérc Chunk tin_ore_chunk: Ónérc chunk
silver_ore_chunk: Ezüstérc Chunk silver_ore_chunk: Ezüstérc chunk
aluminum_ore_chunk: Alumínium Érc Chunk aluminum_ore_chunk: Alumíniumérc chunk
lead_ore_chunk: Ólomérc Chunk lead_ore_chunk: Ólomérc chunk
zinc_ore_chunk: Cinkérc Chunk zinc_ore_chunk: Cinkérc chunk
nickel_ore_chunk: Nikkelérc Chunk nickel_ore_chunk: Nikkelérc chunk
cobalt_ore_chunk: Kobalt Érc Chunk cobalt_ore_chunk: Kobaltérc Chunk

View File

@ -0,0 +1,25 @@
{
"values" : [
"#slimefun:sensitive_materials",
"#slimefun:mushrooms",
{
"id" : "#minecraft:tall_flowers",
"required" : false
},
{
"id" : "#minecraft:beds",
"required" : false
},
{
"id" : "#minecraft:doors",
"required" : false
},
"minecraft:sugar_cane",
"minecraft:lily_pad",
"minecraft:dead_bush",
{
"id" : "minecraft:bamboo",
"required" : false
}
]
}

View File

@ -0,0 +1,9 @@
{
"values" : [
"#slimefun:ores",
{
"id" : "minecraft:ancient_debris",
"required" : false
}
]
}

View File

@ -0,0 +1,16 @@
{
"values" : [
"#slimefun:ice_variants",
"#slimefun:terracotta",
"#slimefun:stone_variants",
"minecraft:netherrack",
{
"id" : "minecraft:blackstone",
"required" : false
},
{
"id" : "minecraft:basalt",
"required" : false
}
]
}

View File

@ -0,0 +1,6 @@
{
"values" : [
"#slimefun:climbing_pick_strong_surfaces",
"#slimefun:climbing_pick_weak_surfaces"
]
}

View File

@ -0,0 +1,7 @@
{
"values" : [
"#slimefun:concrete_powders",
"#minecraft:sand",
"minecraft:gravel"
]
}

View File

@ -0,0 +1,7 @@
{
"values" : [
"minecraft:command_block",
"minecraft:chain_command_block",
"minecraft:repeating_command_block"
]
}

View File

@ -0,0 +1,20 @@
{
"values" : [
"minecraft:white_concrete_powder",
"minecraft:orange_concrete_powder",
"minecraft:magenta_concrete_powder",
"minecraft:light_blue_concrete_powder",
"minecraft:yellow_concrete_powder",
"minecraft:lime_concrete_powder",
"minecraft:pink_concrete_powder",
"minecraft:gray_concrete_powder",
"minecraft:light_gray_concrete_powder",
"minecraft:cyan_concrete_powder",
"minecraft:purple_concrete_powder",
"minecraft:blue_concrete_powder",
"minecraft:brown_concrete_powder",
"minecraft:green_concrete_powder",
"minecraft:red_concrete_powder",
"minecraft:black_concrete_powder"
]
}

View File

@ -0,0 +1,20 @@
{
"values" : [
{
"id" : "#minecraft:crops",
"required" : false
},
"minecraft:beetroots",
"minecraft:carrots",
"minecraft:potatoes",
"minecraft:wheat",
"minecraft:melon_stem",
"minecraft:pumpkin_stem",
"minecraft:nether_wart",
"minecraft:cocoa",
{
"id" : "minecraft:sweet_berry_bush",
"required" : false
}
]
}

View File

@ -0,0 +1,18 @@
{
"values" : [
"#minecraft:sand",
"#minecraft:dirt_like",
"#slimefun:concrete_powders",
"minecraft:farmland",
"minecraft:grass_path",
"minecraft:snow",
"minecraft:snow_block",
"minecraft:gravel",
"minecraft:clay",
"minecraft:soul_sand",
{
"id" : "minecraft:soul_soil",
"required" : false
}
]
}

View File

@ -0,0 +1,7 @@
{
"values" : [
"#minecraft:saplings",
"minecraft:player_head",
"minecraft:player_wall_head"
]
}

View File

@ -0,0 +1,6 @@
{
"values" : [
"#slimefun:glass_blocks",
"#slimefun:glass_panes"
]
}

View File

@ -0,0 +1,21 @@
{
"values" : [
"minecraft:glass",
"minecraft:white_stained_glass",
"minecraft:orange_stained_glass",
"minecraft:magenta_stained_glass",
"minecraft:light_blue_stained_glass",
"minecraft:yellow_stained_glass",
"minecraft:lime_stained_glass",
"minecraft:pink_stained_glass",
"minecraft:gray_stained_glass",
"minecraft:light_gray_stained_glass",
"minecraft:cyan_stained_glass",
"minecraft:purple_stained_glass",
"minecraft:blue_stained_glass",
"minecraft:brown_stained_glass",
"minecraft:green_stained_glass",
"minecraft:red_stained_glass",
"minecraft:black_stained_glass"
]
}

View File

@ -0,0 +1,21 @@
{
"values" : [
"minecraft:glass_pane",
"minecraft:white_stained_glass_pane",
"minecraft:orange_stained_glass_pane",
"minecraft:magenta_stained_glass_pane",
"minecraft:light_blue_stained_glass_pane",
"minecraft:yellow_stained_glass_pane",
"minecraft:lime_stained_glass_pane",
"minecraft:pink_stained_glass_pane",
"minecraft:gray_stained_glass_pane",
"minecraft:light_gray_stained_glass_pane",
"minecraft:cyan_stained_glass_pane",
"minecraft:purple_stained_glass_pane",
"minecraft:blue_stained_glass_pane",
"minecraft:brown_stained_glass_pane",
"minecraft:green_stained_glass_pane",
"minecraft:red_stained_glass_pane",
"minecraft:black_stained_glass_pane"
]
}

View File

@ -0,0 +1,8 @@
{
"values" : [
"minecraft:ice",
"minecraft:packed_ice",
"minecraft:frosted_ice",
"minecraft:blue_ice"
]
}

View File

@ -0,0 +1,9 @@
{
"values" : [
"#slimefun:ores",
{
"id" : "minecraft:gilded_blackstone",
"required" : false
}
]
}

View File

@ -0,0 +1,14 @@
{
"values" : [
"minecraft:red_mushroom",
"minecraft:brown_mushroom",
{
"id" : "minecraft:crimson_fungus",
"required" : false
},
{
"id" : "minecraft:warped_fungus",
"required" : false
}
]
}

View File

@ -0,0 +1,16 @@
{
"values" : [
{
"id" : "#minecraft:gold_ores",
"required" : false
},
"minecraft:gold_ore",
"minecraft:iron_ore",
"minecraft:coal_ore",
"minecraft:lapis_ore",
"minecraft:diamond_ore",
"minecraft:redstone_ore",
"minecraft:emerald_ore",
"minecraft:nether_quartz_ore"
]
}

View File

@ -0,0 +1,9 @@
{
"values" : [
"#slimefun:ores",
{
"id" : "minecraft:ancient_debris",
"required" : false
}
]
}

View File

@ -0,0 +1,9 @@
{
"values" : [
"#slimefun:ores",
{
"id" : "minecraft:ancient_debris",
"required" : false
}
]
}

View File

@ -0,0 +1,11 @@
{
"values" : [
"#minecraft:saplings",
"#minecraft:wooden_pressure_plates",
"#slimefun:torches",
"minecraft:stone_pressure_plate",
"minecraft:light_weighted_pressure_plate",
"minecraft:heavy_weighted_pressure_plate",
"minecraft:cake"
]
}

View File

@ -0,0 +1,21 @@
{
"values" : [
"minecraft:shulker_box",
"minecraft:white_shulker_box",
"minecraft:orange_shulker_box",
"minecraft:magenta_shulker_box",
"minecraft:light_blue_shulker_box",
"minecraft:yellow_shulker_box",
"minecraft:lime_shulker_box",
"minecraft:pink_shulker_box",
"minecraft:gray_shulker_box",
"minecraft:light_gray_shulker_box",
"minecraft:cyan_shulker_box",
"minecraft:purple_shulker_box",
"minecraft:blue_shulker_box",
"minecraft:brown_shulker_box",
"minecraft:green_shulker_box",
"minecraft:red_shulker_box",
"minecraft:black_shulker_box"
]
}

View File

@ -0,0 +1,10 @@
{
"values" : [
{
"id" : "#minecraft:gold_ores",
"required" : false
},
"minecraft:gold_ore",
"minecraft:iron_ore"
]
}

View File

@ -0,0 +1,8 @@
{
"values" : [
"minecraft:stone",
"minecraft:granite",
"minecraft:andesite",
"minecraft:diorite"
]
}

View File

@ -0,0 +1,21 @@
{
"values" : [
"minecraft:terracotta",
"minecraft:white_terracotta",
"minecraft:orange_terracotta",
"minecraft:magenta_terracotta",
"minecraft:light_blue_terracotta",
"minecraft:yellow_terracotta",
"minecraft:lime_terracotta",
"minecraft:pink_terracotta",
"minecraft:gray_terracotta",
"minecraft:light_gray_terracotta",
"minecraft:cyan_terracotta",
"minecraft:purple_terracotta",
"minecraft:blue_terracotta",
"minecraft:brown_terracotta",
"minecraft:green_terracotta",
"minecraft:red_terracotta",
"minecraft:black_terracotta"
]
}

View File

@ -0,0 +1,10 @@
{
"values" : [
"minecraft:torch",
"minecraft:redstone_torch",
{
"id" : "minecraft:soul_torch",
"required" : false
}
]
}

View File

@ -0,0 +1,17 @@
{
"values" : [
"#slimefun:command_blocks",
"minecraft:bedrock",
"minecraft:barrier",
"minecraft:nether_portal",
"minecraft:end_portal",
"minecraft:end_portal_frame",
"minecraft:end_gateway",
"minecraft:structure_block",
"minecraft:structure_void",
{
"id" : "minecraft:jigsaw",
"required" : false
}
]
}

View File

@ -71,4 +71,4 @@ public final class TestUtilities {
latch.await(2, TimeUnit.SECONDS); latch.await(2, TimeUnit.SECONDS);
return ref.get(); return ref.get();
} }
} }

View File

@ -1,30 +1,43 @@
package io.github.thebusybiscuit.slimefun4.testing.tests.items.implementations.tools; package io.github.thebusybiscuit.slimefun4.testing.tests.items.implementations.tools;
import java.util.stream.Stream;
import javax.annotation.Nonnull;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest; 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.EnumSource;
import org.junit.jupiter.params.provider.MethodSource;
import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.MockBukkit;
import be.seeseemelk.mockbukkit.ServerMock; import be.seeseemelk.mockbukkit.ServerMock;
import be.seeseemelk.mockbukkit.block.BlockMock; import be.seeseemelk.mockbukkit.block.BlockMock;
import be.seeseemelk.mockbukkit.entity.PlayerMock; import be.seeseemelk.mockbukkit.entity.PlayerMock;
import io.github.thebusybiscuit.slimefun4.api.events.ClimbingPickLaunchEvent; import io.github.thebusybiscuit.slimefun4.api.events.ClimbingPickLaunchEvent;
import io.github.thebusybiscuit.slimefun4.api.exceptions.TagMisconfigurationException;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.ClimbingPick; import io.github.thebusybiscuit.slimefun4.implementation.items.tools.ClimbingPick;
import io.github.thebusybiscuit.slimefun4.testing.TestUtilities; import io.github.thebusybiscuit.slimefun4.testing.TestUtilities;
import io.github.thebusybiscuit.slimefun4.testing.interfaces.SlimefunItemTest; import io.github.thebusybiscuit.slimefun4.testing.interfaces.SlimefunItemTest;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
class TestClimbingPick implements SlimefunItemTest<ClimbingPick> { class TestClimbingPick implements SlimefunItemTest<ClimbingPick> {
private static final double STRONG_SURFACE_DEFAULT = 1.0;
private static final double WEAK_SURFACE_DEFAULT = 0.6;
private static ServerMock server; private static ServerMock server;
private static SlimefunPlugin plugin; private static SlimefunPlugin plugin;
@ -41,8 +54,7 @@ class TestClimbingPick implements SlimefunItemTest<ClimbingPick> {
@Override @Override
public ClimbingPick registerSlimefunItem(SlimefunPlugin plugin, String id) { public ClimbingPick registerSlimefunItem(SlimefunPlugin plugin, String id) {
SlimefunItemStack item = new SlimefunItemStack(id, Material.IRON_PICKAXE, "&5Test Pick"); SlimefunItemStack item = new SlimefunItemStack(id, Material.IRON_PICKAXE, "&5Test Pick", id);
ClimbingPick pick = new ClimbingPick(TestUtilities.getCategory(plugin, "climbing_pick"), item, RecipeType.NULL, new ItemStack[9]) { ClimbingPick pick = new ClimbingPick(TestUtilities.getCategory(plugin, "climbing_pick"), item, RecipeType.NULL, new ItemStack[9]) {
@Override @Override
@ -53,28 +65,106 @@ class TestClimbingPick implements SlimefunItemTest<ClimbingPick> {
}; };
pick.register(plugin); pick.register(plugin);
Assertions.assertFalse(pick.getClimbableSurfaces().isEmpty());
return pick; return pick;
} }
@ParameterizedTest
@DisplayName("Test Climbing Pick on strong surfaces")
@MethodSource("getStrongSurfaces")
void testStrongSurfaces(Material surface) {
ClimbingPick pick = registerSlimefunItem(plugin, "STRONG_CLIMBING_PICK_" + surface.name());
double speed = pick.getClimbingSpeed(surface);
Assertions.assertTrue(SlimefunTag.CLIMBING_PICK_STRONG_SURFACES.isTagged(surface));
Assertions.assertEquals(STRONG_SURFACE_DEFAULT, speed);
Assertions.assertEquals(1, pick.getClimbableSurfaces().stream().filter(s -> s.getType() == surface).count());
}
private static Stream<Arguments> getStrongSurfaces() throws TagMisconfigurationException {
SlimefunTag.reloadAll();
return SlimefunTag.CLIMBING_PICK_STRONG_SURFACES.getValues().stream().map(Arguments::of);
}
@ParameterizedTest
@DisplayName("Test Climbing Pick on weak surfaces")
@MethodSource("getWeakSurfaces")
void testWeakSurfaces(Material surface) {
ClimbingPick pick = registerSlimefunItem(plugin, "WEAK_CLIMBING_PICK_" + surface.name());
double speed = pick.getClimbingSpeed(surface);
Assertions.assertTrue(SlimefunTag.CLIMBING_PICK_WEAK_SURFACES.isTagged(surface));
Assertions.assertEquals(WEAK_SURFACE_DEFAULT, speed);
Assertions.assertEquals(1, pick.getClimbableSurfaces().stream().filter(s -> s.getType() == surface).count());
}
private static Stream<Arguments> getWeakSurfaces() throws TagMisconfigurationException {
SlimefunTag.reloadAll();
return SlimefunTag.CLIMBING_PICK_WEAK_SURFACES.getValues().stream().map(Arguments::of);
}
@Test
@DisplayName("Test Climbing Pick on climbable surface")
void testClimbable() {
ClimbingPick pick = registerSlimefunItem(plugin, "WEAK_CLIMBING_PICK");
double speed = pick.getClimbingSpeed(Material.ICE);
Assertions.assertTrue(SlimefunTag.CLIMBING_PICK_SURFACES.isTagged(Material.ICE));
Assertions.assertTrue(speed > 0);
}
@Test
@DisplayName("Test Climbing Pick on non-climbable surface")
void testNonClimbable() {
ClimbingPick pick = registerSlimefunItem(plugin, "NOT_CLIMBING_PICK");
double speed = pick.getClimbingSpeed(Material.DRAGON_EGG);
Assertions.assertFalse(SlimefunTag.CLIMBING_PICK_SURFACES.isTagged(Material.DRAGON_EGG));
Assertions.assertEquals(0, speed);
}
@ParameterizedTest @ParameterizedTest
@DisplayName("Test Climbing Pick on various Block Faces") @DisplayName("Test Climbing Pick on various Block Faces")
@EnumSource(value = BlockFace.class) @EnumSource(value = BlockFace.class, names = { "UP", "DOWN", "NORTH", "EAST", "SOUTH", "WEST" })
void testItemUse(BlockFace face) { void testItemUse(BlockFace face) {
server.getPluginManager().clearEvents();
PlayerMock player = server.addPlayer(); PlayerMock player = server.addPlayer();
ClimbingPick pick = registerSlimefunItem(plugin, "TEST_CLIMBING_PICK_" + face.name()); ClimbingPick pick = registerSlimefunItem(plugin, "TEST_CLIMBING_PICK_" + face.name());
Location blockLocation = new Location(player.getLocation().getWorld(), player.getLocation().getBlockX() + 1, player.getLocation().getBlockY(), player.getLocation().getBlockZ()); Location blockLocation = new Location(player.getLocation().getWorld(), player.getLocation().getBlockX() + 1, player.getLocation().getBlockY(), player.getLocation().getBlockZ());
boolean shouldFireEvent = face != BlockFace.DOWN && face != BlockFace.UP; boolean shouldFireEvent = face != BlockFace.DOWN && face != BlockFace.UP;
BlockMock block1 = new BlockMock(Material.ICE, blockLocation); BlockMock block = new BlockMock(Material.ICE, blockLocation);
simulateRightClickBlock(player, pick, block1, face); simulateRightClickBlock(player, pick, block, face);
if (shouldFireEvent) { if (shouldFireEvent) {
server.getPluginManager().assertEventFired(ClimbingPickLaunchEvent.class); Assertions.assertTrue(pick.getClimbingSpeed(block.getType()) > 0);
Assertions.assertTrue(player.getVelocity().length() > 0); Assertions.assertTrue(player.getVelocity().length() > 0);
server.getPluginManager().assertEventFired(ClimbingPickLaunchEvent.class, e -> e.getPlayer() == player && e.getPick() == pick);
} else { } else {
Assertions.assertEquals(0, player.getVelocity().length()); Assertions.assertEquals(0, player.getVelocity().length());
} }
} }
@Test
@DisplayName("Test Climbing Pick Efficiency modifier")
void testEfficiency() {
Material surface = Material.ICE;
ClimbingPick pick = registerSlimefunItem(plugin, "TEST_CLIMBING_PICK_EFFICIENCY");
ItemStack efficiency0 = pick.getItem().clone();
ItemStack efficiency1 = getPickWithEfficiency(pick, 1);
ItemStack efficiency2 = getPickWithEfficiency(pick, 2);
ItemStack efficiency3 = getPickWithEfficiency(pick, 3);
Assertions.assertEquals(pick.getClimbingSpeed(surface), pick.getClimbingSpeed(efficiency0, surface));
Assertions.assertTrue(pick.getClimbingSpeed(efficiency1, surface) > pick.getClimbingSpeed(efficiency0, surface));
Assertions.assertTrue(pick.getClimbingSpeed(efficiency2, surface) > pick.getClimbingSpeed(efficiency1, surface));
Assertions.assertTrue(pick.getClimbingSpeed(efficiency3, surface) > pick.getClimbingSpeed(efficiency2, surface));
}
private ItemStack getPickWithEfficiency(@Nonnull ClimbingPick pick, int level) {
ItemStack item = pick.getItem().clone();
item.addUnsafeEnchantment(Enchantment.DIG_SPEED, level);
return item;
}
} }

View File

@ -1,5 +1,6 @@
package io.github.thebusybiscuit.slimefun4.testing.tests.listeners; package io.github.thebusybiscuit.slimefun4.testing.tests.listeners;
import java.util.UUID;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
@ -21,25 +22,28 @@ import org.bukkit.inventory.ItemStack;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource; import org.junit.jupiter.params.provider.EnumSource;
import org.mockito.Mockito;
import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.MockBukkit;
import be.seeseemelk.mockbukkit.ServerMock; import be.seeseemelk.mockbukkit.ServerMock;
import be.seeseemelk.mockbukkit.entity.ItemEntityMock;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.api.exceptions.TagMisconfigurationException;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerBackpack; import io.github.thebusybiscuit.slimefun4.api.player.PlayerBackpack;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.SlimefunBackpack; import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.SlimefunBackpack;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.BackpackListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.BackpackListener;
import io.github.thebusybiscuit.slimefun4.testing.TestUtilities; import io.github.thebusybiscuit.slimefun4.testing.TestUtilities;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class TestBackpackListener { class TestBackpackListener {
private static final int BACKPACK_SIZE = 27; private static final int BACKPACK_SIZE = 27;
private static ServerMock server; private static ServerMock server;
@ -47,9 +51,11 @@ public class TestBackpackListener {
private static BackpackListener listener; private static BackpackListener listener;
@BeforeAll @BeforeAll
public static void load() { public static void load() throws TagMisconfigurationException {
server = MockBukkit.mock(); server = MockBukkit.mock();
plugin = MockBukkit.load(SlimefunPlugin.class); plugin = MockBukkit.load(SlimefunPlugin.class);
SlimefunTag.reloadAll();
listener = new BackpackListener(); listener = new BackpackListener();
listener.register(plugin); listener.register(plugin);
} }
@ -89,7 +95,8 @@ public class TestBackpackListener {
} }
@Test @Test
public void testIllegalSetId() { @DisplayName("Verify an Exception is thrown when setting a backpack id to invalid items")
void testIllegalSetId() {
Player player = server.addPlayer(); Player player = server.addPlayer();
Assertions.assertThrows(IllegalArgumentException.class, () -> listener.setBackpackId(null, null, 1, 1)); Assertions.assertThrows(IllegalArgumentException.class, () -> listener.setBackpackId(null, null, 1, 1));
@ -100,7 +107,8 @@ public class TestBackpackListener {
} }
@Test @Test
public void testSetId() throws InterruptedException { @DisplayName("Test if backpack id is properly applied to the lore")
void testSetId() throws InterruptedException {
Player player = server.addPlayer(); Player player = server.addPlayer();
ItemStack item = new CustomItem(Material.CHEST, "&cA mocked Backpack", "", "&7Size: &e" + BACKPACK_SIZE, "&7ID: <ID>", "", "&7&eRight Click&7 to open"); ItemStack item = new CustomItem(Material.CHEST, "&cA mocked Backpack", "", "&7Size: &e" + BACKPACK_SIZE, "&7ID: <ID>", "", "&7&eRight Click&7 to open");
@ -116,7 +124,8 @@ public class TestBackpackListener {
} }
@Test @Test
public void testOpenBackpack() throws InterruptedException { @DisplayName("Test backpacks opening to Players")
void testOpenBackpack() throws InterruptedException {
Player player = server.addPlayer(); Player player = server.addPlayer();
PlayerBackpack backpack = openMockBackpack(player, "TEST_OPEN_BACKPACK", 27); PlayerBackpack backpack = openMockBackpack(player, "TEST_OPEN_BACKPACK", 27);
InventoryView view = player.getOpenInventory(); InventoryView view = player.getOpenInventory();
@ -124,7 +133,8 @@ public class TestBackpackListener {
} }
@Test @Test
public void testCloseBackpack() throws InterruptedException { @DisplayName("Test backpacks being marked dirty on close")
void testCloseBackpack() throws InterruptedException {
Player player = server.addPlayer(); Player player = server.addPlayer();
PlayerBackpack backpack = openMockBackpack(player, "TEST_CLOSE_BACKPACK", 27); PlayerBackpack backpack = openMockBackpack(player, "TEST_CLOSE_BACKPACK", 27);
listener.onClose(new InventoryCloseEvent(player.getOpenInventory())); listener.onClose(new InventoryCloseEvent(player.getOpenInventory()));
@ -133,12 +143,12 @@ public class TestBackpackListener {
} }
@Test @Test
public void testBackpackDropNormalItem() throws InterruptedException { @DisplayName("Test backpacks not disturbing normal item dropping")
void testBackpackDropNormalItem() throws InterruptedException {
Player player = server.addPlayer(); Player player = server.addPlayer();
openMockBackpack(player, "DROP_NORMAL_ITEM_BACKPACK_TEST", 27); openMockBackpack(player, "DROP_NORMAL_ITEM_BACKPACK_TEST", 27);
Item item = Mockito.mock(Item.class); Item item = new ItemEntityMock(server, UUID.randomUUID(), new ItemStack(Material.SUGAR_CANE));
Mockito.when(item.getItemStack()).thenReturn(new ItemStack(Material.SUGAR_CANE));
PlayerDropItemEvent event = new PlayerDropItemEvent(player, item); PlayerDropItemEvent event = new PlayerDropItemEvent(player, item);
listener.onItemDrop(event); listener.onItemDrop(event);
@ -157,20 +167,23 @@ public class TestBackpackListener {
} }
@ParameterizedTest @ParameterizedTest
@DisplayName("Test backpacks allowing normal materials")
@EnumSource(value = Material.class, names = { "AIR", "DIAMOND", "STONE" }) @EnumSource(value = Material.class, names = { "AIR", "DIAMOND", "STONE" })
public void areItemsAllowed(Material type) throws InterruptedException { void areItemsAllowed(Material type) throws InterruptedException {
Assertions.assertTrue(isAllowed("BACKPACK_ALLOWANCE_" + type.name(), new ItemStack(type))); Assertions.assertTrue(isAllowed("BACKPACK_ALLOWANCE_" + type.name(), new ItemStack(type)));
} }
@ParameterizedTest @ParameterizedTest
@DisplayName("Test backpacks rejecting certain materials")
@EnumSource(value = Material.class, names = { "SHULKER_BOX", "RED_SHULKER_BOX", "BLUE_SHULKER_BOX", "BLACK_SHULKER_BOX" }) @EnumSource(value = Material.class, names = { "SHULKER_BOX", "RED_SHULKER_BOX", "BLUE_SHULKER_BOX", "BLACK_SHULKER_BOX" })
public void areShulkerBoxesAllowed(Material type) throws InterruptedException { void areShulkerBoxesAllowed(Material type) throws InterruptedException {
Assertions.assertFalse(isAllowed("BACKPACK_ALLOWANCE_" + type.name(), new ItemStack(type))); Assertions.assertFalse(isAllowed("BACKPACK_ALLOWANCE_" + type.name(), new ItemStack(type)));
} }
@ParameterizedTest @ParameterizedTest
@DisplayName("Test backpacks hotbar key exploits")
@EnumSource(value = Material.class, names = { "AIR", "SHULKER_BOX" }) @EnumSource(value = Material.class, names = { "AIR", "SHULKER_BOX" })
public void testHotbarKey(Material type) throws InterruptedException { void testHotbarKey(Material type) throws InterruptedException {
Player player = server.addPlayer(); Player player = server.addPlayer();
openMockBackpack(player, "BACKPACK_HOTBAR_" + type.name(), 9); openMockBackpack(player, "BACKPACK_HOTBAR_" + type.name(), 9);

View File

@ -0,0 +1,143 @@
package io.github.thebusybiscuit.slimefun4.testing.tests.tags;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Material;
import org.bukkit.Tag;
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 be.seeseemelk.mockbukkit.MockBukkit;
import io.github.thebusybiscuit.slimefun4.api.exceptions.TagMisconfigurationException;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
class TestSlimefunTags {
@BeforeAll
public static void load() {
MockBukkit.mock();
MockBukkit.load(SlimefunPlugin.class);
}
@AfterAll
public static void unload() {
MockBukkit.unmock();
}
@Test
@DisplayName("Test for Exceptions with Slimefun Tags")
void testTags() {
for (SlimefunTag tag : SlimefunTag.values()) {
Assertions.assertDoesNotThrow(tag::reload);
}
}
@Test
@DisplayName("Test for infinite loops with Slimefun Tags")
void testForInfiniteLoops() throws TagMisconfigurationException {
SlimefunTag.reloadAll();
for (SlimefunTag tag : SlimefunTag.values()) {
assertNotCyclic(tag);
}
}
@Test
@DisplayName("Test SlimefunTag#isTagged()")
void testIsTagged() throws TagMisconfigurationException {
SlimefunTag.reloadAll();
// Direct inclusion
Assertions.assertTrue(SlimefunTag.SENSITIVE_MATERIALS.isTagged(Material.CAKE));
// Inclusion through a Minecraft Tag
Assertions.assertTrue(SlimefunTag.SENSITIVE_MATERIALS.isTagged(Material.OAK_SAPLING));
// Inclusion through a Slimefun Tag
Assertions.assertTrue(SlimefunTag.SENSITIVE_MATERIALS.isTagged(Material.TORCH));
}
@Test
@DisplayName("Test SlimefunTag#toArray()")
void testToArray() throws TagMisconfigurationException {
SlimefunTag.reloadAll();
for (SlimefunTag tag : SlimefunTag.values()) {
Set<Material> values = tag.getValues();
Assertions.assertArrayEquals(values.toArray(new Material[0]), tag.toArray());
}
}
@Test
@DisplayName("Test SlimefunTag#getValues()")
void testGetValues() throws TagMisconfigurationException {
SlimefunTag.reloadAll();
for (SlimefunTag tag : SlimefunTag.values()) {
Set<Material> values = tag.getValues();
Assertions.assertFalse(values.isEmpty());
for (Material value : tag.getValues()) {
// All values of our tag must be tagged
Assertions.assertTrue(tag.isTagged(value));
}
for (Tag<Material> sub : tag.getSubTags()) {
for (Material value : sub.getValues()) {
// All values of sub tags should be tagged by our tag too
Assertions.assertTrue(tag.isTagged(value));
}
}
}
}
@Test
@DisplayName("Test static SlimefunTag accessors")
void testGetTag() {
Assertions.assertEquals(SlimefunTag.GLASS_BLOCKS, SlimefunTag.getTag("GLASS_BLOCKS"));
Assertions.assertEquals(SlimefunTag.ORES, SlimefunTag.getTag("ORES"));
Assertions.assertEquals(SlimefunTag.SHULKER_BOXES, SlimefunTag.getTag("SHULKER_BOXES"));
Assertions.assertNull(SlimefunTag.getTag("hello"));
Assertions.assertThrows(IllegalArgumentException.class, () -> SlimefunTag.getTag(null));
}
private void assertNotCyclic(@Nonnull SlimefunTag tag) {
Set<SlimefunTag> visiting = new HashSet<>();
Set<SlimefunTag> visited = new HashSet<>();
if (isCyclic(visiting, visited, tag)) {
System.out.println("Currently visiting: " + visiting);
System.out.println("Previously visited" + visiting);
Assertions.fail("Tag '" + tag.getKey() + "' is cyclic!");
}
}
@ParametersAreNonnullByDefault
private boolean isCyclic(Set<SlimefunTag> visiting, Set<SlimefunTag> visited, SlimefunTag tag) {
visiting.add(tag);
for (Tag<Material> sub : tag.getSubTags()) {
if (sub instanceof SlimefunTag) {
if (visiting.contains(sub)) {
return true;
} else if (!visited.contains(sub) && isCyclic(visiting, visited, (SlimefunTag) sub)) {
return true;
}
}
}
visiting.remove(tag);
visited.add(tag);
return false;
}
}

View File

@ -0,0 +1,104 @@
package io.github.thebusybiscuit.slimefun4.testing.tests.tags;
import javax.annotation.Nonnull;
import org.bukkit.NamespacedKey;
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 be.seeseemelk.mockbukkit.MockBukkit;
import io.github.thebusybiscuit.slimefun4.api.exceptions.TagMisconfigurationException;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.tags.TagParser;
class TestTagParser {
private static SlimefunPlugin plugin;
private static NamespacedKey key;
@BeforeAll
public static void load() {
MockBukkit.mock();
plugin = MockBukkit.load(SlimefunPlugin.class);
key = new NamespacedKey(plugin, "test");
}
@AfterAll
public static void unload() {
MockBukkit.unmock();
}
@Test
@DisplayName("Test Keyed implementation")
void testkey() {
TagParser parser = new TagParser(key);
Assertions.assertEquals(key, parser.getKey());
}
@Test
@DisplayName("Test Nullability check")
void testNullability() {
TagParser parser = new TagParser(key);
Assertions.assertThrows(IllegalArgumentException.class, () -> parser.parse(null, (a, b) -> {}));
}
@Test
@DisplayName("Test JSON Parsing Error handling")
void testInvalidJson() {
assertMisconfiguration("");
assertMisconfiguration("hello world");
}
@Test
@DisplayName("Test no Arrays")
void testMissingArray() {
assertMisconfiguration("{}");
assertMisconfiguration("{\"values\":\"derp\"}");
}
@Test
@DisplayName("Test invalid Type")
void testInvalidMaterial() {
assertMisconfiguration("{\"values\":[123456]}");
}
@Test
@DisplayName("Test invalid Materials")
void testInvalidMaterials() {
assertMisconfiguration("{\"values\":[\"NO\"]}");
assertMisconfiguration("{\"values\":[\"lol:jk\"]}");
assertMisconfiguration("{\"values\":[\"minecraft:no\"]}");
}
@Test
@DisplayName("Test invalid Minecraft Tags")
void testInvalidMinecraftTags() {
assertMisconfiguration("{\"values\":[\"#minecraft:never_gonna_give_you_up\"]}");
}
@Test
@DisplayName("Test invalid Slimefun Tags")
void testInvalidSlimefunTags() {
assertMisconfiguration("{\"values\":[\"#slimefun:never_gonna_give_you_up\"]}");
}
@Test
@DisplayName("Test invalid Object elements")
void testInvalidJSONObjects() {
assertMisconfiguration("{\"values\":[{}]}");
assertMisconfiguration("{\"values\":[{\"id\":123}]}");
assertMisconfiguration("{\"values\":[{\"id\":\"wooh\"}]}");
assertMisconfiguration("{\"values\":[{\"required\":false}]}");
assertMisconfiguration("{\"values\":[{\"id\":\"wooh\",\"required\":\"wooh\"}]}");
assertMisconfiguration("{\"values\":[{\"id\":\"wooh\",\"required\":true}]}");
}
private void assertMisconfiguration(@Nonnull String json) {
TagParser parser = new TagParser(key);
Assertions.assertThrows(TagMisconfigurationException.class, () -> parser.parse(json, (a, b) -> {}));
}
}

View File

@ -16,7 +16,7 @@ class TestHeadTextures {
void testForDuplicates() { void testForDuplicates() {
Set<String> textures = new HashSet<>(); Set<String> textures = new HashSet<>();
for (HeadTexture head : HeadTexture.values) { for (HeadTexture head : HeadTexture.valuesCache) {
String texture = head.getTexture(); String texture = head.getTexture();
Assertions.assertNotNull(texture); Assertions.assertNotNull(texture);