1
mirror of https://github.com/StarWishsama/Slimefun4.git synced 2024-09-20 03:35:51 +00:00

Merge pull request #8 from TheBusyBiscuit/master

update to latest
This commit is contained in:
dniym 2020-07-25 11:09:20 -04:00 committed by GitHub
commit bd2a30385e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 1759 additions and 819 deletions

View File

@ -27,22 +27,33 @@
* Added a [Metrics module](https://github.com/Slimefun/MetricsModule) which allows us to release updates to metrics (bStats) independently from the main plugin
* Added "Compressed Carbon -> Carbon" recipe to the Ore Crusher
* Added "Carbon -> Coal" recipe to the Ore Crusher
* Added an option to disable the message "Ignoring duplicate block"
* Added Iron Golem Assembler
* Added Reinforced Cloth
* Added Bee protection to Hazmat Suit
* Added Enchantment Rune
* Added Tape Measure
#### Changes
* Refactored and reworked the Generator API
* Small performance improvements to Energy networks
* Big performance improvements to Cargo networks when using ChestTerminal
* Slight changes to /sf timings
* Changed recipe of Hazmat Suits
* Uranium can no longer be placed down
* Huge performance improvements when using Paper
* Optimized Cargo networks for Paper
* Optimized Multiblocks for Paper
* Optimized Enhanced Furnaces for Paper
#### Fixes
* Fixed Slimefun Armor sometimes not applying its effects
* Fixed #2075
* Fixed #2093
* Fixed #2086
* Fixed #1894
* Fixed #2097
* Fixed Wither Assembler requiring more items than it actually consumes
## Release Candidate 14 (12 Jul 2020)

View File

@ -115,7 +115,7 @@ public class ErrorReport {
stream.println(" Type: " + (item.getBlockTicker().isSynchronized() ? "Synchronized" : "Asynchronous"));
stream.println();
}
if (item instanceof EnergyNetProvider) {
stream.println("Ticker-Info:");
stream.println(" Type: Indirect (Energy Network)");

View File

@ -78,7 +78,7 @@ public final class HashedArmorpiece {
*/
public boolean hasDiverged(ItemStack stack) {
if (stack == null || stack.getType() == Material.AIR) {
return hash == 0;
return hash != 0;
}
else {
ItemStack copy = stack.clone();

View File

@ -19,6 +19,7 @@ import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -31,9 +32,12 @@ import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.cscorelib2.config.Config;
import io.github.thebusybiscuit.slimefun4.api.gps.Waypoint;
import io.github.thebusybiscuit.slimefun4.api.items.HashedArmorpiece;
import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectiveArmor;
import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType;
import io.github.thebusybiscuit.slimefun4.core.guide.GuideHistory;
import io.github.thebusybiscuit.slimefun4.core.researching.Research;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece;
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
import me.mrCookieSlime.Slimefun.api.Slimefun;
@ -47,6 +51,7 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
* @see Research
* @see Waypoint
* @see PlayerBackpack
* @see HashedArmorpiece
*
*/
public final class PlayerProfile {
@ -446,6 +451,41 @@ public final class PlayerProfile {
}
}
public boolean hasFullProtectionAgainst(ProtectionType type) {
int armorCount = 0;
NamespacedKey setId = null;
for (HashedArmorpiece armorpiece : armor) {
Optional<SlimefunArmorPiece> armorPiece = armorpiece.getItem();
if (!armorPiece.isPresent()) {
return false;
}
if (armorPiece.get() instanceof ProtectiveArmor) {
ProtectiveArmor protectedArmor = (ProtectiveArmor) armorPiece.get();
if (setId == null && protectedArmor.isFullSetRequired()) {
setId = protectedArmor.getArmorSetId();
}
for (ProtectionType protectionType : protectedArmor.getProtectionTypes()) {
if (protectionType == type) {
if (setId == null) {
return true;
}
else if (setId.equals(protectedArmor.getArmorSetId())) {
armorCount++;
}
}
}
}
}
return armorCount == 4;
}
@Override
public int hashCode() {
return uuid.hashCode();

View File

@ -64,10 +64,11 @@ public class SlimefunRegistry {
private boolean enableResearches;
private boolean freeCreativeResearches;
private boolean researchFireworks;
private boolean logDuplicateBlockEntries;
private final Set<String> tickers = new HashSet<>();
private final Set<SlimefunItem> radioactive = new HashSet<>();
private final Set<String> activeChunks = new HashSet<>();
private final Set<String> activeChunks = ConcurrentHashMap.newKeySet();
private final KeyMap<GEOResource> geoResources = new KeyMap<>();
@ -82,7 +83,7 @@ public class SlimefunRegistry {
private final Map<Class<? extends ItemHandler>, Set<ItemHandler>> globalItemHandlers = new HashMap<>();
private final Map<String, SlimefunBlockHandler> blockHandlers = new HashMap<>();
private final Map<String, Set<Location>> activeTickers = new HashMap<>();
private final Map<String, Set<Location>> activeTickers = new ConcurrentHashMap<>();
private final Map<String, ItemStack> automatedCraftingChamberRecipes = new HashMap<>();
@ -98,6 +99,7 @@ public class SlimefunRegistry {
backwardsCompatibility = cfg.getBoolean("options.backwards-compatibility") || SlimefunPlugin.getMinecraftVersion().isBefore(MinecraftVersion.MINECRAFT_1_14);
freeCreativeResearches = cfg.getBoolean("researches.free-in-creative-mode");
researchFireworks = cfg.getBoolean("researches.enable-fireworks");
logDuplicateBlockEntries = cfg.getBoolean("options.log-duplicate-block-entries");
}
/**
@ -264,5 +266,9 @@ public class SlimefunRegistry {
public Map<String, ItemStack> getAutomatedCraftingChamberRecipes() {
return automatedCraftingChamberRecipes;
}
public boolean logDuplicateBlockEntries() {
return logDuplicateBlockEntries;
}
}

View File

@ -0,0 +1,26 @@
package io.github.thebusybiscuit.slimefun4.core.attributes;
import org.bukkit.entity.Bee;
/**
* Represents the {@link ProtectionType} that a {@link ProtectiveArmor}
* prevents the damage from.
*
* @author Linox
*
* @see ProtectiveArmor
*
*/
public enum ProtectionType {
/**
* This damage type represents damage inflicted by {@link Radioactive} materials.
*/
RADIATION,
/**
* This damage type represents damage caused by a {@link Bee}
*/
BEES;
}

View File

@ -0,0 +1,48 @@
package io.github.thebusybiscuit.slimefun4.core.attributes;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.HazmatArmorPiece;
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece;
/**
* Implement this interface to a {@link SlimefunArmorPiece} to protect
* the {@link Player} who wears that {@link SlimefunArmorPiece} from
* {@link ProtectionType} damage.
*
* <b>Important:</b> You need to specify which {@link ProtectionType} damages
* to protect the {@link Player} from.
*
* @author Linox
*
* @see SlimefunArmorPiece
* @see HazmatArmorPiece
* @see ItemAttribute
*
*/
public interface ProtectiveArmor extends ItemAttribute {
/**
* This returns which {@link ProtectionType} damages this {@link ItemAttribute}
* will protect the {@link Player} from.
*
* @return The {@link ProtectionType}s.
*/
ProtectionType[] getProtectionTypes();
/**
* This returns whether the full set is required for {@link Player}'s protection on
* assigned {@link ProtectionType} damages.
*
* @return Whether or not he full set is required.
*/
boolean isFullSetRequired();
/**
* This returns the armor set {@link NamespacedKey} of this {@link SlimefunArmorPiece}.
*
* @return The set {@link NamespacedKey}, <code>null</code> if none is found.
*/
NamespacedKey getArmorSetId();
}

View File

@ -36,13 +36,15 @@ class VersionsCommand extends SubCommand {
// After all these years... Spigot still displays as "CraftBukkit"
// so we will just fix this inconsistency for them :)
String serverSoftware = PaperLib.isSpigot() && !PaperLib.isPaper() ? "Spigot" : Bukkit.getName();
sender.sendMessage(ChatColors.color("&a" + serverSoftware + " &2" + ReflectionUtils.getVersion()));
sender.sendMessage("");
sender.sendMessage(ChatColors.color("&aCS-CoreLib &2v" + SlimefunPlugin.getCSCoreLibVersion()));
sender.sendMessage(ChatColors.color("&aSlimefun &2v" + SlimefunPlugin.getVersion()));
if (SlimefunPlugin.getMetricsService().getVersion() != null)
sender.sendMessage(ChatColors.color("&aMetrics: &2#" + SlimefunPlugin.getMetricsService().getVersion() + ')'));
if (SlimefunPlugin.getMetricsService().getVersion() != null) {
sender.sendMessage(ChatColors.color("&aMetrics build: &2#" + SlimefunPlugin.getMetricsService().getVersion()));
}
if (SlimefunPlugin.getRegistry().isBackwardsCompatible()) {
sender.sendMessage(ChatColor.YELLOW + "Backwards compatibility enabled!");

View File

@ -54,7 +54,7 @@ abstract class GitHubConnector {
writeCacheFile(resp.getBody());
}
else {
Slimefun.getLogger().log(Level.WARNING, "Failed to fetch {0}: {1} - {2}", new Object[] {repository + getURLSuffix(), resp.getStatus(), resp.getBody().toString()});
Slimefun.getLogger().log(Level.WARNING, "Failed to fetch {0}: {1} - {2}", new Object[] {repository + getURLSuffix(), resp.getStatus(), resp.getBody()});
}
}
catch (UnirestException e) {

View File

@ -1,8 +1,11 @@
package io.github.thebusybiscuit.slimefun4.implementation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.bukkit.ChatColor;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
@ -41,14 +44,16 @@ public final class SlimefunItems {
public static final SlimefunItemStack BROKEN_SPAWNER = new SlimefunItemStack("BROKEN_SPAWNER", Material.SPAWNER, "&cBroken Spawner", "&7Type: &b<Type>", "", "&cFractured, must be repaired in an Ancient Altar");
public static final SlimefunItemStack REPAIRED_SPAWNER = new SlimefunItemStack("REINFORCED_SPAWNER", Material.SPAWNER, "&bReinforced Spawner", "&7Type: &b<Type>");
public static final SlimefunItemStack INFERNAL_BONEMEAL = new SlimefunItemStack("INFERNAL_BONEMEAL", Material.BONE_MEAL, "&4Infernal Bonemeal", "", "&cSpeeds up the Growth of", "&cNether Warts as well");
public static final SlimefunItemStack TAPE_MEASURE = new SlimefunItemStack("TAPE_MEASURE", "180d5c43a6cf5bb7769fd0c8240e1e70d2ae38ef9d78a1db401aca6a2cb36f65", "&6Tape Measure", "", "&eCrouch & Right Click &7to set an anchor", "&eRight Click &7to measure");
/* Gadgets */
public static final SlimefunItemStack GOLD_PAN = new SlimefunItemStack("GOLD_PAN", Material.BOWL, "&6Gold Pan", "&a&oCan get you all kinds of Goodies...", "", "&7&eRight Click&7 to pan various Stuff out of Gravel");
public static final SlimefunItemStack NETHER_GOLD_PAN = new SlimefunItemStack("NETHER_GOLD_PAN", Material.BOWL, "&4Nether Gold Pan", "", "&7&eRight Click&7 to pan various stuff out of Soul Sand");
public static final SlimefunItemStack GOLD_PAN = new SlimefunItemStack("GOLD_PAN", Material.BOWL, "&6Gold Pan", "", "&eRight Click&7 to collect resources", "&7from Gravel");
public static final SlimefunItemStack NETHER_GOLD_PAN = new SlimefunItemStack("NETHER_GOLD_PAN", Material.BOWL, "&4Nether Gold Pan", "", "&eRight Click&7 to collect resources", "&7from Soul Sand");
public static final SlimefunItemStack PARACHUTE = new SlimefunItemStack("PARACHUTE", Material.LEATHER_CHESTPLATE, Color.WHITE, "&f&lParachute", "", LoreBuilder.CROUCH_TO_USE);
public static final SlimefunItemStack GRAPPLING_HOOK = new SlimefunItemStack("GRAPPLING_HOOK", Material.LEAD, "&6Grappling Hook", "", LoreBuilder.RIGHT_CLICK_TO_USE);
public static final SlimefunItemStack SOLAR_HELMET = new SlimefunItemStack("SOLAR_HELMET", Material.IRON_HELMET, "&bSolar Helmet", "", "&a&oCharges held Items and Armor");
public static final SlimefunItemStack CLOTH = new SlimefunItemStack("CLOTH", Material.PAPER, "&bCloth");
public static final SlimefunItemStack REINFORCED_CLOTH = new SlimefunItemStack("REINFORCED_CLOTH", Material.PAPER, "&bReinforced Cloth", "", "&fThis cloth has been reinforced", "&fwith &bLead &fto protect against", "&fradioactive substances");
public static final SlimefunItemStack TIN_CAN = new SlimefunItemStack("CAN", HeadTexture.TIN_CAN, "&fTin Can");
public static final SlimefunItemStack NIGHT_VISION_GOGGLES = new SlimefunItemStack("NIGHT_VISION_GOGGLES", Material.LEATHER_HELMET, Color.BLACK, "&aNight Vision Goggles", "", "&9+ Night Vision");
public static final SlimefunItemStack FARMER_SHOES = new SlimefunItemStack("FARMER_SHOES", Material.LEATHER_BOOTS, Color.YELLOW, "&eFarmer Shoes", "", "&6&oPrevents you from trampling your Crops");
@ -245,10 +250,36 @@ public final class SlimefunItems {
public static final SlimefunItemStack REINFORCED_ALLOY_LEGGINGS = new SlimefunItemStack("REINFORCED_ALLOY_LEGGINGS", Material.IRON_LEGGINGS, "&bReinforced Leggings");
public static final SlimefunItemStack REINFORCED_ALLOY_BOOTS = new SlimefunItemStack("REINFORCED_ALLOY_BOOTS", Material.IRON_BOOTS, "&bReinforced Boots");
public static final SlimefunItemStack SCUBA_HELMET = new SlimefunItemStack("SCUBA_HELMET", Material.LEATHER_HELMET, Color.ORANGE, "&cScuba Helmet", "", "&bAllows you to breathe Underwater", "&4&oPart of Hazmat Suit");
public static final SlimefunItemStack HAZMAT_CHESTPLATE = new SlimefunItemStack("HAZMAT_CHESTPLATE", Material.LEATHER_CHESTPLATE, Color.ORANGE, "&cHazmat Suit", "", "&bAllows you to walk through Fire", "&4&oPart of Hazmat Suit");
public static final SlimefunItemStack HAZMAT_LEGGINGS = new SlimefunItemStack("HAZMAT_LEGGINGS", Material.LEATHER_LEGGINGS, Color.ORANGE, "&cHazmat Suit Leggings", "", "&4&oPart of Hazmat Suit");
public static final SlimefunItemStack RUBBER_BOOTS = new SlimefunItemStack("RUBBER_BOOTS", Material.LEATHER_BOOTS, Color.BLACK, "&cRubber Boots", "", "&4&oPart of Hazmat Suit");
private static final List<String> hazmatLore = new ArrayList<>();
static {
hazmatLore.add("");
hazmatLore.add(ChatColor.GOLD + "Full set effects:");
hazmatLore.add(ChatColor.YELLOW + "- Radioation immunity");
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_15)) {
hazmatLore.add(ChatColor.YELLOW + "- Bee Sting protection");
}
}
public static final SlimefunItemStack SCUBA_HELMET = new SlimefunItemStack("SCUBA_HELMET", Material.LEATHER_HELMET, Color.ORANGE, "&cScuba Helmet", "", "&7Allows you to breathe underwater");
public static final SlimefunItemStack HAZMAT_CHESTPLATE = new SlimefunItemStack("HAZMAT_CHESTPLATE", Material.LEATHER_CHESTPLATE, Color.ORANGE, "&cHazmat Suit", "", "&7Allows you to walk through fire and lava");
public static final SlimefunItemStack HAZMAT_LEGGINGS = new SlimefunItemStack("HAZMAT_LEGGINGS", Material.LEATHER_LEGGINGS, Color.ORANGE, "&cHazmat Suit Leggings", hazmatLore.toArray(new String[0]));
public static final SlimefunItemStack HAZMAT_BOOTS = new SlimefunItemStack("RUBBER_BOOTS", Material.LEATHER_BOOTS, Color.BLACK, "&cHazmat Boots", hazmatLore.toArray(new String[0]));
static {
ItemMeta helmetMeta = SCUBA_HELMET.getItemMeta();
List<String> helmetLore = helmetMeta.getLore();
helmetLore.addAll(hazmatLore);
helmetMeta.setLore(helmetLore);
SCUBA_HELMET.setItemMeta(helmetMeta);
ItemMeta chestplateMeta = HAZMAT_CHESTPLATE.getItemMeta();
List<String> chestplateLore = chestplateMeta.getLore();
chestplateLore.addAll(hazmatLore);
chestplateMeta.setLore(chestplateLore);
HAZMAT_CHESTPLATE.setItemMeta(chestplateMeta);
}
public static final SlimefunItemStack GILDED_IRON_HELMET = new SlimefunItemStack("GILDED_IRON_HELMET", Material.GOLDEN_HELMET, "&6Gilded Iron Helmet");
public static final SlimefunItemStack GILDED_IRON_CHESTPLATE = new SlimefunItemStack("GILDED_IRON_CHESTPLATE", Material.GOLDEN_CHESTPLATE, "&6Gilded Iron Chestplate");
@ -328,6 +359,7 @@ public final class SlimefunItems {
public static final SlimefunItemStack ENDER_LUMP_3 = new SlimefunItemStack("ENDER_LUMP_3", Material.GOLD_NUGGET, "&5Ender Lump &7- &eIII", "", "&c&oTier: III");
public static final SlimefunItemStack MAGICAL_BOOK_COVER = new SlimefunItemStack("MAGICAL_BOOK_COVER", Material.PAPER, "&6Magical Book Cover", "", "&a&oUsed for various Magic Books");
public static final SlimefunItemStack MAGICAL_ZOMBIE_PILLS = new SlimefunItemStack("MAGICAL_ZOMBIE_PILLS", Material.NETHER_WART, "&6Magical Zombie Pills", "", "&eRight Click &7a Zombified Villager to", "&7instantly cure it from its curse");
public static final SlimefunItemStack MAGICAL_GLASS = new SlimefunItemStack("MAGICAL_GLASS", Material.GLASS_PANE, "&6Magical Glass", "", "&a&oUsed for various Magical Gadgets");
public static final SlimefunItemStack BASIC_CIRCUIT_BOARD = new SlimefunItemStack("BASIC_CIRCUIT_BOARD", Material.ACTIVATOR_RAIL, "&bBasic Circuit Board");
public static final SlimefunItemStack ADVANCED_CIRCUIT_BOARD = new SlimefunItemStack("ADVANCED_CIRCUIT_BOARD", Material.POWERED_RAIL, "&bAdvanced Circuit Board");
public static final SlimefunItemStack WHEAT_FLOUR = new SlimefunItemStack("WHEAT_FLOUR", Material.SUGAR, "&fWheat Flour");
@ -599,6 +631,7 @@ public final class SlimefunItems {
public static final SlimefunItemStack RAINBOW_RUNE = new SlimefunItemStack("ANCIENT_RUNE_RAINBOW", new ColoredFireworkStar(Color.FUCHSIA, "&7Ancient Rune &8&l[&d&lRainbow&8&l]"));
public static final SlimefunItemStack LIGHTNING_RUNE = new SlimefunItemStack("ANCIENT_RUNE_LIGHTNING", new ColoredFireworkStar(Color.fromRGB(255, 255, 95), "&7Ancient Rune &8&l[&e&lLightning&8&l]"));
public static final SlimefunItemStack SOULBOUND_RUNE = new SlimefunItemStack("ANCIENT_RUNE_SOULBOUND", new ColoredFireworkStar(Color.fromRGB(47, 0, 117), "&7Ancient Rune &8&l[&5&lSoulbound&8&l]", "&eDrop this rune onto a dropped item to", "&5bind &ethat item to your soul.", " ", "&eIt is advised that you only use this rune", "&eon &6important &eitems.", " ", "&eItems bound to your soul won't drop on death."));
public static final SlimefunItemStack ENCHANTMENT_RUNE = new SlimefunItemStack("ANCIENT_RUNE_ENCHANTMENT", new ColoredFireworkStar(Color.fromRGB(255, 217, 25), "&7Ancient Rune &8&l[&6&lEnchantment&8&l]", "&eDrop this rune onto a dropped item to", "&6enchant &ethat item with a random enchantment."));
/* Electricity */
public static final SlimefunItemStack SOLAR_GENERATOR = new SlimefunItemStack("SOLAR_GENERATOR", Material.DAYLIGHT_DETECTOR, "&bSolar Generator", "", LoreBuilder.machine(MachineTier.BASIC, MachineType.GENERATOR), LoreBuilder.powerBuffer(0), LoreBuilder.powerPerSecond(4));
@ -782,6 +815,7 @@ public final class SlimefunItems {
public static final SlimefunItemStack FLUID_PUMP = new SlimefunItemStack("FLUID_PUMP", Material.BLUE_TERRACOTTA, "&9Fluid Pump", "", LoreBuilder.machine(MachineTier.ADVANCED, MachineType.MACHINE), "&8\u21E8 &e\u26A1 &732 J/Block");
public static final SlimefunItemStack CHARGING_BENCH = new SlimefunItemStack("CHARGING_BENCH", Material.CRAFTING_TABLE, "&6Charging Bench", "", "&fCharges Items such as Jetpacks", "", LoreBuilder.machine(MachineTier.BASIC, MachineType.MACHINE), LoreBuilder.powerBuffer(128), "&8\u21E8 &e\u26A1 &7Energy Loss: &c50%");
public static final SlimefunItemStack IRON_GOLEM_ASSEMBLER = new SlimefunItemStack("IRON_GOLEM_ASSEMBLER", Material.IRON_BLOCK, "&6Iron Golem Assembler", "", LoreBuilder.machine(MachineTier.END_GAME, MachineType.MACHINE), "&8\u21E8 &7Cooldown: &b30 Seconds", LoreBuilder.powerBuffer(4096), "&8\u21E8 &e\u26A1 &72048 J/Golem");
public static final SlimefunItemStack WITHER_ASSEMBLER = new SlimefunItemStack("WITHER_ASSEMBLER", Material.OBSIDIAN, "&5Wither Assembler", "", LoreBuilder.machine(MachineTier.END_GAME, MachineType.MACHINE), "&8\u21E8 &7Cooldown: &b30 Seconds", LoreBuilder.powerBuffer(4096), "&8\u21E8 &e\u26A1 &74096 J/Wither");
public static final SlimefunItemStack TRASH_CAN = new SlimefunItemStack("TRASH_CAN_BLOCK", HeadTexture.TRASH_CAN, "&3Trash Can", "", "&fWill destroy all Items put into it");

View File

@ -36,12 +36,12 @@ import io.github.thebusybiscuit.slimefun4.core.services.BlockDataService;
import io.github.thebusybiscuit.slimefun4.core.services.CustomItemDataService;
import io.github.thebusybiscuit.slimefun4.core.services.CustomTextureService;
import io.github.thebusybiscuit.slimefun4.core.services.LocalizationService;
import io.github.thebusybiscuit.slimefun4.core.services.MetricsService;
import io.github.thebusybiscuit.slimefun4.core.services.MinecraftRecipeService;
import io.github.thebusybiscuit.slimefun4.core.services.PerWorldSettingsService;
import io.github.thebusybiscuit.slimefun4.core.services.PermissionsService;
import io.github.thebusybiscuit.slimefun4.core.services.UpdaterService;
import io.github.thebusybiscuit.slimefun4.core.services.github.GitHubService;
import io.github.thebusybiscuit.slimefun4.core.services.MetricsService;
import io.github.thebusybiscuit.slimefun4.core.services.plugins.ThirdPartyPluginService;
import io.github.thebusybiscuit.slimefun4.core.services.profiler.SlimefunProfiler;
import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientAltar;
@ -52,6 +52,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.SeismicAx
import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.VampireBlade;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.AncientAltarListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.BackpackListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.BeeListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.BlockListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.BlockPhysicsListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.CargoNodeListener;
@ -68,6 +69,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.IronGolemList
import io.github.thebusybiscuit.slimefun4.implementation.listeners.ItemPickupListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.MobDropListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.MultiBlockListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.PiglinListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.PlayerInteractEntityListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.PlayerProfileListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.SeismicAxeListener;
@ -165,7 +167,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
}
else if (getServer().getPluginManager().isPluginEnabled("CS-CoreLib")) {
long timestamp = System.nanoTime();
PaperLib.suggestPaper(this);
// We wanna ensure that the Server uses a compatible version of Minecraft
@ -432,6 +434,14 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
new PlayerInteractEntityListener(this);
new MobDropListener(this);
if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_15)) {
new BeeListener(this);
}
if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
new PiglinListener(this);
}
// Item-specific Listeners
new VampireBladeListener(this, (VampireBlade) SlimefunItems.BLADE_OF_VAMPIRES.getItem());
new CoolerListener(this, (Cooler) SlimefunItems.COOLER.getItem());

View File

@ -2,8 +2,11 @@ package io.github.thebusybiscuit.slimefun4.implementation.items;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent;
import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
import io.github.thebusybiscuit.slimefun4.core.attributes.Radioactive;
import io.github.thebusybiscuit.slimefun4.core.attributes.Radioactivity;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
@ -21,7 +24,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
* @see Radioactivity
*
*/
public class RadioactiveItem extends SlimefunItem implements Radioactive {
public class RadioactiveItem extends SlimefunItem implements Radioactive, NotPlaceable {
private final Radioactivity radioactivity;
@ -41,8 +44,14 @@ public class RadioactiveItem extends SlimefunItem implements Radioactive {
*/
public RadioactiveItem(Category category, Radioactivity radioactivity, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
this.radioactivity = radioactivity;
addItemHandler(onRightClick());
}
private ItemUseHandler onRightClick() {
return PlayerRightClickEvent::cancel;
}
@Override

View File

@ -0,0 +1,50 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.armor;
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectiveArmor;
import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/**
* Represents 1 {@link SlimefunArmorPiece} of the Hazmat armor set.
* One of the very few utilisations of {@link ProtectiveArmor}.
*
* @author Linox
*
* @see SlimefunArmorPiece
* @see ProtectiveArmor
*
*/
public class HazmatArmorPiece extends SlimefunArmorPiece implements ProtectiveArmor {
private final NamespacedKey namespacedKey;
private final ProtectionType[] types;
public HazmatArmorPiece(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, PotionEffect[] effects) {
super(category, item, recipeType, recipe, effects);
types = new ProtectionType[] { ProtectionType.BEES, ProtectionType.RADIATION };
namespacedKey = new NamespacedKey(SlimefunPlugin.instance(), "hazmat_suit");
}
@Override
public ProtectionType[] getProtectionTypes() {
return types;
}
@Override
public boolean isFullSetRequired() {
return true;
}
@Override
public NamespacedKey getArmorSetId() {
return namespacedKey;
}
}

View File

@ -28,5 +28,4 @@ public class SlimefunArmorPiece extends SlimefunItem {
public PotionEffect[] getPotionEffects() {
return effects;
}
}

View File

@ -0,0 +1,306 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason;
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
import me.mrCookieSlime.Slimefun.api.energy.ChargableBlock;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu;
import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow;
/**
* This is an abstract super class for Entity Assemblers.
*
* @author TheBusyBiscuit
*
* @see WitherAssembler
* @see IronGolemAssembler
*
*/
public abstract class AbstractEntityAssembler<T extends Entity> extends SimpleSlimefunItem<BlockTicker> implements EnergyNetComponent {
private static final String KEY_ENABLED = "enabled";
private static final String KEY_OFFSET = "offset";
private final int[] border = { 0, 2, 3, 4, 5, 6, 8, 12, 14, 21, 23, 30, 32, 39, 40, 41 };
private final int[] inputSlots = { 19, 28, 25, 34 };
private final int[] headSlots = { 19, 28 };
private final int[] headBorder = { 9, 10, 11, 18, 20, 27, 29, 36, 37, 38 };
private final int[] bodySlots = { 25, 34 };
private final int[] bodyBorder = { 15, 16, 17, 24, 26, 33, 35, 42, 43, 44 };
private int lifetime = 0;
public AbstractEntityAssembler(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
new BlockMenuPreset(getID(), item.getImmutableMeta().getDisplayName().orElse("Entity Assembler")) {
@Override
public void init() {
for (int i : border) {
addItem(i, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler());
}
for (int i : headBorder) {
addItem(i, new CustomItem(getHeadBorder(), " "), ChestMenuUtils.getEmptyClickHandler());
}
for (int i : bodyBorder) {
addItem(i, new CustomItem(getBodyBorder(), " "), ChestMenuUtils.getEmptyClickHandler());
}
constructMenu(this);
}
@Override
public void newInstance(BlockMenu menu, Block b) {
updateBlockInventory(menu, b);
}
@Override
public boolean canOpen(Block b, Player p) {
return p.hasPermission("slimefun.inventory.bypass") || SlimefunPlugin.getProtectionManager().hasPermission(p, b.getLocation(), ProtectableAction.ACCESS_INVENTORIES);
}
@Override
public int[] getSlotsAccessedByItemTransport(ItemTransportFlow flow) {
if (flow == ItemTransportFlow.INSERT) {
return inputSlots;
}
else {
return new int[0];
}
}
@Override
public int[] getSlotsAccessedByItemTransport(DirtyChestMenu menu, ItemTransportFlow flow, ItemStack item) {
if (flow == ItemTransportFlow.INSERT && item != null) {
if (item.getType() == getBody().getType()) {
return bodySlots;
}
if (item.getType() == getHead().getType()) {
return headSlots;
}
}
return new int[0];
}
};
registerBlockHandler(getID(), new SlimefunBlockHandler() {
@Override
public void onPlace(Player p, Block b, SlimefunItem item) {
BlockStorage.addBlockInfo(b, KEY_OFFSET, "3.0");
BlockStorage.addBlockInfo(b, KEY_ENABLED, String.valueOf(false));
}
@Override
public boolean onBreak(Player p, Block b, SlimefunItem item, UnregisterReason reason) {
if (reason == UnregisterReason.EXPLODE) {
return false;
}
BlockMenu inv = BlockStorage.getInventory(b);
dropInventory(b, inv);
return true;
}
});
}
private void updateBlockInventory(BlockMenu menu, Block b) {
if (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), KEY_ENABLED) == null || BlockStorage.getLocationInfo(b.getLocation(), KEY_ENABLED).equals(String.valueOf(false))) {
menu.replaceExistingItem(22, new CustomItem(Material.GUNPOWDER, "&7Enabled: &4\u2718", "", "&e> Click to enable this Machine"));
menu.addMenuClickHandler(22, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, KEY_ENABLED, String.valueOf(true));
updateBlockInventory(menu, b);
return false;
});
}
else {
menu.replaceExistingItem(22, new CustomItem(Material.REDSTONE, "&7Enabled: &2\u2714", "", "&e> Click to disable this Machine"));
menu.addMenuClickHandler(22, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, KEY_ENABLED, String.valueOf(false));
updateBlockInventory(menu, b);
return false;
});
}
double offset = (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), KEY_OFFSET) == null) ? 3.0F : Double.valueOf(BlockStorage.getLocationInfo(b.getLocation(), KEY_OFFSET));
menu.replaceExistingItem(31, new CustomItem(Material.PISTON, "&7Offset: &3" + offset + " Block(s)", "", "&fLeft Click: &7+0.1", "&fRight Click: &7-0.1"));
menu.addMenuClickHandler(31, (p, slot, item, action) -> {
double offsetv = DoubleHandler.fixDouble(Double.valueOf(BlockStorage.getLocationInfo(b.getLocation(), KEY_OFFSET)) + (action.isRightClicked() ? -0.1F : 0.1F));
BlockStorage.addBlockInfo(b, KEY_OFFSET, String.valueOf(offsetv));
updateBlockInventory(menu, b);
return false;
});
}
private void dropInventory(Block b, BlockMenu inv) {
if (inv != null) {
for (int slot : bodySlots) {
if (inv.getItemInSlot(slot) != null) {
b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot));
inv.replaceExistingItem(slot, null);
}
}
for (int slot : headSlots) {
if (inv.getItemInSlot(slot) != null) {
b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot));
inv.replaceExistingItem(slot, null);
}
}
}
}
@Override
public BlockTicker getItemHandler() {
return new BlockTicker() {
@Override
public void tick(Block b, SlimefunItem sf, Config data) {
if ("false".equals(BlockStorage.getLocationInfo(b.getLocation(), KEY_ENABLED))) {
return;
}
if (lifetime % 60 == 0 && ChargableBlock.getCharge(b) >= getEnergyConsumption()) {
BlockMenu menu = BlockStorage.getInventory(b);
boolean hasBody = findResource(menu, getBody(), bodySlots);
boolean hasHead = findResource(menu, getHead(), headSlots);
if (hasBody && hasHead) {
consumeResources(menu);
ChargableBlock.addCharge(b, -getEnergyConsumption());
double offset = Double.parseDouble(BlockStorage.getLocationInfo(b.getLocation(), KEY_OFFSET));
Slimefun.runSync(() -> {
Location loc = new Location(b.getWorld(), b.getX() + 0.5D, b.getY() + offset, b.getZ() + 0.5D);
spawnEntity(loc);
b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, getHead().getType());
});
}
}
}
@Override
public void uniqueTick() {
lifetime++;
}
@Override
public boolean isSynchronized() {
return false;
}
};
}
private boolean findResource(BlockMenu menu, ItemStack item, int[] slots) {
int found = 0;
for (int slot : slots) {
if (SlimefunUtils.isItemSimilar(menu.getItemInSlot(slot), item, true, false)) {
found += menu.getItemInSlot(slot).getAmount();
if (found >= item.getAmount()) {
return true;
}
}
}
return false;
}
private void consumeResources(BlockMenu inv) {
int bodyCount = getBody().getAmount();
int headCount = getHead().getAmount();
for (int slot : bodySlots) {
if (SlimefunUtils.isItemSimilar(inv.getItemInSlot(slot), getBody(), true, false)) {
int amount = inv.getItemInSlot(slot).getAmount();
if (amount >= bodyCount) {
inv.consumeItem(slot, bodyCount);
break;
}
else {
bodyCount -= amount;
inv.replaceExistingItem(slot, null);
}
}
}
for (int slot : headSlots) {
if (SlimefunUtils.isItemSimilar(inv.getItemInSlot(slot), getHead(), true, false)) {
int amount = inv.getItemInSlot(slot).getAmount();
if (amount >= headCount) {
inv.consumeItem(slot, headCount);
break;
}
else {
headCount -= amount;
inv.replaceExistingItem(slot, null);
}
}
}
}
protected void constructMenu(BlockMenuPreset preset) {
preset.addItem(1, new CustomItem(getHead(), "&7Head Slot", "", "&fThis Slot accepts the head type"), ChestMenuUtils.getEmptyClickHandler());
preset.addItem(7, new CustomItem(getBody(), "&7Body Slot", "", "&fThis Slot accepts the body type"), ChestMenuUtils.getEmptyClickHandler());
preset.addItem(13, new CustomItem(Material.CLOCK, "&7Cooldown: &b30 Seconds", "", "&fThis Machine takes up to half a Minute to operate", "&fso give it some Time!"), ChestMenuUtils.getEmptyClickHandler());
}
@Override
public EnergyNetComponentType getEnergyComponentType() {
return EnergyNetComponentType.CONSUMER;
}
public abstract int getEnergyConsumption();
public abstract ItemStack getHead();
public abstract ItemStack getBody();
public abstract Material getHeadBorder();
public abstract Material getBodyBorder();
public abstract T spawnEntity(Location l);
}

View File

@ -0,0 +1,80 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.IronGolem;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
/**
* The {@link IronGolemAssembler} is an electrical machine that can automatically spawn
* a {@link IronGolem} if the required ingredients have been provided.
*
* @author TheBusyBiscuit
*
* @see WitherAssembler
*
*/
public class IronGolemAssembler extends AbstractEntityAssembler<IronGolem> {
public IronGolemAssembler(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
}
@Override
public int getCapacity() {
return 4096;
}
@Override
public int getEnergyConsumption() {
return 2048;
}
@Override
public ItemStack getHead() {
return new ItemStack(Material.CARVED_PUMPKIN);
}
@Override
public Material getHeadBorder() {
return Material.ORANGE_STAINED_GLASS_PANE;
}
@Override
public ItemStack getBody() {
return new ItemStack(Material.IRON_BLOCK, 4);
}
@Override
public Material getBodyBorder() {
return Material.WHITE_STAINED_GLASS_PANE;
}
@Override
protected void constructMenu(BlockMenuPreset preset) {
preset.addItem(1, new CustomItem(getHead(), "&7Pumpkin Slot", "", "&fThis Slot accepts Pumpkins"), ChestMenuUtils.getEmptyClickHandler());
preset.addItem(7, new CustomItem(getBody(), "&7Iron Block Slot", "", "&fThis Slot accepts Iron Blocks"), ChestMenuUtils.getEmptyClickHandler());
preset.addItem(13, new CustomItem(Material.CLOCK, "&7Cooldown: &b30 Seconds", "", "&fThis Machine takes up to half a Minute to operate", "&fso give it some Time!"), ChestMenuUtils.getEmptyClickHandler());
}
@Override
public IronGolem spawnEntity(Location l) {
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_15)) {
// This sound doesn't exist in 1.14 and earlier :/
l.getWorld().playSound(l, Sound.ENTITY_IRON_GOLEM_REPAIR, 0.5F, 1);
}
return l.getWorld().spawn(l, IronGolem.class);
}
}

View File

@ -2,195 +2,29 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machine
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.entity.Wither;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason;
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
import me.mrCookieSlime.Slimefun.api.energy.ChargableBlock;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu;
import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow;
/**
* The {@link WitherAssembler} is an electrical machine that can automatically spawn
* a {@link Wither} if the required ingredients have been provided.
*
* @author TheBusyBiscuit
*
* @see IronGolemAssembler
*
*/
public class WitherAssembler extends SimpleSlimefunItem<BlockTicker> implements EnergyNetComponent {
private static final int ENERGY_CONSUMPTION = 4096;
private final int[] border = { 0, 2, 3, 4, 5, 6, 8, 12, 14, 21, 23, 30, 32, 39, 40, 41 };
private final int[] skullBorder = { 9, 10, 11, 18, 20, 27, 29, 36, 37, 38 };
private final int[] sandBorder = { 15, 16, 17, 24, 26, 33, 35, 42, 43, 44 };
private int lifetime = 0;
public class WitherAssembler extends AbstractEntityAssembler<Wither> {
public WitherAssembler(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
new BlockMenuPreset(getID(), "&5Wither Assembler") {
@Override
public void init() {
constructMenu(this);
}
@Override
public void newInstance(BlockMenu menu, Block b) {
if (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), "enabled") == null || BlockStorage.getLocationInfo(b.getLocation(), "enabled").equals(String.valueOf(false))) {
menu.replaceExistingItem(22, new CustomItem(Material.GUNPOWDER, "&7Enabled: &4\u2718", "", "&e> Click to enable this Machine"));
menu.addMenuClickHandler(22, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, "enabled", String.valueOf(true));
newInstance(menu, b);
return false;
});
}
else {
menu.replaceExistingItem(22, new CustomItem(Material.REDSTONE, "&7Enabled: &2\u2714", "", "&e> Click to disable this Machine"));
menu.addMenuClickHandler(22, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, "enabled", String.valueOf(false));
newInstance(menu, b);
return false;
});
}
double offset = (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), "offset") == null) ? 3.0F : Double.valueOf(BlockStorage.getLocationInfo(b.getLocation(), "offset"));
menu.replaceExistingItem(31, new CustomItem(Material.PISTON, "&7Offset: &3" + offset + " Block(s)", "", "&rLeft Click: &7+0.1", "&rRight Click: &7-0.1"));
menu.addMenuClickHandler(31, (p, slot, item, action) -> {
double offsetv = DoubleHandler.fixDouble(Double.valueOf(BlockStorage.getLocationInfo(b.getLocation(), "offset")) + (action.isRightClicked() ? -0.1F : 0.1F));
BlockStorage.addBlockInfo(b, "offset", String.valueOf(offsetv));
newInstance(menu, b);
return false;
});
}
@Override
public boolean canOpen(Block b, Player p) {
return p.hasPermission("slimefun.inventory.bypass") || SlimefunPlugin.getProtectionManager().hasPermission(p, b.getLocation(), ProtectableAction.ACCESS_INVENTORIES);
}
@Override
public int[] getSlotsAccessedByItemTransport(ItemTransportFlow flow) {
if (flow == ItemTransportFlow.INSERT) {
return getInputSlots();
}
else {
return new int[0];
}
}
@Override
public int[] getSlotsAccessedByItemTransport(DirtyChestMenu menu, ItemTransportFlow flow, ItemStack item) {
if (flow == ItemTransportFlow.INSERT && item != null) {
if (item.getType() == Material.SOUL_SAND) {
return getSoulSandSlots();
}
if (item.getType() == Material.WITHER_SKELETON_SKULL) {
return getWitherSkullSlots();
}
}
return new int[0];
}
};
registerBlockHandler(getID(), new SlimefunBlockHandler() {
@Override
public void onPlace(Player p, Block b, SlimefunItem item) {
BlockStorage.addBlockInfo(b, "offset", "3.0");
BlockStorage.addBlockInfo(b, "enabled", String.valueOf(false));
}
@Override
public boolean onBreak(Player p, Block b, SlimefunItem item, UnregisterReason reason) {
if (reason == UnregisterReason.EXPLODE) {
return false;
}
BlockMenu inv = BlockStorage.getInventory(b);
if (inv != null) {
for (int slot : getSoulSandSlots()) {
if (inv.getItemInSlot(slot) != null) {
b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot));
inv.replaceExistingItem(slot, null);
}
}
for (int slot : getWitherSkullSlots()) {
if (inv.getItemInSlot(slot) != null) {
b.getWorld().dropItemNaturally(b.getLocation(), inv.getItemInSlot(slot));
inv.replaceExistingItem(slot, null);
}
}
}
return true;
}
});
}
private void constructMenu(BlockMenuPreset preset) {
for (int i : border) {
preset.addItem(i, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler());
}
for (int i : skullBorder) {
preset.addItem(i, new CustomItem(Material.BLACK_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler());
}
for (int i : sandBorder) {
preset.addItem(i, new CustomItem(Material.BROWN_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler());
}
preset.addItem(1, new CustomItem(Material.WITHER_SKELETON_SKULL, "&7Wither Skull Slot", "", "&rThis Slot accepts Wither Skeleton Skulls"), ChestMenuUtils.getEmptyClickHandler());
preset.addItem(7, new CustomItem(Material.SOUL_SAND, "&7Soul Sand Slot", "", "&rThis Slot accepts Soul Sand"), ChestMenuUtils.getEmptyClickHandler());
preset.addItem(13, new CustomItem(Material.CLOCK, "&7Cooldown: &b30 Seconds", "", "&rThis Machine takes up to half a Minute to operate", "&rso give it some Time!"), ChestMenuUtils.getEmptyClickHandler());
}
public int[] getInputSlots() {
return new int[] { 19, 28, 25, 34 };
}
public int[] getWitherSkullSlots() {
return new int[] { 19, 28 };
}
public int[] getSoulSandSlots() {
return new int[] { 25, 34 };
}
@Override
public EnergyNetComponentType getEnergyComponentType() {
return EnergyNetComponentType.CONSUMER;
}
@Override
@ -199,93 +33,40 @@ public class WitherAssembler extends SimpleSlimefunItem<BlockTicker> implements
}
@Override
public BlockTicker getItemHandler() {
return new BlockTicker() {
@Override
public void tick(Block b, SlimefunItem sf, Config data) {
if (String.valueOf(false).equals(BlockStorage.getLocationInfo(b.getLocation(), "enabled"))) {
return;
}
if (lifetime % 60 == 0 && ChargableBlock.getCharge(b) >= ENERGY_CONSUMPTION) {
BlockMenu menu = BlockStorage.getInventory(b);
boolean soulsand = findResource(menu, Material.SOUL_SAND, 4, getSoulSandSlots());
boolean skulls = findResource(menu, Material.WITHER_SKELETON_SKULL, 3, getWitherSkullSlots());
if (soulsand && skulls) {
consumeResources(menu);
ChargableBlock.addCharge(b, -ENERGY_CONSUMPTION);
double offset = Double.parseDouble(BlockStorage.getLocationInfo(b.getLocation(), "offset"));
Slimefun.runSync(() -> b.getWorld().spawnEntity(new Location(b.getWorld(), b.getX() + 0.5D, b.getY() + offset, b.getZ() + 0.5D), EntityType.WITHER));
}
}
}
@Override
public void uniqueTick() {
lifetime++;
}
@Override
public boolean isSynchronized() {
return false;
}
};
public int getEnergyConsumption() {
return 4096;
}
private boolean findResource(BlockMenu menu, Material resource, int required, int[] slots) {
int found = 0;
for (int slot : slots) {
if (SlimefunUtils.isItemSimilar(menu.getItemInSlot(slot), new ItemStack(resource), true, false)) {
found += menu.getItemInSlot(slot).getAmount();
if (found > required) {
return true;
}
}
}
return false;
@Override
public ItemStack getHead() {
return new ItemStack(Material.WITHER_SKELETON_SKULL, 3);
}
private void consumeResources(BlockMenu inv) {
int soulsand = 4;
int skulls = 3;
@Override
public Material getHeadBorder() {
return Material.BLACK_STAINED_GLASS_PANE;
}
for (int slot : getSoulSandSlots()) {
if (SlimefunUtils.isItemSimilar(inv.getItemInSlot(slot), new ItemStack(Material.SOUL_SAND), true, false)) {
int amount = inv.getItemInSlot(slot).getAmount();
@Override
public ItemStack getBody() {
return new ItemStack(Material.SOUL_SAND, 4);
}
if (amount >= soulsand) {
inv.consumeItem(slot, soulsand);
break;
}
else {
soulsand -= amount;
inv.replaceExistingItem(slot, null);
}
}
}
@Override
public Material getBodyBorder() {
return Material.BROWN_STAINED_GLASS_PANE;
}
for (int slot : getWitherSkullSlots()) {
if (SlimefunUtils.isItemSimilar(inv.getItemInSlot(slot), new ItemStack(Material.WITHER_SKELETON_SKULL), true, false)) {
int amount = inv.getItemInSlot(slot).getAmount();
@Override
protected void constructMenu(BlockMenuPreset preset) {
preset.addItem(1, new CustomItem(getHead(), "&7Wither Skeleton Skull Slot", "", "&fThis Slot accepts Wither Skeleton Skulls"), ChestMenuUtils.getEmptyClickHandler());
preset.addItem(7, new CustomItem(getBody(), "&7Soul Sand Slot", "", "&fThis Slot accepts Soul Sand"), ChestMenuUtils.getEmptyClickHandler());
preset.addItem(13, new CustomItem(Material.CLOCK, "&7Cooldown: &b30 Seconds", "", "&fThis Machine takes up to half a Minute to operate", "&fso give it some Time!"), ChestMenuUtils.getEmptyClickHandler());
}
if (amount >= skulls) {
inv.consumeItem(slot, skulls);
break;
}
else {
skulls -= amount;
inv.replaceExistingItem(slot, null);
}
}
}
@Override
public Wither spawnEntity(Location l) {
return l.getWorld().spawn(l, Wither.class);
}
}

View File

@ -0,0 +1,182 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.magical;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ThreadLocalRandom;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.Sound;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemDropHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/**
* This {@link SlimefunItem} allows you to enchant any enchantable {@link ItemStack} with a random
* {@link Enchantment}. It is also one of the very few utilisations of {@link ItemDropHandler}.
*
* @author Linox
*
* @see ItemDropHandler
*
*/
public class EnchantmentRune extends SimpleSlimefunItem<ItemDropHandler> {
private static final double RANGE = 1.5;
private final Map<Material, List<Enchantment>> applicableEnchantments = new EnumMap<>(Material.class);
public EnchantmentRune(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
for (Material mat : Material.values()) {
List<Enchantment> enchantments = new ArrayList<>();
for (Enchantment enchantment : Enchantment.values()) {
if (enchantment == Enchantment.BINDING_CURSE || enchantment == Enchantment.VANISHING_CURSE) {
continue;
}
if (enchantment.canEnchantItem(new ItemStack(mat))) {
enchantments.add(enchantment);
}
}
applicableEnchantments.put(mat, enchantments);
}
}
@Override
public ItemDropHandler getItemHandler() {
return (e, p, item) -> {
if (isItem(item.getItemStack())) {
if (Slimefun.hasUnlocked(p, this, true)) {
Slimefun.runSync(() -> {
try {
addRandomEnchantment(p, e, item);
}
catch (Exception x) {
error("An Exception occured while trying to apply an Enchantment Rune", x);
}
}, 20L);
}
return true;
}
return false;
};
}
private void addRandomEnchantment(Player p, PlayerDropItemEvent e, Item item) {
// Being sure the entity is still valid and not picked up or whatsoever.
if (!item.isValid()) {
return;
}
Location l = item.getLocation();
Collection<Entity> entites = l.getWorld().getNearbyEntities(l, RANGE, RANGE, RANGE, this::findCompatibleItem);
Optional<Entity> optional = entites.stream().findFirst();
if (optional.isPresent()) {
Item entity = (Item) optional.get();
ItemStack target = entity.getItemStack();
List<Enchantment> potentialEnchantments = applicableEnchantments.get(target.getType());
if (potentialEnchantments == null) {
SlimefunPlugin.getLocalization().sendMessage(p, "messages.enchantment-rune.fail", true);
return;
}
else {
potentialEnchantments = new ArrayList<>(potentialEnchantments);
}
// Removing the enchantments that the item already has from enchantmentSet
// This also removes any conflicting enchantments
removeIllegalEnchantments(target, potentialEnchantments);
if (potentialEnchantments.isEmpty()) {
SlimefunPlugin.getLocalization().sendMessage(p, "messages.enchantment-rune.no-enchantment", true);
return;
}
Enchantment enchantment = potentialEnchantments.get(ThreadLocalRandom.current().nextInt(potentialEnchantments.size()));
int level = 1;
if (enchantment.getMaxLevel() != 1) {
level = ThreadLocalRandom.current().nextInt(enchantment.getMaxLevel()) + 1;
}
target.addEnchantment(enchantment, level);
if (target.getAmount() == 1) {
e.setCancelled(true);
// This lightning is just an effect, it deals no damage.
l.getWorld().strikeLightningEffect(l);
Slimefun.runSync(() -> {
// Being sure entities are still valid and not picked up or whatsoever.
if (item.isValid() && entity.isValid() && target.getAmount() == 1) {
l.getWorld().spawnParticle(Particle.CRIT_MAGIC, l, 1);
l.getWorld().playSound(l, Sound.ENTITY_ZOMBIE_VILLAGER_CURE, 1F, 1F);
entity.remove();
item.remove();
l.getWorld().dropItemNaturally(l, target);
SlimefunPlugin.getLocalization().sendMessage(p, "messages.enchantment-rune.success", true);
}
}, 10L);
}
else {
SlimefunPlugin.getLocalization().sendMessage(p, "messages.enchantment-rune.fail", true);
}
}
}
private void removeIllegalEnchantments(ItemStack target, List<Enchantment> potentialEnchantments) {
for (Enchantment enchantment : target.getEnchantments().keySet()) {
Iterator<Enchantment> iterator = potentialEnchantments.iterator();
while (iterator.hasNext()) {
Enchantment possibleEnchantment = iterator.next();
// Duplicate or conflict
if (possibleEnchantment.equals(enchantment) || possibleEnchantment.conflictsWith(enchantment)) {
iterator.remove();
}
}
}
}
private boolean findCompatibleItem(Entity n) {
if (n instanceof Item) {
Item item = (Item) n;
return !isItem(item.getItemStack());
}
return false;
}
}

View File

@ -1,6 +1,8 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.magical;
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
import org.bukkit.GameMode;
import org.bukkit.Sound;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Villager;
@ -39,7 +41,10 @@ public class MagicalZombiePills extends SimpleSlimefunItem<EntityInteractHandler
return (p, entity, item, offhand) -> {
if (entity.getType() == EntityType.ZOMBIE_VILLAGER) {
ItemUtils.consumeItem(item, false);
if (p.getGameMode() != GameMode.CREATIVE) {
ItemUtils.consumeItem(item, false);
}
p.playSound(p.getLocation(), Sound.ENTITY_ZOMBIE_VILLAGER_CONVERTED, 1, 1);
ZombieVillager zombieVillager = (ZombieVillager) entity;

View File

@ -13,7 +13,6 @@ import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.core.attributes.Soulbound;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemDropHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
@ -48,7 +47,7 @@ public class SoulboundRune extends SimpleSlimefunItem<ItemDropHandler> {
return (e, p, item) -> {
if (isItem(item.getItemStack())) {
if (!Slimefun.hasUnlocked(p, SlimefunItems.SOULBOUND_RUNE, true)) {
if (!Slimefun.hasUnlocked(p, this, true)) {
return true;
}

View File

@ -0,0 +1,115 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.tools;
import java.text.DecimalFormat;
import java.util.Optional;
import java.util.UUID;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/**
* The {@link TapeMeasure} is used to measure the distance between two {@link Block Blocks}.
*
* @author TheBusyBiscuit
*
*/
public class TapeMeasure extends SimpleSlimefunItem<ItemUseHandler> implements NotPlaceable {
private final NamespacedKey key = new NamespacedKey(SlimefunPlugin.instance(), "anchor");
private final DecimalFormat format = new DecimalFormat("##.###");
public TapeMeasure(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
}
@Override
public ItemUseHandler getItemHandler() {
return e -> {
e.cancel();
if (e.getClickedBlock().isPresent()) {
Block block = e.getClickedBlock().get();
if (e.getPlayer().isSneaking()) {
setAnchor(e.getPlayer(), e.getItem(), block);
}
else {
measure(e.getPlayer(), e.getItem(), block);
}
}
};
}
private void setAnchor(Player p, ItemStack item, Block block) {
ItemMeta meta = item.getItemMeta();
JsonObject json = new JsonObject();
json.addProperty("world", block.getWorld().getUID().toString());
json.addProperty("x", block.getX());
json.addProperty("y", block.getY());
json.addProperty("z", block.getZ());
meta.getPersistentDataContainer().set(key, PersistentDataType.STRING, json.toString());
String anchor = block.getX() + " | " + block.getY() + " | " + block.getZ();
SlimefunPlugin.getLocalization().sendMessage(p, "messages.tape-measure.anchor-set", msg -> msg.replace("%anchor%", anchor));
item.setItemMeta(meta);
}
private Optional<Location> getAnchor(Player p, ItemStack item) {
ItemMeta meta = item.getItemMeta();
String data = meta.getPersistentDataContainer().get(key, PersistentDataType.STRING);
if (data != null) {
JsonObject json = new JsonParser().parse(data).getAsJsonObject();
UUID uuid = UUID.fromString(json.get("world").getAsString());
if (p.getWorld().getUID().equals(uuid)) {
int x = json.get("x").getAsInt();
int y = json.get("y").getAsInt();
int z = json.get("z").getAsInt();
Location loc = new Location(p.getWorld(), x, y, z);
return Optional.of(loc);
}
else {
SlimefunPlugin.getLocalization().sendMessage(p, "messages.tape-measure.wrong-world");
return Optional.empty();
}
}
else {
SlimefunPlugin.getLocalization().sendMessage(p, "messages.tape-measure.no-anchor");
return Optional.empty();
}
}
private void measure(Player p, ItemStack item, Block block) {
Optional<Location> anchor = getAnchor(p, item);
if (anchor.isPresent()) {
Location loc = anchor.get();
double distance = loc.distance(block.getLocation());
SlimefunPlugin.getLocalization().sendMessage(p, "messages.tape-measure.distance", msg -> msg.replace("%distance%", format.format(distance)));
}
}
}

View File

@ -0,0 +1,53 @@
package io.github.thebusybiscuit.slimefun4.implementation.listeners;
import java.util.Optional;
import org.bukkit.entity.Bee;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
/**
* The {@link Listener} for Hazmat Suit's {@link Bee} sting protection.
* Only applied if the whole set is worn.
*
* @author Linox
*
*/
public class BeeListener implements Listener {
public BeeListener(SlimefunPlugin plugin) {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler
public void onDamage(EntityDamageByEntityEvent e) {
if (e.getDamager() instanceof Bee && e.getEntity() instanceof Player) {
Player p = (Player) e.getEntity();
Optional<PlayerProfile> optional = PlayerProfile.find(p);
if (!optional.isPresent()) {
PlayerProfile.request(p);
return;
}
PlayerProfile profile = optional.get();
if (profile.hasFullProtectionAgainst(ProtectionType.BEES)) {
for (ItemStack armor : p.getInventory().getArmorContents()) {
ItemUtils.damageItem(armor, 1, false);
}
e.setDamage(0D);
}
}
}
}

View File

@ -11,7 +11,7 @@ import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
/**
* Listens to the ItemPickup events to prevent it if the item has the "no_pickup" metadata or is an ALTAR_PROBE.
*
*
* @author TheBusyBiscuit
*/
public class ItemPickupListener implements Listener {

View File

@ -0,0 +1,67 @@
package io.github.thebusybiscuit.slimefun4.implementation.listeners;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Piglin;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
/**
* This {@link Listener} prevents a {@link Piglin} from bartering with a {@link SlimefunItem}.
*
* @author poma123
*
*/
public class PiglinListener implements Listener {
public PiglinListener(SlimefunPlugin plugin) {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler
public void onEntityPickup(EntityPickupItemEvent e) {
if (e.getEntityType() == EntityType.PIGLIN) {
ItemStack item = e.getItem().getItemStack();
// Don't let Piglins pick up gold from Slimefun
if (SlimefunItem.getByItem(item) != null) {
e.setCancelled(true);
}
}
}
@EventHandler
public void onInteractEntity(PlayerInteractEntityEvent e) {
if (!e.getRightClicked().isValid() || e.getRightClicked().getType() != EntityType.PIGLIN) {
return;
}
Player p = e.getPlayer();
ItemStack item;
if (e.getHand() == EquipmentSlot.OFF_HAND) {
item = p.getInventory().getItemInOffHand();
}
else {
item = p.getInventory().getItemInMainHand();
}
// We only care about Gold since it's the actual "Bartering" we wanna prevent
if (item.getType() == Material.GOLD_INGOT) {
SlimefunItem sfItem = SlimefunItem.getByItem(item);
if (sfItem != null) {
SlimefunPlugin.getLocalization().sendMessage(p, "messages.piglin-barter", true);
e.setCancelled(true);
}
}
}
}

View File

@ -104,7 +104,7 @@ public final class ResearchSetup {
register("whirlwind_talisman", 75, "Talisman of the Whirlwind", 19, SlimefunItems.TALISMAN_WHIRLWIND);
register("wizard_talisman", 76, "Talisman of the Wizard", 22, SlimefunItems.TALISMAN_WIZARD);
register("lumber_axe", 77, "Lumber Axe", 21, SlimefunItems.LUMBER_AXE);
register("hazmat_suit", 79, "Hazmat Suit", 21, SlimefunItems.SCUBA_HELMET, SlimefunItems.HAZMAT_CHESTPLATE, SlimefunItems.HAZMAT_LEGGINGS, SlimefunItems.RUBBER_BOOTS);
register("hazmat_suit", 79, "Hazmat Suit", 21, SlimefunItems.SCUBA_HELMET, SlimefunItems.HAZMAT_CHESTPLATE, SlimefunItems.HAZMAT_LEGGINGS, SlimefunItems.HAZMAT_BOOTS);
register("uranium", 80, "Radioactive", 30, SlimefunItems.TINY_URANIUM, SlimefunItems.SMALL_URANIUM, SlimefunItems.URANIUM);
register("crushed_ore", 81, "Ore Purification", 25, SlimefunItems.CRUSHED_ORE, SlimefunItems.PULVERIZED_ORE, SlimefunItems.PURE_ORE_CLUSTER);
register("redstone_alloy", 84, "Redstone Alloy", 16, SlimefunItems.REDSTONE_ALLOY);
@ -267,6 +267,10 @@ public final class ResearchSetup {
register("advanced_industrial_miner", 98, "Better Mining", 36, SlimefunItems.ADVANCED_INDUSTRIAL_MINER);
register("magical_zombie_pills", 257, "De-Zombification", 22, SlimefunItems.MAGICAL_ZOMBIE_PILLS);
register("auto_brewer", 258, "Industrial Brewery", 30, SlimefunItems.AUTO_BREWER);
register("enchantment_rune", 259, "Ancient Enchanting", 24, SlimefunItems.MAGICAL_GLASS, SlimefunItems.ENCHANTMENT_RUNE);
register("lead_clothing", 260, "Lead Clothing", 14, SlimefunItems.REINFORCED_CLOTH);
register("tape_measure", 261, "Tape Measure", 7, SlimefunItems.TAPE_MEASURE);
register("iron_golem_assembler", 262, "Automated Iron Golems", 30, SlimefunItems.IRON_GOLEM_ASSEMBLER);
}
private static void register(String key, int id, String name, int defaultCost, ItemStack... items) {

View File

@ -32,6 +32,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.androids.FisherAn
import io.github.thebusybiscuit.slimefun4.implementation.items.androids.MinerAndroid;
import io.github.thebusybiscuit.slimefun4.implementation.items.androids.ProgrammableAndroid;
import io.github.thebusybiscuit.slimefun4.implementation.items.androids.WoodcutterAndroid;
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.HazmatArmorPiece;
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.Parachute;
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece;
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler;
@ -96,6 +97,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.FoodFabricator;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.Freezer;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.HeatedPressureChamber;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.IronGolemAssembler;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.Refinery;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.TreeGrowthAccelerator;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.WitherAssembler;
@ -120,6 +122,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.gps.GPSTransmitte
import io.github.thebusybiscuit.slimefun4.implementation.items.gps.PersonalActivationPlate;
import io.github.thebusybiscuit.slimefun4.implementation.items.gps.Teleporter;
import io.github.thebusybiscuit.slimefun4.implementation.items.gps.TeleporterPylon;
import io.github.thebusybiscuit.slimefun4.implementation.items.magical.EnchantmentRune;
import io.github.thebusybiscuit.slimefun4.implementation.items.magical.InfernalBonemeal;
import io.github.thebusybiscuit.slimefun4.implementation.items.magical.InfusedMagnet;
import io.github.thebusybiscuit.slimefun4.implementation.items.magical.KnowledgeFlask;
@ -173,6 +176,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.tools.PickaxeOfVe
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.PortableCrafter;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.PortableDustbin;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.SmeltersPickaxe;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.TapeMeasure;
import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.ExplosiveBow;
import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.IcyBow;
import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.SeismicAxe;
@ -350,12 +354,12 @@ public final class SlimefunItemSetup {
new ItemStack[] {SlimefunItems.SALT, new ItemStack(Material.ROTTEN_FLESH), null, null, null, null, null, null, null})
.register(plugin);
new SlimefunItem(categories.magicalArmor, SlimefunItems.SLIME_HELMET, RecipeType.ARMOR_FORGE,
new ItemStack[] {new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), null, new ItemStack(Material.IRON_INGOT), null, null, null})
new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_HELMET, RecipeType.ARMOR_FORGE,
new ItemStack[] {new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), null, new ItemStack(Material.IRON_INGOT), null, null, null}, null)
.register(plugin);
new SlimefunItem(categories.magicalArmor, SlimefunItems.SLIME_CHESTPLATE, RecipeType.ARMOR_FORGE,
new ItemStack[] {new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT)})
new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_CHESTPLATE, RecipeType.ARMOR_FORGE,
new ItemStack[] {new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.IRON_INGOT), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.IRON_INGOT)}, null)
.register(plugin);
new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_LEGGINGS, RecipeType.ARMOR_FORGE,
@ -376,6 +380,10 @@ public final class SlimefunItemSetup {
new ItemStack[] {null, SlimefunItems.MAGIC_LUMP_2, null, SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.BOOK), SlimefunItems.MAGIC_LUMP_2, null, SlimefunItems.MAGIC_LUMP_2, null})
.register(plugin);
new SlimefunItem(categories.magicalResources, SlimefunItems.MAGICAL_GLASS, RecipeType.MAGIC_WORKBENCH,
new ItemStack[] {SlimefunItems.MAGIC_LUMP_2, SlimefunItems.GOLD_DUST, SlimefunItems.MAGIC_LUMP_2, SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE, new ItemStack(Material.GLASS_PANE), SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE, SlimefunItems.MAGIC_LUMP_2, SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE, SlimefunItems.MAGIC_LUMP_2})
.register(plugin);
new BasicCircuitBoard(categories.technicalComponents, SlimefunItems.BASIC_CIRCUIT_BOARD, RecipeType.MOB_DROP,
new ItemStack[] {null, null, null, null, new CustomItem(SlimefunUtils.getCustomHead("89091d79ea0f59ef7ef94d7bba6e5f17f2f7d4572c44f90f76c4819a714"), "&aIron Golem"), null, null, null, null})
.register(plugin);
@ -904,23 +912,27 @@ public final class SlimefunItemSetup {
registerArmorSet(categories.armor, SlimefunItems.GILDED_IRON, new ItemStack[] {
SlimefunItems.GILDED_IRON_HELMET, SlimefunItems.GILDED_IRON_CHESTPLATE, SlimefunItems.GILDED_IRON_LEGGINGS, SlimefunItems.GILDED_IRON_BOOTS
}, "GILDED_IRON", false, plugin);
new SlimefunItem(categories.technicalComponents, SlimefunItems.REINFORCED_CLOTH, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {null, SlimefunItems.CLOTH, null, SlimefunItems.CLOTH, SlimefunItems.LEAD_INGOT, SlimefunItems.CLOTH, null, SlimefunItems.CLOTH, null}, new SlimefunItemStack(SlimefunItems.REINFORCED_CLOTH, 2))
.register(plugin);
new SlimefunArmorPiece(categories.armor, SlimefunItems.SCUBA_HELMET, RecipeType.ARMOR_FORGE,
new ItemStack[] {new ItemStack(Material.ORANGE_WOOL), new ItemStack(Material.ORANGE_WOOL), new ItemStack(Material.ORANGE_WOOL), new ItemStack(Material.BLACK_WOOL), new ItemStack(Material.GLASS_PANE), new ItemStack(Material.BLACK_WOOL), null, null, null},
new HazmatArmorPiece(categories.armor, SlimefunItems.SCUBA_HELMET, RecipeType.ARMOR_FORGE,
new ItemStack[] {new ItemStack(Material.ORANGE_WOOL), SlimefunItems.REINFORCED_CLOTH, new ItemStack(Material.ORANGE_WOOL), SlimefunItems.REINFORCED_CLOTH, new ItemStack(Material.GLASS_PANE), SlimefunItems.REINFORCED_CLOTH, null, null, null},
new PotionEffect[] {new PotionEffect(PotionEffectType.WATER_BREATHING, 300, 1)})
.register(plugin);
new SlimefunArmorPiece(categories.armor, SlimefunItems.HAZMAT_CHESTPLATE, RecipeType.ARMOR_FORGE,
new ItemStack[] {new ItemStack(Material.ORANGE_WOOL), null, new ItemStack(Material.ORANGE_WOOL), new ItemStack(Material.ORANGE_WOOL), new ItemStack(Material.ORANGE_WOOL), new ItemStack(Material.ORANGE_WOOL), new ItemStack(Material.BLACK_WOOL), new ItemStack(Material.BLACK_WOOL), new ItemStack(Material.BLACK_WOOL)},
new HazmatArmorPiece(categories.armor, SlimefunItems.HAZMAT_CHESTPLATE, RecipeType.ARMOR_FORGE,
new ItemStack[] {new ItemStack(Material.ORANGE_WOOL), null, new ItemStack(Material.ORANGE_WOOL), SlimefunItems.REINFORCED_CLOTH, SlimefunItems.REINFORCED_CLOTH, SlimefunItems.REINFORCED_CLOTH, new ItemStack(Material.BLACK_WOOL), SlimefunItems.REINFORCED_CLOTH, new ItemStack(Material.BLACK_WOOL)},
new PotionEffect[] {new PotionEffect(PotionEffectType.FIRE_RESISTANCE, 300, 1)})
.register(plugin);
new SlimefunItem(categories.armor, SlimefunItems.HAZMAT_LEGGINGS, RecipeType.ARMOR_FORGE,
new ItemStack[] {new ItemStack(Material.BLACK_WOOL), new ItemStack(Material.BLACK_WOOL), new ItemStack(Material.BLACK_WOOL), new ItemStack(Material.ORANGE_WOOL), null, new ItemStack(Material.ORANGE_WOOL), new ItemStack(Material.ORANGE_WOOL), null, new ItemStack(Material.ORANGE_WOOL)})
new HazmatArmorPiece(categories.armor, SlimefunItems.HAZMAT_LEGGINGS, RecipeType.ARMOR_FORGE,
new ItemStack[] {new ItemStack(Material.BLACK_WOOL), SlimefunItems.REINFORCED_CLOTH, new ItemStack(Material.BLACK_WOOL), SlimefunItems.REINFORCED_CLOTH, null, SlimefunItems.REINFORCED_CLOTH, SlimefunItems.REINFORCED_CLOTH, null, SlimefunItems.REINFORCED_CLOTH}, new PotionEffect[0])
.register(plugin);
new SlimefunItem(categories.armor, SlimefunItems.RUBBER_BOOTS, RecipeType.ARMOR_FORGE,
new ItemStack[] {null, null, null, new ItemStack(Material.BLACK_WOOL), null, new ItemStack(Material.BLACK_WOOL), new ItemStack(Material.BLACK_WOOL), null, new ItemStack(Material.BLACK_WOOL)})
new HazmatArmorPiece(categories.armor, SlimefunItems.HAZMAT_BOOTS, RecipeType.ARMOR_FORGE,
new ItemStack[] {SlimefunItems.REINFORCED_CLOTH, null, SlimefunItems.REINFORCED_CLOTH, SlimefunItems.REINFORCED_CLOTH, null, SlimefunItems.REINFORCED_CLOTH, new ItemStack(Material.BLACK_WOOL), null, new ItemStack(Material.BLACK_WOOL)}, new PotionEffect[0])
.register(plugin);
new SlimefunItem(categories.misc, SlimefunItems.CRUSHED_ORE, RecipeType.ORE_CRUSHER,
@ -1004,12 +1016,12 @@ public final class SlimefunItemSetup {
new TableSaw(categories.basicMachines, SlimefunItems.TABLE_SAW).register(plugin);
}
new SlimefunItem(categories.magicalArmor, SlimefunItems.SLIME_HELMET_STEEL, RecipeType.ARMOR_FORGE,
new ItemStack[] {new ItemStack(Material.SLIME_BALL), SlimefunItems.STEEL_PLATE, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), null, null, null})
new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_HELMET_STEEL, RecipeType.ARMOR_FORGE,
new ItemStack[] {new ItemStack(Material.SLIME_BALL), SlimefunItems.STEEL_PLATE, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), null, null, null}, null)
.register(plugin);
new SlimefunItem(categories.magicalArmor, SlimefunItems.SLIME_CHESTPLATE_STEEL, RecipeType.ARMOR_FORGE,
new ItemStack[] {new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), SlimefunItems.STEEL_PLATE, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL)})
new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_CHESTPLATE_STEEL, RecipeType.ARMOR_FORGE,
new ItemStack[] {new ItemStack(Material.SLIME_BALL), null, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), SlimefunItems.STEEL_PLATE, new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL), new ItemStack(Material.SLIME_BALL)}, null)
.register(plugin);
new SlimefunArmorPiece(categories.magicalArmor, SlimefunItems.SLIME_LEGGINGS_STEEL, RecipeType.ARMOR_FORGE,
@ -2450,6 +2462,10 @@ public final class SlimefunItemSetup {
new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.ENDER_LUMP_3, SlimefunItems.ENDER_RUNE, SlimefunItems.ENDER_LUMP_3, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.MAGIC_LUMP_3})
.register(plugin);
new EnchantmentRune(categories.magicalResources, SlimefunItems.ENCHANTMENT_RUNE, RecipeType.ANCIENT_ALTAR,
new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, SlimefunItems.MAGICAL_GLASS, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.MAGICAL_GLASS, SlimefunItems.LIGHTNING_RUNE, SlimefunItems.MAGICAL_GLASS, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.MAGICAL_GLASS, SlimefunItems.MAGIC_LUMP_3})
.register(plugin);
new InfernalBonemeal(categories.magicalGadgets, SlimefunItems.INFERNAL_BONEMEAL, RecipeType.ANCIENT_ALTAR,
new ItemStack[] {new ItemStack(Material.NETHER_WART), SlimefunItems.EARTH_RUNE, new ItemStack(Material.NETHER_WART), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.BONE_MEAL), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.NETHER_WART), new ItemStack(Material.BLAZE_POWDER), new ItemStack(Material.NETHER_WART)},
new CustomItem(SlimefunItems.INFERNAL_BONEMEAL, 8))
@ -3208,9 +3224,19 @@ public final class SlimefunItemSetup {
}.register(plugin);
new IronGolemAssembler(categories.electricity, SlimefunItems.IRON_GOLEM_ASSEMBLER, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.ADVANCED_CIRCUIT_BOARD, SlimefunItems.BLISTERING_INGOT_3, new ItemStack(Material.IRON_BLOCK), SlimefunItems.ANDROID_MEMORY_CORE, new ItemStack(Material.IRON_BLOCK), SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.CARBONADO_EDGED_CAPACITOR})
.register(plugin);
new WitherAssembler(categories.electricity, SlimefunItems.WITHER_ASSEMBLER, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.BLISTERING_INGOT_3, new ItemStack(Material.NETHER_STAR), SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.ANDROID_MEMORY_CORE, SlimefunItems.WITHER_PROOF_OBSIDIAN, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.CARBONADO_EDGED_CAPACITOR})
.register(plugin);
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) {
new TapeMeasure(categories.usefulItems, SlimefunItems.TAPE_MEASURE, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.SILICON, new ItemStack(Material.YELLOW_DYE), SlimefunItems.SILICON, new ItemStack(Material.YELLOW_DYE), new ItemStack(Material.STRING), new ItemStack(Material.YELLOW_DYE), SlimefunItems.GILDED_IRON, new ItemStack(Material.YELLOW_DYE), SlimefunItems.SILICON})
.register(plugin);
}
}
private static void registerArmorSet(Category category, ItemStack baseComponent, ItemStack[] items, String idSyntax, boolean vanilla, SlimefunAddon addon) {

View File

@ -14,6 +14,7 @@ import org.bukkit.potion.PotionEffectType;
import io.github.thebusybiscuit.slimefun4.api.items.HashedArmorpiece;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType;
import io.github.thebusybiscuit.slimefun4.core.attributes.Radioactive;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
@ -63,7 +64,7 @@ public class ArmorTask implements Runnable {
checkForSolarHelmet(p);
}
checkForRadiation(p);
checkForRadiation(p, profile);
});
}
}
@ -125,18 +126,17 @@ public class ArmorTask implements Runnable {
return (world.getTime() < 12300 || world.getTime() > 23850) && p.getEyeLocation().getBlock().getLightFromSky() == 15;
}
private void checkForRadiation(Player p) {
// Check for a Hazmat Suit
if (!SlimefunUtils.isItemSimilar(p.getInventory().getHelmet(), SlimefunItems.SCUBA_HELMET, true) || !SlimefunUtils.isItemSimilar(p.getInventory().getChestplate(), SlimefunItems.HAZMAT_CHESTPLATE, true) || !SlimefunUtils.isItemSimilar(p.getInventory().getLeggings(), SlimefunItems.HAZMAT_LEGGINGS, true) || !SlimefunUtils.isItemSimilar(p.getInventory().getBoots(), SlimefunItems.RUBBER_BOOTS, true)) {
private void checkForRadiation(Player p, PlayerProfile profile) {
if (!profile.hasFullProtectionAgainst(ProtectionType.RADIATION)) {
for (ItemStack item : p.getInventory()) {
if (isRadioactive(p, item)) {
if (checkAndApplyRadiation(p, item)) {
break;
}
}
}
}
private boolean isRadioactive(Player p, ItemStack item) {
private boolean checkAndApplyRadiation(Player p, ItemStack item) {
for (SlimefunItem radioactiveItem : SlimefunPlugin.getRegistry().getRadioactiveItems()) {
if (radioactiveItem.isItem(item) && Slimefun.isEnabled(p, radioactiveItem, true)) {
// If the item is enabled in the world, then make radioactivity do its job
@ -153,5 +153,4 @@ public class ArmorTask implements Runnable {
return false;
}
}

View File

@ -150,7 +150,7 @@ public final class SlimefunItems {
public static final SlimefunItemStack SCUBA_HELMET = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.SCUBA_HELMET;
public static final SlimefunItemStack HAZMATSUIT_CHESTPLATE = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.HAZMAT_CHESTPLATE;
public static final SlimefunItemStack HAZMATSUIT_LEGGINGS = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.HAZMAT_LEGGINGS;
public static final SlimefunItemStack RUBBER_BOOTS = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.RUBBER_BOOTS;
public static final SlimefunItemStack RUBBER_BOOTS = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.HAZMAT_BOOTS;
public static final SlimefunItemStack GILDED_IRON_HELMET = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GILDED_IRON_HELMET;
public static final SlimefunItemStack GILDED_IRON_CHESTPLATE = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GILDED_IRON_CHESTPLATE;
public static final SlimefunItemStack GILDED_IRON_LEGGINGS = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GILDED_IRON_LEGGINGS;

View File

@ -16,7 +16,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Block;
@ -151,40 +150,8 @@ public class BlockStorage {
FileConfiguration cfg = YamlConfiguration.loadConfiguration(file);
for (String key : cfg.getKeys(false)) {
Location l = deserializeLocation(key);
String chunkString = locationToChunkString(l);
try {
totalBlocks++;
String json = cfg.getString(key);
Config blockInfo = parseBlockInfo(l, json);
if (blockInfo != null && blockInfo.contains("id")) {
if (storage.containsKey(l)) {
// It should not be possible to have two blocks on the same location. Ignore the
// new entry if a block is already present and print an error to the console.
Slimefun.getLogger().log(Level.INFO, "Ignoring duplicate block @ {0}, {1}, {2}", new Object[] { l.getBlockX(), l.getBlockY(), l.getBlockZ() });
Slimefun.getLogger().log(Level.INFO, "New: {0} | Old: {1}", new Object[] { key, serializeBlockInfo(storage.get(l)) });
continue;
}
storage.put(l, blockInfo);
if (SlimefunPlugin.getRegistry().getTickerBlocks().contains(file.getName().replace(".sfb", ""))) {
Set<Location> locations = SlimefunPlugin.getRegistry().getActiveTickers().getOrDefault(chunkString, new HashSet<>());
locations.add(l);
SlimefunPlugin.getRegistry().getActiveTickers().put(chunkString, locations);
if (!SlimefunPlugin.getRegistry().getActiveChunks().contains(chunkString)) {
SlimefunPlugin.getRegistry().getActiveChunks().add(chunkString);
}
}
}
}
catch (Exception x) {
Slimefun.getLogger().log(Level.WARNING, x, () -> "Failed to load " + file.getName() + '(' + key + ") for Slimefun " + SlimefunPlugin.getVersion());
}
loadBlock(file, cfg, key);
totalBlocks++;
}
done++;
@ -202,6 +169,48 @@ public class BlockStorage {
}
}
private void loadBlock(File file, FileConfiguration cfg, String key) {
Location l = deserializeLocation(key);
if (l == null) {
// That location was malformed, we will skip this one
return;
}
try {
String chunkString = locationToChunkString(l);
String json = cfg.getString(key);
Config blockInfo = parseBlockInfo(l, json);
if (blockInfo != null && blockInfo.contains("id")) {
if (storage.containsKey(l)) {
// It should not be possible to have two blocks on the same location. Ignore the
// new entry if a block is already present and print an error to the console.
if (SlimefunPlugin.getRegistry().logDuplicateBlockEntries()) {
Slimefun.getLogger().log(Level.INFO, "Ignoring duplicate block @ {0}, {1}, {2} ({3} -> {4})", new Object[] { l.getBlockX(), l.getBlockY(), l.getBlockZ(), blockInfo.getString("id"), storage.get(l).getString("id") });
}
return;
}
storage.put(l, blockInfo);
if (SlimefunPlugin.getRegistry().getTickerBlocks().contains(file.getName().replace(".sfb", ""))) {
Set<Location> locations = SlimefunPlugin.getRegistry().getActiveTickers().getOrDefault(chunkString, new HashSet<>());
locations.add(l);
SlimefunPlugin.getRegistry().getActiveTickers().put(chunkString, locations);
if (!SlimefunPlugin.getRegistry().getActiveChunks().contains(chunkString)) {
SlimefunPlugin.getRegistry().getActiveChunks().add(chunkString);
}
}
}
}
catch (Exception x) {
Slimefun.getLogger().log(Level.WARNING, x, () -> "Failed to load " + file.getName() + '(' + key + ") for Slimefun " + SlimefunPlugin.getVersion());
}
}
private void loadChunks() {
File chunks = new File(PATH_CHUNKS + "chunks.sfc");
@ -211,7 +220,8 @@ public class BlockStorage {
for (String key : cfg.getKeys(false)) {
try {
if (world.getName().equals(PatternUtils.SEMICOLON.split(key)[0])) {
SlimefunPlugin.getRegistry().getChunks().put(key, new BlockInfoConfig(parseJSON(cfg.getString(key))));
BlockInfoConfig data = new BlockInfoConfig(parseJSON(cfg.getString(key)));
SlimefunPlugin.getRegistry().getChunks().put(key, data);
}
}
catch (Exception x) {
@ -381,6 +391,7 @@ public class BlockStorage {
*
* @param block
* the block to retrieve the ItemStack from
*
* @return the SlimefunItem's ItemStack corresponding to the block if it has one, otherwise null
*
* @since 4.0
@ -424,6 +435,7 @@ public class BlockStorage {
map.put(entry.getKey(), entry.getValue().getAsString());
}
}
return map;
}
@ -530,12 +542,14 @@ public class BlockStorage {
}
else if (!storage.hasInventory(l)) {
File file = new File(PATH_INVENTORIES + serializeLocation(l) + ".sfi");
BlockMenuPreset preset = BlockMenuPreset.getPreset(id);
if (file.exists()) {
storage.inventories.put(l, new BlockMenu(BlockMenuPreset.getPreset(id), l, new io.github.thebusybiscuit.cscorelib2.config.Config(file)));
BlockMenu inventory = new BlockMenu(preset, l, new io.github.thebusybiscuit.cscorelib2.config.Config(file));
storage.inventories.put(l, inventory);
}
else {
storage.loadInventory(l, BlockMenuPreset.getPreset(id));
storage.loadInventory(l, preset);
}
}
}
@ -732,15 +746,11 @@ public class BlockStorage {
}
public static Set<String> getTickingChunks() {
return new HashSet<>(SlimefunPlugin.getRegistry().getActiveChunks());
}
public static Set<Location> getTickingLocations(Chunk chunk) {
return getTickingLocations(chunk.toString());
return SlimefunPlugin.getRegistry().getActiveChunks();
}
public static Set<Location> getTickingLocations(String chunk) {
return new HashSet<>(SlimefunPlugin.getRegistry().getActiveTickers().get(chunk));
return SlimefunPlugin.getRegistry().getActiveTickers().getOrDefault(chunk, new HashSet<>());
}
public BlockMenu loadInventory(Location l, BlockMenuPreset preset) {
@ -769,7 +779,8 @@ public class BlockStorage {
}
public void loadUniversalInventory(BlockMenuPreset preset) {
SlimefunPlugin.getRegistry().getUniversalInventories().put(preset.getID(), new UniversalBlockMenu(preset));
UniversalBlockMenu inventory = new UniversalBlockMenu(preset);
SlimefunPlugin.getRegistry().getUniversalInventories().put(preset.getID(), inventory);
}
public void clearInventory(Location l) {

View File

@ -269,5 +269,4 @@ public class SlimefunItemStack extends CustomItem {
throw new IllegalArgumentException("The provided texture for Item \"" + id + "\" does not seem to be a valid texture String!");
}
}
}

View File

@ -16,6 +16,7 @@ options:
legacy-ore-grinder: true
language: en
enable-translations: true
log-duplicate-block-entries: true
guide:
default-view-book: false

View File

@ -1,66 +1,19 @@
---
android:
scripts:
already-uploaded: "&4Dieses Skript wurde bereits hochgeladen."
editor: Skripteditor
enter-name:
-
- "&eBitte gebe einen Namen für dein Skript ins Chatfenster ein"
instructions:
ATTACK_ANIMALS: "&4Angreifen &c(Nur Tiere)"
ATTACK_ANIMALS_ADULT: "&4Angreifen &c(Nur ausgewachsene Tiere)"
ATTACK_MOBS: "&4Angreifen &c(Nur Monster)"
ATTACK_MOBS_ANIMALS: "&4Angreifen &c(Monster & Tiere)"
CATCH_FISH: "&bAngeln"
CHOP_TREE: "&cBaum fällen und nachpflanzen"
DIG_DOWN: "&bGrabe nach unten"
DIG_FORWARD: "&bGrabe vorwärts"
DIG_UP: "&bGrabe nach oben"
FARM_DOWN: "&bErnten und Nachpflanzen &7(Unterer Block)"
FARM_EXOTIC_DOWN: "&bErnten und Nachpflanzen (Fortgeschritten und unterer Block)"
FARM_EXOTIC_FORWARD: "&bErnten und Nachpflanzen (Fortgeschritten)"
FARM_FORWARD: "&bErnten und Nachpflanzen"
GO_DOWN: "&7Gehe nach unten"
GO_FORWARD: "&7Gehe vorwärts"
GO_UP: "&7Gehe nach oben"
INTERFACE_FUEL: "&cTreibstoff aus dem vorliegenden Interface nehmen"
INTERFACE_ITEMS: "&9Items ins vorliegende Interface bewegen"
MOVE_AND_DIG_DOWN: "&bGehe & Grabe nach unten"
MOVE_AND_DIG_FORWARD: "&bGehe & Grabe vorwärts"
MOVE_AND_DIG_UP: "&bGehe & Grabe nach oben"
REPEAT: "&9Neubeginn des Skripts"
START: "&2Start des Skripts"
TURN_LEFT: "&7Drehung nach links"
TURN_RIGHT: "&7Drehung nach rechts"
WAIT: "&eWarte 0.5 Sekunden"
rating:
already: "&4Du hast dieses Skript bereits bewertet!"
own: "&4Du kannst nicht dein eigenes Skript bewerten!"
uploaded:
- "&bLade dein Skript hoch..."
- "&aDein Skript wurde erfolgreich hochgeladen!"
started: "&7Dein Android hat sein Skript fortgesetzt"
stopped: "&7Dein Android hat sein Skript pausiert"
anvil:
not-working: "&4Items von Slimefun können nicht in einem Amboss verwendet werden!"
backpack:
already-open: "&cDieser Rucksack wird derzeit von jemand anderem benutzt!"
no-stack: "&cRucksäcke dürfen nicht gestapelt werden"
commands:
help: Zeigt diesen Infotext an
cheat: Ermöglicht das Cheaten von Items
give: Gibt jemandem ein bestimmtes Item
guide: Gibt dir das Slimefun-Handbuch
help: Zeigt diesen Infotext an
timings: Zeigt einige Informationen über die Performance
teleporter: Erlaubt es dir Wegpunkte anderer Spieler anzusehen
versions: Eine Liste aller installierter Addons
search: Durchsucht dein Slimefun-Handbuch nach einem Begriff
open_guide: Öffnet das Slimefun-Handbuch
stats: Zeigt einige Statistiken über einen Spieler
research:
description: Verändert den Erfahrungsgrad eines Spielers
reset: "&cDu hast soeben %player%'s Erfahrungsgrad zurückgesetzt"
reset-target: "&cDein Erfahrungsgrad wurde zurückgesetzt"
search: Durchsucht dein Slimefun-Handbuch nach einem Begriff
stats: Zeigt einige Statistiken über einen Spieler
teleporter: Erlaubt es dir Wegpunkte anderer Spieler anzusehen
timings: Zeigt einige Informationen über die Performance
versions: Eine Liste aller installierter Addons
backpack:
description: Gibt eine Kopie eines existierenden Rucksacks
invalid-id: "&4Die id muss eine nicht-negative ganze Zahl sein!"
@ -68,184 +21,120 @@ commands:
backpack-does-not-exist: "&4Der angegebene Rucksack konnte nicht gefunden werden!"
restored-backpack-given: "&aDein Rucksack wurde erfolgreich wiederhergestellt
und deinem Inventar hinzugefügt!"
gps:
deathpoint: "&4Todespunkt &7%date%"
geo:
scan-required: "&4GEO-Scan benötigt! &cScanne diesen Chunk mit einem GEO-Scanner!"
insufficient-complexity:
- "&4Unzureichende Komplexität deines GPS-Netzwerkes! Folgende Komplexität wird
benötigt: &c%complexity%"
- "&4a) Vielleicht hast du gar kein GPS-Netzwerk"
- "&4b) Oder dein GPS-Netzwerk ist nicht komplex genug"
waypoint:
added: "&aEin neuer Wegpunkt wurde hinzugefügt"
max: "&4Du hast die maximale Anzahl an Wegpunkten erreicht"
new: "&eBitte gebe ins Chatfenser einen Namen für deinen Wegpunkt ein. &7(Farbcodes
werden unterstützt!)"
guide:
back:
guide: Gehe zurück zum Slimefun-Handbuch
settings: Gehe zurück zu den Einstellungen
title: Zurück
search:
message: "&bWonach möchtest du suchen?"
name: "&7Suche..."
tooltip: "&bKlicke um die Suche zu starten"
inventory: 'Suche nach: %item%'
lore:
- "&bWonach möchtest du suchen?"
- "&7Gib den Begriff, nach dem du suchen willst, in das Chatfenster ein"
cheat:
no-multiblocks: "&4Multiblöcke müssen gebaut werden! Du kannst dir diese nicht
geben."
credits:
commit: Beitrag
commits: Beiträge
profile-link: Klick um mich auf GitHub zu sehen
roles:
developer: "&6Entwickler"
resourcepack: "&cRessourcenpaket-Designer"
translator: "&9Übersetzer"
wiki: "&3Wiki-Editor"
languages:
updated: "&aFolgende Sprache wurde ausgewählt: &b%lang%"
translations:
name: "&aFehlt etwas?"
lore: Klicke um eine Übersetzung hinzuzufügen
select: Klicke hier um diese Sprache auszuwählen
select-default: Klicke hier um die Standardsprache auszuwählen
selected-language: 'Aktuell ausgewählt:'
translations:
lore: Klicke um eine Übersetzung hinzuzufügen
name: "&aFehlt etwas?"
updated: "&aFolgende Sprache wurde ausgewählt: &b%lang%"
title:
main: Slimefun-Handbuch
settings: Einstellungen & Infos
languages: Wähle deine bevorzugte Sprache
credits: 'Slimefun4: Mitwirkende'
wiki: Slimefun4-Wiki
addons: Addons für Slimefun4
bugs: Fehlermeldungen
source: Quellcode
credits:
commit: Beitrag
commits: Beiträge
roles:
developer: "&6Entwickler"
wiki: "&3Wiki-Editor"
resourcepack: "&cRessourcenpaket-Designer"
translator: "&9Übersetzer"
profile-link: Klick um mich auf GitHub zu sehen
pages:
previous: Vorherige Seite
next: Nächste Seite
tooltips:
open-category: Klicke zum Öffnen
versions-notice: Dies ist sehr wichtig bei Fehlermeldungen!
wiki: Besuche das offizielle Slimefun-Wiki
recipes:
machine: Rezepte dieser Maschine
miner: Ressourcen, die mit dieser Maschine gewonnen werden können
generator: Mögliche Treibstoffquellen
gold-pan: Ressourcen, die hiermit gewonnen werden können
back:
title: Zurück
guide: Gehe zurück zum Slimefun-Handbuch
settings: Gehe zurück zu den Einstellungen
locked: GESPERRT
locked-category:
- Um diese Kategorie freizuschalten,
- müssen zuerst sämtliche Items der
- folgenden Kategorien freigeschaltet werden
pages:
next: Nächste Seite
previous: Vorherige Seite
search:
inventory: 'Suche nach: %item%'
lore:
- "&bWonach möchtest du suchen?"
- "&7Gib den Begriff, nach dem du suchen willst, in das Chatfenster ein"
message: "&bWonach möchtest du suchen?"
name: "&7Suche..."
tooltip: "&bKlicke um die Suche zu starten"
title:
addons: Addons für Slimefun4
bugs: Fehlermeldungen
credits: 'Slimefun4: Mitwirkende'
languages: Wähle deine bevorzugte Sprache
main: Slimefun-Handbuch
settings: Einstellungen & Infos
source: Quellcode
wiki: Slimefun4-Wiki
tooltips:
open-category: Klicke zum Öffnen
recipes:
generator: Mögliche Treibstoffquellen
gold-pan: Ressourcen, die hiermit gewonnen werden können
machine: Rezepte dieser Maschine
miner: Ressourcen, die mit dieser Maschine gewonnen werden können
versions-notice: Dies ist sehr wichtig bei Fehlermeldungen!
wiki: Besuche das offizielle Slimefun-Wiki
inventory:
no-access: "&4Du kannst nicht auf diesen Block zugreifen"
languages:
af: Afrikaans
ar: Arabisch
be: Belarusisch
bg: Bulgarisch
cs: Tschechisch
da: Dänisch
de: Deutsch
default: Server-Standard
el: Griechisch
en: Englisch
es: Spanisch
fa: Persisch
fi: Finnisch
fr: Französisch
he: Hebräisch
hr: Kroatisch
hu: Ungarisch
id: Indonesisch
it: Italienisch
ja: Japanisch
ko: Koreanisch
lv: Lettisch
mk: Mazedonisch
ms: Malaiisch
nl: Niederländisch
'no': Norwegisch
pl: Polnisch
pt: Portugiesisch (Portugal)
pt-BR: Portugiesisch (Brasilien)
ro: Rumänisch
ru: Russisch
sk: Slowakisch
sr: Serbisch
sv: Schwedisch
th: Thailändisch
tr: Türkisch
uk: Ukrainisch
vi: Vietnamesisch
zh-CN: Chinesisch (China)
zh-TW: Chinesisch (Taiwan)
machines:
ANCIENT_ALTAR:
not-enough-pedestals: "&4Es fehlen einige Sockel des Altars &c(%pedestals% / 8)"
unknown-catalyst: "&4Unbekannter Katalysator!"
unknown-recipe: "&4Unbekanntes Rezept!"
ANCIENT_PEDESTAL:
obstructed: "&4Der Sockel wurde blockiert! &cBitte entferne den Block über jedem
jedem Sockel!"
CARGO_NODES:
must-be-placed: "&4Dieser Block muss an die Seite einer Maschine oder Kiste platziert
werden!"
ELEVATOR:
click-to-teleport: "&eKlicke hier &7um zu dieser Etage zu teleportieren:"
current-floor: "&eDeine aktuelle Etage:"
enter-name: "&7Bitte gebe ins Chatfenser einen Namen für diese Etage ein. &r(Farbcodes
werden unterstützt!)"
named: '&2Diese Etage wurde erfolgreich &r"%floor%&r" &2genannt'
no-destinations: "&4Es konnten keine weiteren Etagen gefunden werden"
pick-a-floor: "&3- Wähle eine Etage -"
full-inventory: "&eDieses Inventar ist bereits voll!"
GPS_CONTROL_PANEL:
title: GPS - Kontrolltafel
transmitters: Satelliten-Übersicht
waypoints: Wegpunkte-Übersicht
HOLOGRAM_PROJECTOR:
enter-text: "&7Bitte gebe ins Chatfenser einen Text für dieses Hologram ein. &r(Farbcodes
werden unterstützt!)"
inventory-title: Hologrammeditor
ignition-chamber-no-flint: "&cAlle Feuerzeuge wurden aufgebraucht!"
in-use: "&cDiese Maschine wird derzeit von einem anderen Spieler verwendet."
pattern-not-found: "&eEs tut mir leid, aber ich konnte kein passendes Rezept finden."
TELEPORTER:
cancelled: "&4Teleportation abgebrochen!"
gui:
time: Voraussichtliche Dauer
title: Deine Wegpunkte
tooltip: Klicke zum teleportieren
invulnerability: "&b&lDu bist nun für 30 Sekunden unverwundbar!"
teleported: "&3Erfolgreich teleportiert!"
teleporting: "&3Du wirst teleportiert..."
unknown-material: "&eEs tut mir leid, aber ich erkenne das Item in meinem Werfer
nicht, probier ein anderes Item aus."
wrong-item: "&eEs tut mir leid, aber ich erkenne das Item in deiner Hand nicht,
probier ein anderes Item aus."
INDUSTRIAL_MINER:
no-fuel: "&cDein Industrial Miner hat keinen Treibstoff mehr! Platziere den benötigten
Treibstoff in die Kiste."
piston-facing: "&cEinIndustrial Miner erfordert Kolben, die nach oben zeigen!"
piston-space: "&cDie Blöcke über den Kolben müssen leer bleiben!"
destroyed: "&cDein Industrial Miner scheint zerstört worden zu sein."
already-running: "&cDieser Industrial Miner wird bereits verwendet!"
full-chest: "&cDie Kiste deines Industrial Miner ist vollgelaufen!"
no-permission: "&4Du scheinst nicht die benötigten Rechte zu haben, um in diesem
Gebiet einen Industrial Miner zu verwenden."
finished: "&eDein Industrial Miner ist fertig! Es wurde(n) insgesamt %ores% Erz(e)
gefunden!"
messages:
cannot-place: "&cDu kannst hier keine Blöcke platzieren!"
diet-cookie: "&eDu beginnst dich sehr leicht zu fühlen..."
not-researched: "&4Du hast diesen Gegenstand noch nicht freigeschaltet!"
not-enough-xp: "&4Du hast nicht genügend Erfahrungspunkte, um dies freizuschalten"
unlocked: '&bDu hast folgenden Erfahrungsgrad gewonnen: &7"%research%"'
only-players: "&4Dieser Befehl ist nur für Spieler"
unknown-player: "&4Unbekannter Spieler: &c%player%"
no-permission: "&4Du hast nicht die benötigten Rechte hierfür"
usage: "&4Korrekte Schreibweise: &c%usage%"
not-online: "&4%player% &cist derzeit nicht online!"
not-valid-item: "&4%item% &cist kein gültiges Item!"
not-valid-amount: "&4%amount% &cist keine gültige Anzahl! Sie muss höher als 0 sein!"
given-item: '&bDir wurde &a%amount% &7mal "%item%&7" gegeben'
give-item: '&bDu hast %player% &a%amount% &7"%item%&7" gegeben'
not-valid-research: "&4%research% &cist kein gültiger Erfahrungsgrad!"
give-research: '&bDu hast %player% den Erfahrungsgrad &7"%research%&7" vergeben'
hungry: "&cDu bist zu hungrig, um dies zu tun!"
mode-change: "&bDer Modus von deinem %device% wurde geändert zu: &9%mode%"
disabled-in-world: "&4&lDieses Item wurde in dieser Welt deaktiviert!"
disabled-item: "&4&lDieses Item wurde von einem Server-Administrator deaktiviert!"
no-tome-yourself: "&cDu kannst dieses Item nicht an dir selbst anwenden..."
multimeter: "&bGespeicherte Energie: &3%stored% &b/ &3%capacity%"
talisman:
anvil: "&a&oDein Talisman hat dein Werkzeug vor dem Zerfall gerettet"
miner: "&a&oDein Talisman hat soeben die Drops verdoppelt"
hunter: "&a&oDein Talisman hat soeben die Drops verdoppelt"
lava: "&a&oDein Talisman hat dich vor dem Verbrennen gerettet"
water: "&a&oDein Talisman hat dich vor dem Ertrinken gerettet"
angel: "&a&oDein Talisman hat dich davor bewahrt Fallschaden zu erleiden"
fire: "&a&oDein Talisman hat dich vor dem Verbrennen gerettet"
magician: "&a&oDein Talisman hat dir eine zusätzliche Verzauberung verliehen"
traveller: "&a&oDein Talisman hat dir einen Geschwindigkeitsboost gegeben"
warrior: "&a&oDein Talisman hat dir einen temporären Stärkebonus gegeben"
knight: "&a&oDein Talisman hat dir 5 Sekunden Regeneration gegeben"
whirlwind: "&a&oDein Talisman hat soeben ein Projektil reflektiert"
wizard: "&a&oDein Talisman hat dein Glück-Level erhöht aber möglicherweise das
Level einer anderen Verzauberung vermindert"
soulbound-rune:
fail: "&cDu kannst nicht mehrere Items auf einmal an deine Seele binden"
success: "&aDu hast dieses Item erfolgreich an deine Seele gebunden! Solltest
du sterben, wirst du es nun behalten."
research:
start: "&7Mysteriöse Worte flüstert man dir in dein Ohr!"
progress: "&7Du beginnst über &b%research% &7nachzudenken &e(%progress%)"
fire-extinguish: "&7Das Feuer wurde erfolgreich gelöscht"
cannot-place: "&cDu kannst hier keine Blöcke platzieren!"
no-pvp: "&cDu kannst andere Spieler hier nicht verletzen!"
radiation: "&4Du wurdest radioaktiver Strahlung ausgesetzt! &cZiehe einen vollständigen
Hazmat Suit an oder werde das radioaktive Item schnleunigst los!"
opening-guide: "&bÖffne dein Handbuch, dies kann eventuell ein paar Sekunden dauern..."
opening-backpack: "&bÖffne deinen Rucksack, dies kann eventuell ein paar Sekunden
dauern..."
no-iron-golem-heal: "&cDas ist kein Eisenbarren. Du kannst dieses Item nicht verwenden
um Eisengolems zu reparieren!"
link-prompt: "&eKlicke hier:"
diet-cookie: "&eDu beginnst dich sehr leicht zu fühlen..."
fortune-cookie:
- "&7Hilfe, ich bin in einer Glückskeks-Fabrik gefangen!"
- "&7Morgen könntest du sterben... durch einen Creeper"
@ -259,56 +148,184 @@ messages:
- "&742. Die Antwort ist 42."
- "&7Ein Walshy am Tag, hält die Sorgen fern. (Insiderwitz)"
- "&7Grabe niemals direkt nach unten!"
give-item: '&bDu hast %player% &a%amount% &7"%item%&7" gegeben'
given-item: '&bDir wurde &a%amount% &7mal "%item%&7" gegeben'
give-research: '&bDu hast %player% den Erfahrungsgrad &7"%research%&7" vergeben'
hungry: "&cDu bist zu hungrig, um dies zu tun!"
link-prompt: "&eKlicke hier:"
mode-change: "&bDer Modus von deinem %device% wurde geändert zu: &9%mode%"
multimeter: "&bGespeicherte Energie: &3%stored% &b/ &3%capacity%"
no-iron-golem-heal: "&cDas ist kein Eisenbarren. Du kannst dieses Item nicht verwenden
um Eisengolems zu reparieren!"
no-permission: "&4Du hast nicht die benötigten Rechte hierfür"
no-pvp: "&cDu kannst andere Spieler hier nicht verletzen!"
not-enough-xp: "&4Du hast nicht genügend Erfahrungspunkte, um dies freizuschalten"
no-tome-yourself: "&cDu kannst dieses Item nicht an dir selbst anwenden..."
not-online: "&4%player% &cist derzeit nicht online!"
not-researched: "&4Du hast diesen Gegenstand noch nicht freigeschaltet!"
not-valid-amount: "&4%amount% &cist keine gültige Anzahl! Sie muss höher als 0 sein!"
not-valid-item: "&4%item% &cist kein gültiges Item!"
not-valid-research: "&4%research% &cist kein gültiger Erfahrungsgrad!"
only-players: "&4Dieser Befehl ist nur für Spieler"
opening-backpack: "&bÖffne deinen Rucksack, dies kann eventuell ein paar Sekunden
dauern..."
opening-guide: "&bÖffne dein Handbuch, dies kann eventuell ein paar Sekunden dauern..."
radiation: "&4Du wurdest radioaktiver Strahlung ausgesetzt! &cZiehe einen vollständigen
Hazmat Suit an oder werde das radioaktive Item schnleunigst los!"
research:
progress: "&7Du beginnst über &b%research% &7nachzudenken &e(%progress%)"
start: "&7Mysteriöse Worte flüstert man dir in dein Ohr!"
soulbound-rune:
fail: "&cDu kannst nicht mehrere Items auf einmal an deine Seele binden"
success: "&aDu hast dieses Item erfolgreich an deine Seele gebunden! Solltest
du sterben, wirst du es nun behalten."
talisman:
angel: "&a&oDein Talisman hat dich davor bewahrt Fallschaden zu erleiden"
anvil: "&a&oDein Talisman hat dein Werkzeug vor dem Zerfall gerettet"
fire: "&a&oDein Talisman hat dich vor dem Verbrennen gerettet"
hunter: "&a&oDein Talisman hat soeben die Drops verdoppelt"
knight: "&a&oDein Talisman hat dir 5 Sekunden Regeneration gegeben"
lava: "&a&oDein Talisman hat dich vor dem Verbrennen gerettet"
magician: "&a&oDein Talisman hat dir eine zusätzliche Verzauberung verliehen"
miner: "&a&oDein Talisman hat soeben die Drops verdoppelt"
traveller: "&a&oDein Talisman hat dir einen Geschwindigkeitsboost gegeben"
warrior: "&a&oDein Talisman hat dir einen temporären Stärkebonus gegeben"
water: "&a&oDein Talisman hat dich vor dem Ertrinken gerettet"
whirlwind: "&a&oDein Talisman hat soeben ein Projektil reflektiert"
wizard: "&a&oDein Talisman hat dein Glück-Level erhöht aber möglicherweise das
Level einer anderen Verzauberung vermindert"
unknown-player: "&4Unbekannter Spieler: &c%player%"
unlocked: '&bDu hast folgenden Erfahrungsgrad gewonnen: &7"%research%"'
usage: "&4Korrekte Schreibweise: &c%usage%"
miner:
no-ores: "&eIch konnte leider keine Erze in der Nähe finden!"
- "&7Das ist nur ein Kratzer!"
- "&7Always look on the bright side of life!"
- "&7Ist das jetzt ein Keks, Cookie oder ein Biscuit?"
- "&7Jetzt auch zuckerfrei!"
piglin-barter: "&4Du kannst Piglins keine Slimefun-Gegenständen anbieten!"
enchantment-rune:
fail: "&cDieser Gegenstand kann nicht verzaubert werden"
no-enchantment: "&cEs konnten keine gültigen Verzauberungen für diesen Gegenstand
gefunden werden"
success: "&aDieser Gegenstand wurde erfolgreich mit einer zufälligen Verzauberung
aufgebessert!"
tape-measure:
no-anchor: "&cDu musst zuerst einen Ankerpunkt setzen bevor du messen kannst!"
wrong-world: "&cDein Ankerpunkt scheint sich in einer anderen Dimension zu befinden!"
distance: "&7Messung erfolgreich. &eDistanz: %distance%"
anchor-set: "&aErfolgreich den Ankerpunkt gesetzt:&e %anchor%"
machines:
pattern-not-found: "&eEs tut mir leid, aber ich konnte kein passendes Rezept finden."
unknown-material: "&eEs tut mir leid, aber ich erkenne das Item in meinem Werfer
nicht, probier ein anderes Item aus."
wrong-item: "&eEs tut mir leid, aber ich erkenne das Item in deiner Hand nicht,
probier ein anderes Item aus."
full-inventory: "&eDieses Inventar ist bereits voll!"
in-use: "&cDiese Maschine wird derzeit von einem anderen Spieler verwendet."
ignition-chamber-no-flint: "&cAlle Feuerzeuge wurden aufgebraucht!"
ANCIENT_ALTAR:
not-enough-pedestals: "&4Es fehlen einige Sockel des Altars &c(%pedestals% / 8)"
unknown-catalyst: "&4Unbekannter Katalysator!"
unknown-recipe: "&4Unbekanntes Rezept!"
ANCIENT_PEDESTAL:
obstructed: "&4Der Sockel wurde blockiert! &cBitte entferne den Block über jedem
jedem Sockel!"
HOLOGRAM_PROJECTOR:
enter-text: "&7Bitte gebe ins Chatfenser einen Text für dieses Hologram ein. &r(Farbcodes
werden unterstützt!)"
inventory-title: Hologrammeditor
ELEVATOR:
no-destinations: "&4Es konnten keine weiteren Etagen gefunden werden"
pick-a-floor: "&3- Wähle eine Etage -"
current-floor: "&eDeine aktuelle Etage:"
click-to-teleport: "&eKlicke hier &7um zu dieser Etage zu teleportieren:"
enter-name: "&7Bitte gebe ins Chatfenser einen Namen für diese Etage ein. &r(Farbcodes
werden unterstützt!)"
named: '&2Diese Etage wurde erfolgreich &r"%floor%&r" &2genannt'
TELEPORTER:
teleporting: "&3Du wirst teleportiert..."
teleported: "&3Erfolgreich teleportiert!"
cancelled: "&4Teleportation abgebrochen!"
invulnerability: "&b&lDu bist nun für 30 Sekunden unverwundbar!"
gui:
title: Deine Wegpunkte
tooltip: Klicke zum teleportieren
time: Voraussichtliche Dauer
CARGO_NODES:
must-be-placed: "&4Dieser Block muss an die Seite einer Maschine oder Kiste platziert
werden!"
GPS_CONTROL_PANEL:
title: GPS - Kontrolltafel
transmitters: Satelliten-Übersicht
waypoints: Wegpunkte-Übersicht
INDUSTRIAL_MINER:
no-fuel: "&cDein Industrial Miner hat keinen Treibstoff mehr! Platziere den benötigten
Treibstoff in die Kiste."
piston-facing: "&cEinIndustrial Miner erfordert Kolben, die nach oben zeigen!"
piston-space: "&cDie Blöcke über den Kolben müssen leer bleiben!"
destroyed: "&cDein Industrial Miner scheint zerstört worden zu sein."
already-running: "&cDieser Industrial Miner wird bereits verwendet!"
full-chest: "&cDie Kiste deines Industrial Miner ist vollgelaufen!"
no-permission: "&4Du scheinst nicht die benötigten Rechte zu haben, um in diesem
Gebiet einen Industrial Miner zu verwenden."
finished: "&eDein Industrial Miner ist fertig! Es wurde(n) insgesamt %ores% Erz(e)
gefunden!"
anvil:
not-working: "&4Items von Slimefun können nicht in einem Amboss verwendet werden!"
backpack:
already-open: "&cDieser Rucksack wird derzeit von jemand anderem benutzt!"
no-stack: "&cRucksäcke dürfen nicht gestapelt werden"
workbench:
not-enhanced: "&4Dieses Item kann nicht in einer normalen Werkbank genutzt werden"
gps:
deathpoint: "&4Todespunkt &7%date%"
waypoint:
new: "&eBitte gebe ins Chatfenser einen Namen für deinen Wegpunkt ein. &7(Farbcodes
werden unterstützt!)"
added: "&aEin neuer Wegpunkt wurde hinzugefügt"
max: "&4Du hast die maximale Anzahl an Wegpunkten erreicht"
insufficient-complexity:
- "&4Unzureichende Komplexität deines GPS-Netzwerkes! Folgende Komplexität wird
benötigt: &c%complexity%"
- "&4a) Vielleicht hast du gar kein GPS-Netzwerk"
- "&4b) Oder dein GPS-Netzwerk ist nicht komplex genug"
geo:
scan-required: "&4GEO-Scan benötigt! &cScanne diesen Chunk mit einem GEO-Scanner!"
inventory:
no-access: "&4Du kannst nicht auf diesen Block zugreifen"
android:
started: "&7Dein Android hat sein Skript fortgesetzt"
stopped: "&7Dein Android hat sein Skript pausiert"
scripts:
already-uploaded: "&4Dieses Skript wurde bereits hochgeladen."
instructions:
START: "&2Start des Skripts"
REPEAT: "&9Neubeginn des Skripts"
WAIT: "&eWarte 0.5 Sekunden"
GO_FORWARD: "&7Gehe vorwärts"
GO_UP: "&7Gehe nach oben"
GO_DOWN: "&7Gehe nach unten"
TURN_LEFT: "&7Drehung nach links"
TURN_RIGHT: "&7Drehung nach rechts"
DIG_UP: "&bGrabe nach oben"
DIG_FORWARD: "&bGrabe vorwärts"
DIG_DOWN: "&bGrabe nach unten"
MOVE_AND_DIG_UP: "&bGehe & Grabe nach oben"
MOVE_AND_DIG_FORWARD: "&bGehe & Grabe vorwärts"
MOVE_AND_DIG_DOWN: "&bGehe & Grabe nach unten"
ATTACK_MOBS_ANIMALS: "&4Angreifen &c(Monster & Tiere)"
ATTACK_MOBS: "&4Angreifen &c(Nur Monster)"
ATTACK_ANIMALS: "&4Angreifen &c(Nur Tiere)"
ATTACK_ANIMALS_ADULT: "&4Angreifen &c(Nur ausgewachsene Tiere)"
CHOP_TREE: "&cBaum fällen und nachpflanzen"
CATCH_FISH: "&bAngeln"
FARM_FORWARD: "&bErnten und Nachpflanzen"
FARM_DOWN: "&bErnten und Nachpflanzen &7(Unterer Block)"
FARM_EXOTIC_FORWARD: "&bErnten und Nachpflanzen (Fortgeschritten)"
FARM_EXOTIC_DOWN: "&bErnten und Nachpflanzen (Fortgeschritten und unterer Block)"
INTERFACE_ITEMS: "&9Items ins vorliegende Interface bewegen"
INTERFACE_FUEL: "&cTreibstoff aus dem vorliegenden Interface nehmen"
enter-name:
-
- "&eBitte gebe einen Namen für dein Skript ins Chatfenster ein"
uploaded:
- "&bLade dein Skript hoch..."
- "&aDein Skript wurde erfolgreich hochgeladen!"
rating:
own: "&4Du kannst nicht dein eigenes Skript bewerten!"
already: "&4Du hast dieses Skript bereits bewertet!"
editor: Skripteditor
languages:
default: Server-Standard
en: Englisch
de: Deutsch
fr: Französisch
it: Italienisch
es: Spanisch
pl: Polnisch
sv: Schwedisch
nl: Niederländisch
cs: Tschechisch
hu: Ungarisch
lv: Lettisch
ru: Russisch
sk: Slowakisch
zh-TW: Chinesisch (Taiwan)
vi: Vietnamesisch
id: Indonesisch
zh-CN: Chinesisch (China)
el: Griechisch
he: Hebräisch
ar: Arabisch
af: Afrikaans
da: Dänisch
fi: Finnisch
uk: Ukrainisch
ms: Malaiisch
'no': Norwegisch
ja: Japanisch
fa: Persisch
th: Thailändisch
ro: Rumänisch
pt: Portugiesisch (Portugal)
pt-BR: Portugiesisch (Brasilien)
bg: Bulgarisch
ko: Koreanisch
tr: Türkisch
hr: Kroatisch
mk: Mazedonisch
sr: Serbisch
be: Belarusisch
tl: Tagalog
miner:
no-ores: "&eIch konnte leider keine Erze in der Nähe finden!"

View File

@ -110,6 +110,7 @@ messages:
disabled-item: '&4&lThis Item has been disabled! How did you even get that?'
no-tome-yourself: '&cYou cannot use the &4Tome of Knowledge &con yourself...'
multimeter: '&bStored Energy: &3%stored% &b/ &3%capacity%'
piglin-barter: '&4You cannot barter with piglins using Slimefun items'
talisman:
anvil: '&a&oYour Talisman saved your tool from breaking'
@ -129,10 +130,21 @@ messages:
soulbound-rune:
fail: '&cYou can only bind one item to your soul at a time.'
success: '&aYou have successfully bound this item to your soul! You will keep it when you die.'
enchantment-rune:
fail: '&cYou cannot enchant this item.'
no-enchantment: '&cCouldn''t find any applicable enchantment for this item.'
success: '&aYou have successfully applied a random applicable enchantment to this item.'
research:
start: '&7The Ancient Spirits whisper mysterious words into your ear!'
progress: '&7You start to wonder about &b%research% &e(%progress%)'
tape-measure:
no-anchor: '&cYou need to set an anchor before you can start to measure!'
wrong-world: '&cYour anchor seems to be in a different world!'
distance: '&7Measurement taken. &eDistance: %distance%'
anchor-set: '&aSuccessfully set the anchor:&e %anchor%'
fire-extinguish: '&7You have extinguished yourself'
cannot-place: '&cYou cannot place that block there!'

View File

@ -151,6 +151,7 @@ messages:
- "&7Всегда смотрите на светлую сторону жизни!"
- "&7Вы съели странное печенье, до жути напоминающее бисквит"
- "&7Неоновые таблички просто ШИК!"
piglin-barter: "&4Вы не можете торговать с пиглинами, используя Slimefun предметы"
machines:
pattern-not-found: "&eК сожалению, не удалось распознать этот рецепт. Пожалуйста,
разложите предметы в верной последовательности в раздатчик."
@ -292,6 +293,8 @@ languages:
zh-CN: Китайский (Китай)
el: Греческий
he: Иврит
pt: Португальский (Португалия)
pt-BR: Португальский (Бразилия)
ar: Арабский
af: Бурский
da: Датский
@ -303,8 +306,6 @@ languages:
fa: Персидский
th: Тайский
ro: Румынский
pt: Португальский (Португалия)
pt-BR: Португальский (Бразилия)
bg: Болгарский
ko: Корейский
tr: Турецкий

View File

@ -152,6 +152,20 @@ messages:
- "&7Laging tumingin sa maliwanag na bahagi ng buhay!"
- "&7Biskwit pala ito at hindi ito siya Kukis."
- "&7Ang astig ng mga Neon Signs!"
piglin-barter: "&4Hindi ka maaaring mag-barter sa mga piglins gamit ang mga item
ng Slimefun."
enchantment-rune:
fail: "&cAng aytem na ito ay bawal i-enchant."
no-enchantment: "&cHindi makahanap ng anuman na puwedeng enchantment para sa aytem
na ito."
success: "&aMatagumpay mong na-apply ang isang random na naaangkop na enchantment
sa aytem na ito."
tape-measure:
no-anchor: "&cKailangan mong magtakda ng isang angkla bago ka makapagsimula upang
masukat!"
wrong-world: "&cAng iyong angkla ay tila nasa ibang mundo!"
distance: "&7Measurement taken. &eDistansiya: %distance%"
anchor-set: "&aMatagumpay na na-set ang angla:&e %anchor%"
machines:
pattern-not-found: "&ePasensiya na, hindi ko maintindihan ang Recipe na ito. Pakilagay
ang mga Aytem sa tamang pattern sa loob ng Dispense."

View File

@ -149,6 +149,16 @@ messages:
- "&7Daima hayatın parlak tarafından bak!"
- "&7Bu aslında bir Bisküvi idi, Kurabiye değil."
- "&7Neon levhalar ışık yayar!"
piglin-barter: "&4Slimefun eşyalarıyla, piglinlerle ticaret yapamazsın"
enchantment-rune:
fail: "&cYou eşyayı büyüleyemezsin."
no-enchantment: "&cBu eşya için uygun bir büyü bulunamadı."
success: "&aBaşarılı bir şekilde bu eşyaya rastgele bir büyü uyguladınız."
tape-measure:
no-anchor: "&cÖlçüm yapmadan önce bir nokta seçmelisiniz!"
wrong-world: "&cSeçtiğiniz nokta başka bir dünyada gözüküyor!"
distance: "&7Ölçüm yapıldı. &eUzaklık: %distance%"
anchor-set: "&aBaşarılı bir şekilde bir nokta seçildi:&e %anchor%"
machines:
pattern-not-found: "&eÜzgünüm, bu tarifi tanıyamadım. Lütfen Eşyaları Dağıtıcıya
doğru şekilde yerleştirin."

View File

@ -147,6 +147,7 @@ messages:
- "&7Завжди дивіться на світлу сторону життя!"
- "&7Цього разу попався бісквіт, а не печиво"
- "&7Неонові таблички просто ШИК!"
piglin-barter: "&4Ви не можете торгувати з піґлінами, використовуючи Slimefun предмети"
machines:
pattern-not-found: "&eНа жаль, не вдалось розпізнати цей рецепт. Будь ласка, розмістіть
предмети у правильній послідовності у роздавач."
@ -287,7 +288,6 @@ languages:
zh-CN: Китайська (Китай)
el: Грецька
he: Іврит
pt: Португальська (Португалія)
pt-BR: Португальська (Бразилія)
ar: Арабська
af: Бурська
@ -300,6 +300,7 @@ languages:
fa: Перська
th: Тайська
ro: Румунська
pt: Португальська (Португалія)
bg: Болгарська
ko: Корейська
tr: Турецька

View File

@ -1,236 +1,242 @@
---
slimefun:
24k_gold_block: Ein Palast aus Gold
advanced_android: Verbesserte Roboter
advanced_butcher_android: Verbesserter Killerroboter
advanced_circuit_board: Fortgeschrittener Schaltkreis
advanced_electric_smeltery: Verbesserter elektrischer Schmelzofen
advanced_farmer_android: Verbesserter Farmroboter
advanced_fisherman_android: Verbesserter Fischerroboter
advanced_output_node: Verbesserte Cargo-Knotenpunkte
alloys: Meister der Legierungen
ancient_altar: Alter Altar
ancient_runes: Antike Runen
android_interfaces: Roboter-Interface
android_memory_core: Roboterkern
angel_talisman: Talisman des Engels
animal_growth_accelerator: Wachstumsboost
anvil_talisman: Talisman des Ambosses
armored_jetboots: Gepanzerte Raketenstiefel
armored_jetpack: Gepanzertes Jetpack
walking_sticks: Gehstöcke
portable_crafter: Eine Werkbank zum Mitnehmen
fortune_cookie: Glückskeks
portable_dustbin: Mobile Mülltonnen
meat_jerky: Dörrfleisch
armor_forge: Rüstungsherstellung
auto_anvil: Automatischer Amboss
auto_breeder: Futterautomaten
auto_drier: Ein trockener Tag
auto_enchanting: Automatische Verzauberungen
automated_crafting_chamber: Automatisches Craften
automated_panning_machine: Goldwaschen für Fortgeschrittene
automatic_ignition_chamber: Ein automatisierter Schmelzofen
backpacks: Rucksäcke
glowstone_armor: Glühende Rüstung
lumps: Magische Klumpen
ender_backpack: Ender-Rucksack
ender_armor: Ender-Rüstung
magic_eye_of_ender: Magisches Enderauge
magic_sugar: Magischer Zucker
monster_jerky: Gepökeltes Zombiefleisch
slime_armor: Schleimige Rüstung
sword_of_beheading: Köpfen mit Köpfchen
basic_circuit_board: Einfacher Schaltkreis
advanced_circuit_board: Fortgeschrittener Schaltkreis
smeltery: Schmelzofen
steel: Die Ära des Stahls
misc_power_items: Items mit Energie
battery: Deine erste Batterie
better_carbon_press: Bessere Karbonpresse
better_crop_growth_accelerator: Noch schnellere Pflanzen
better_electric_crucibles: Verbesserter Schmelztiegel
better_electric_furnace: Verbesserter elektrischer Ofen
better_food_fabricator: Essen vom Fließband
better_freezer: Ein besserer Kühlschrank
better_gps_transmitters: Verbesserte Satelliten
better_heated_pressure_chamber: Unter Druck
better_solar_generators: Verbesserte Solargeneratoren
bio_reactor: Biologisch abbaubar
blade_of_vampires: Vampirklinge
blistering_ingots: Radioaktiv und glühend
block_placer: Automatisch Blöcke platzieren
boosted_uranium: Starkes Uran
boots_of_the_stomper: Stampfende Stiefel
bound_armor: Rüstung zum Behalten
bound_backpack: Ein treuer Rucksack
bound_tools: Werkzeuge zum Behalten
bound_weapons: Waffen zum Behalten
bronze: Bronze
butcher_androids: Killer-Roboter
steel_plate: Stahlplatten
steel_thruster: Ein Triebwerk aus Stahl
parachute: Fallschirm
grappling_hook: Enterhaken
jetpacks: Jetpacks
multitools: Schweizer Taschenmesser
solar_panel_and_helmet: Solarhelm
elemental_staff: Stab der Elemente
grind_stone: Das Zermalmen von Items
cactus_armor: Eine Rüstung aus Kaktus
capacitors: Einfache Kondensatoren
carbonado: Schwarze Diamanten
carbonado_furnace: Carbonado-Ofen
carbonado_tools: Werkzeuge aus Carbonado
carbon_press: Karbonpresse
cargo_basics: Cargo 101
cargo_nodes: Cargo-Knotenpunkte
chainmail_armor: Kettenrüstung
charging_bench: Unter Strom
coal_generator: Kohleindustrie
cobalt_pickaxe: Eine schnelle Spitzhacke
combustion_reactor: Verbrennungsmotor
common_talisman: Gewöhnlicher Talisman
composter: Kompostierung
gold_pan: Goldgräber
magical_book_cover: Magischer Buchbinder
slimefun_metals: Neues Metall
ore_crusher: Doppelte Erze
bronze: Bronze
alloys: Meister der Legierungen
compressor_and_carbon: Karbon-Herstellung
cooler: Kühles zum Mitnehmen
copper_wire: Kupferdrähte
crop_growth_accelerator: Beschleunigte Pflanzen
crucible: Schmelztiegel
crushed_ore: Erzpurifikation
gilded_iron_armor: Vergoldete Eisenrüstung
synthetic_diamond: Synthetische Diamanten
pressure_chamber: Druckkammer
synthetic_sapphire: Synthetische Sapphire
damascus_steel: Damaststahl
damascus_steel_armor: Damaststahlrüstung
diet_cookie: Diätkekse
duct_tape: Panzerband
electric_crucible: Elektrischer Schmelztiegel
electric_furnaces: Elektrische Öfen
electric_ingot_machines: Die Barrenfabrik
reinforced_alloy: Verstärkte Legierung
carbonado: Schwarze Diamanten
magic_workbench: Magische Werkbank
wind_staff: " Bezwinger der Lüfte"
reinforced_armor: Verstärkte Rüstung
ore_washer: Erze waschen
gold_carats: Hochwertiges Gold
silicon: Silikon
fire_staff: Bezwinger der Flammen
smelters_pickaxe: Eine Spitzhacke zum Dahinschmelzen
common_talisman: Gewöhnlicher Talisman
anvil_talisman: Talisman des Ambosses
miner_talisman: Talisman der Mine
hunter_talisman: Talisman des Jägers
lava_talisman: Schwimmen in Lava
water_talisman: Atmen wie ein Fisch
angel_talisman: Talisman des Engels
fire_talisman: Talisman des Feuerwehrmanns
lava_crystal: Feurige Angelegenheit
magician_talisman: Talisman des Magiers
traveller_talisman: Talisman des Wanderers
warrior_talisman: Talisman des Kriegers
knight_talisman: Talisman des Ritters
gilded_iron: Glänzendes Eisen
synthetic_emerald: Falsche Edelsteine
chainmail_armor: Kettenrüstung
whirlwind_talisman: Talisman des Wirbelwindes
wizard_talisman: Talisman des Zauberers
lumber_axe: Holzfällen mit Stil
hazmat_suit: Gefahrenschutz
uranium: Radioaktives Material
crushed_ore: Erzpurifikation
redstone_alloy: Redstone-Legierung
carbonado_tools: Werkzeuge aus Carbonado
first_aid: Erste Hilfe Set
gold_armor: Glitzernde Rüstung
night_vision_googles: Nachtsichtgerät
pickaxe_of_containment: Eine Spitzhacke für Spawner
hercules_pickaxe: Die Kraft von Herkules
table_saw: Tischsäge
slime_steel_armor: Schleimiger Stahl
blade_of_vampires: Vampirklinge
water_staff: Wasserbändiger
24k_gold_block: Ein Palast aus Gold
composter: Kompostierung
farmer_shoes: Gartenarbeit
explosive_tools: Explosives Werkzeug
automated_panning_machine: Goldwaschen für Fortgeschrittene
boots_of_the_stomper: Stampfende Stiefel
pickaxe_of_the_seeker: Wer suchet, der findet
backpacks: Rucksäcke
woven_backpack: Stoff-Rucksack
crucible: Schmelztiegel
gilded_backpack: Vergoldeter Rucksack
armored_jetpack: Gepanzertes Jetpack
ender_talismans: Ender-Talisman
nickel_and_cobalt: Erzforscher
magnet: Magneten
infused_magnet: Verzauberter Magnet
cobalt_pickaxe: Eine schnelle Spitzhacke
essence_of_afterlife: Die Untoten
bound_backpack: Ein treuer Rucksack
jetboots: Raketenstiefel
armored_jetboots: Gepanzerte Raketenstiefel
seismic_axe: Die Erdbebenaxt
pickaxe_of_vein_mining: Minen im großen Stile
bound_weapons: Waffen zum Behalten
bound_tools: Werkzeuge zum Behalten
bound_armor: Rüstung zum Behalten
juicer: Leckere Säfte
repaired_spawner: Spawner reparieren
enhanced_furnace: Verbesserter Ofen
more_enhanced_furnaces: Noch bessere Öfen
high_tier_enhanced_furnaces: High-End-Öfen
reinforced_furnace: Verstärkter Ofen
carbonado_furnace: Carbonado-Ofen
electric_motor: Elektromotoren
block_placer: Automatisch Blöcke platzieren
scroll_of_dimensional_teleposition: Schwindelerregend
special_bows: Robin Hood
tome_of_knowledge_sharing: Erfahrungen teilen
flask_of_knowledge: Erfahrung lagern
hardened_glass: Verstärktes Glas
golden_apple_juice: Ein goldener Zaubertrank
cooler: Kühles zum Mitnehmen
ancient_altar: Alter Altar
wither_proof_obsidian: Anti-Wither Obsidian
ancient_runes: Antike Runen
special_runes: Lila Runen
infernal_bonemeal: Knochenmehl für Warzen
rainbow_blocks: Regenbogen
infused_hopper: Magischer Trichter
wither_proof_glass: Anti-Wither Glas
duct_tape: Panzerband
plastic_sheet: Plastik
android_memory_core: Roboterkern
oil: Schwarzes Gold
fuel: Fossile Brennstoffe
hologram_projector: Hologramme
capacitors: Einfache Kondensatoren
high_tier_capacitors: Verbesserte Kondensatoren
solar_generators: Solarenergie
electric_furnaces: Elektrische Öfen
electric_ore_grinding: Zermalmen und Zerquetschen
electric_press: Elektrische Presse
electric_smeltery: Ein besserer Schmelzofen
elemental_staff: Stab der Elemente
heated_pressure_chamber: Beheizte Druckkammer
coal_generator: Kohleindustrie
bio_reactor: Biologisch abbaubar
auto_enchanting: Automatische Verzauberungen
auto_anvil: Automatischer Amboss
multimeter: Messgeräte
gps_setup: GPS-Netzwerke 101
gps_emergency_transmitter: Ein Wegweiser für alle Fälle
programmable_androids: Programmierbare Roboter
android_interfaces: Roboter-Interface
geo_scanner: GEO-Scanner
combustion_reactor: Verbrennungsmotor
teleporter: Teleportation
teleporter_activation_plates: Beam mich hoch!
better_solar_generators: Verbesserte Solargeneratoren
better_gps_transmitters: Verbesserte Satelliten
elevator: Aufzüge
elytra: Gleitflügel
energized_solar_generator: Solarkraft in der Nacht
energized_gps_transmitter: High-End-Satelliten
energy_regulator: Ein Netzwerk unter Strom
butcher_androids: Killer-Roboter
organic_food: Viehfutter
auto_breeder: Futterautomaten
advanced_android: Verbesserte Roboter
advanced_butcher_android: Verbesserter Killerroboter
advanced_fisherman_android: Verbesserter Fischerroboter
animal_growth_accelerator: Wachstumsboost
xp_collector: Erfahrungssammler
organic_fertilizer: Organischer Dünger
crop_growth_accelerator: Beschleunigte Pflanzen
better_crop_growth_accelerator: Noch schnellere Pflanzen
reactor_essentials: Kraftwerke für Jedermann
nuclear_reactor: Kernkraftwerk
freezer: Eiskalt
cargo_basics: Cargo 101
cargo_nodes: Cargo-Knotenpunkte
electric_ingot_machines: Die Barrenfabrik
high_tier_electric_ingot_machines: Schnelle Barren
automated_crafting_chamber: Automatisches Craften
better_food_fabricator: Essen vom Fließband
reactor_access_port: Automatischer Reaktor
fluid_pump: Pumpe
better_freezer: Ein besserer Kühlschrank
boosted_uranium: Starkes Uran
trash_can: Mülltonne
advanced_output_node: Verbesserte Cargo-Knotenpunkte
carbon_press: Karbonpresse
electric_smeltery: Ein besserer Schmelzofen
better_electric_furnace: Verbesserter elektrischer Ofen
better_carbon_press: Bessere Karbonpresse
empowered_android: Hochenergetischer Roboter
empowered_butcher_android: Hochenergetischer Killerroboter
empowered_fisherman_android: Hochenergetischer Anglerroboter
ender_armor: Ender-Rüstung
ender_backpack: Ender-Rucksack
ender_talismans: Ender-Talisman
energized_gps_transmitter: High-End-Satelliten
energized_solar_generator: Solarkraft in der Nacht
energy_regulator: Ein Netzwerk unter Strom
enhanced_furnace: Verbesserter Ofen
essence_of_afterlife: Die Untoten
explosive_tools: Explosives Werkzeug
farmer_shoes: Gartenarbeit
fire_staff: Bezwinger der Flammen
fire_talisman: Talisman des Feuerwehrmanns
first_aid: Erste Hilfe Set
flask_of_knowledge: Erfahrung lagern
fluid_pump: Pumpe
fortune_cookie: Glückskeks
freezer: Eiskalt
fuel: Fossile Brennstoffe
geo_miner: GEO-Mining
geo_scanner: GEO-Scanner
gilded_backpack: Vergoldeter Rucksack
gilded_iron: Glänzendes Eisen
gilded_iron_armor: Vergoldete Eisenrüstung
glowstone_armor: Glühende Rüstung
gold_armor: Glitzernde Rüstung
gold_carats: Hochwertiges Gold
golden_apple_juice: Ein goldener Zaubertrank
gold_pan: Goldgräber
gps_emergency_transmitter: Ein Wegweiser für alle Fälle
gps_setup: GPS-Netzwerke 101
grappling_hook: Enterhaken
grind_stone: Das Zermalmen von Items
hardened_glass: Verstärktes Glas
hazmat_suit: Gefahrenschutz
heated_pressure_chamber: Beheizte Druckkammer
hercules_pickaxe: Die Kraft von Herkules
high_tier_capacitors: Verbesserte Kondensatoren
high_tier_carbon_press: Ultimative Karbonpresse
high_tier_electric_ingot_machines: Schnelle Barren
high_tier_enhanced_furnaces: High-End-Öfen
hologram_projector: Hologramme
hunter_talisman: Talisman des Jägers
infernal_bonemeal: Knochenmehl für Warzen
infused_hopper: Magischer Trichter
infused_magnet: Verzauberter Magnet
jetboots: Raketenstiefel
jetpacks: Jetpacks
juicer: Leckere Säfte
kelp_cookie: Süßer Seetang
knight_talisman: Talisman des Ritters
lava_crystal: Feurige Angelegenheit
wither_assembler: Ein automatisierter Wither
better_heated_pressure_chamber: Unter Druck
elytra: Gleitflügel
special_elytras: Verzauberte Gleitflügel
electric_crucible: Elektrischer Schmelztiegel
better_electric_crucibles: Verbesserter Schmelztiegel
advanced_electric_smeltery: Verbesserter elektrischer Schmelzofen
advanced_farmer_android: Verbesserter Farmroboter
lava_generator: Thermale Energie
lava_talisman: Schwimmen in Lava
lightning_rune: Rune des Blitzes
lumber_axe: Holzfällen mit Stil
lumps: Magische Klumpen
magical_book_cover: Magischer Buchbinder
magic_eye_of_ender: Magisches Enderauge
magician_talisman: Talisman des Magiers
magic_sugar: Magischer Zucker
magic_workbench: Magische Werkbank
magnesium_generator: Energie durch Magnesium
magnet: Magneten
makeshift_smeltery: Improvisierter Schmelzofen
meat_jerky: Dörrfleisch
miner_talisman: Talisman der Mine
misc_power_items: Items mit Energie
monster_jerky: Gepökeltes Zombiefleisch
more_enhanced_furnaces: Noch bessere Öfen
multimeter: Messgeräte
multitools: Schweizer Taschenmesser
nether_gold_pan: Goldwäsche im Nether
nether_ice: Eis aus dem Nether
nether_star_reactor: Netherstern-Reaktor
nickel_and_cobalt: Erzforscher
night_vision_googles: Nachtsichtgerät
nuclear_reactor: Kernkraftwerk
oil: Schwarzes Gold
ore_crusher: Doppelte Erze
ore_washer: Erze waschen
organic_fertilizer: Organischer Dünger
organic_food: Viehfutter
blistering_ingots: Radioaktiv und glühend
automatic_ignition_chamber: Ein automatisierter Schmelzofen
output_chest: Einfache Auffangkiste
parachute: Fallschirm
pickaxe_of_containment: Eine Spitzhacke für Spawner
pickaxe_of_the_seeker: Wer suchet, der findet
pickaxe_of_vein_mining: Minen im großen Stile
plastic_sheet: Plastik
portable_crafter: Eine Werkbank zum Mitnehmen
portable_dustbin: Mobile Mülltonnen
pressure_chamber: Druckkammer
programmable_androids: Programmierbare Roboter
copper_wire: Kupferdrähte
radiant_backpack: Strahlender Rucksack
rainbow_blocks: Regenbogen
reactor_access_port: Automatischer Reaktor
reactor_essentials: Kraftwerke für Jedermann
redstone_alloy: Redstone-Legierung
reinforced_alloy: Verstärkte Legierung
reinforced_armor: Verstärkte Rüstung
reinforced_furnace: Verstärkter Ofen
repaired_spawner: Spawner reparieren
scroll_of_dimensional_teleposition: Schwindelerregend
seismic_axe: Die Erdbebenaxt
silicon: Silikon
slime_armor: Schleimige Rüstung
slimefun_metals: Neues Metall
slime_steel_armor: Schleimiger Stahl
smelters_pickaxe: Eine Spitzhacke zum Dahinschmelzen
smeltery: Schmelzofen
solar_generators: Solarenergie
solar_panel_and_helmet: Solarhelm
soulbound_rune: Seelenbindung
special_bows: Robin Hood
special_elytras: Verzauberte Gleitflügel
special_runes: Lila Runen
steel: Die Ära des Stahls
steel_plate: Stahlplatten
steel_thruster: Ein Triebwerk aus Stahl
auto_drier: Ein trockener Tag
diet_cookie: Diätkekse
storm_staff: Die Stärke von Thor
sword_of_beheading: Köpfen mit Köpfchen
synthetic_diamond: Synthetische Diamanten
synthetic_emerald: Falsche Edelsteine
synthetic_sapphire: Synthetische Sapphire
table_saw: Tischsäge
teleporter: Teleportation
teleporter_activation_plates: Beam mich hoch!
tome_of_knowledge_sharing: Erfahrungen teilen
soulbound_rune: Seelenbindung
geo_miner: GEO-Mining
lightning_rune: Rune des Blitzes
totem_of_undying: Das Totem der Untoten
trash_can: Mülltonne
traveller_talisman: Talisman des Wanderers
charging_bench: Unter Strom
nether_gold_pan: Goldwäsche im Nether
electric_press: Elektrische Presse
magnesium_generator: Energie durch Magnesium
kelp_cookie: Süßer Seetang
makeshift_smeltery: Improvisierter Schmelzofen
tree_growth_accelerator: Schnelle Bäume
uranium: Radioaktives Material
walking_sticks: Gehstöcke
warrior_talisman: Talisman des Kriegers
water_staff: Wasserbändiger
water_talisman: Atmen wie ein Fisch
whirlwind_talisman: Talisman des Wirbelwindes
wind_staff: " Bezwinger der Lüfte"
wither_assembler: Ein automatisierter Wither
wither_proof_glass: Anti-Wither Glas
wither_proof_obsidian: Anti-Wither Obsidian
wizard_talisman: Talisman des Zauberers
woven_backpack: Stoff-Rucksack
xp_collector: Erfahrungssammler
industrial_miner: Industrielle Erzförderung
advanced_industrial_miner: Verbesserter Erzabbau
magical_zombie_pills: De-Zombifikation/Anti-Zombi Medizin
auto_brewer: Automatischer Braustand
enchantment_rune: Primitiver Zauber
lead_clothing: Kleidung aus Blei
tape_measure: Maßband
iron_golem_assembler: Eisengolems vom Fließband

View File

@ -235,3 +235,7 @@ slimefun:
advanced_industrial_miner: Better Mining
magical_zombie_pills: De-Zombification
auto_brewer: Industrial Brewery
enchantment_rune: Ancient Enchanting
lead_clothing: Lead Clothing
tape_measure: Tape Measure
iron_golem_assembler: Automated Iron Golems

View File

@ -236,3 +236,7 @@ slimefun:
advanced_industrial_miner: Better Mining
magical_zombie_pills: De-Zombification
auto_brewer: Industrial Brewery
enchantment_rune: Ancient Enchanting
lead_clothing: Lead Clothing
tape_measure: Tape Measure
iron_golem_assembler: Automated Iron Golems

View File

@ -236,3 +236,7 @@ slimefun:
advanced_industrial_miner: Gelişmiş Madencilik
magical_zombie_pills: A-Zombifikasyon
auto_brewer: Endüstriyel İksircilik
enchantment_rune: Kadim Büyücülük
lead_clothing: Kurşun Kaplama
tape_measure: Mezura
iron_golem_assembler: Otomize Demir Golemler

View File

@ -236,3 +236,7 @@ slimefun:
advanced_industrial_miner: 工業化採礦 - 改
magical_zombie_pills: 救贖藥丸
auto_brewer: 工業化釀造
enchantment_rune: 古代附魔
lead_clothing: 防輻射衣
tape_measure: 捲尺
iron_golem_assembler: 鐵巨人召喚機