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

Merge branch 'master' of https://github.com/TheBusyBiscuit/Slimefun4 into feature/metrics-module

This commit is contained in:
Daniel Walsh 2020-07-20 15:15:39 +01:00
commit 55041e81b1
45 changed files with 1148 additions and 1020 deletions

View File

@ -2,6 +2,7 @@
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of contents**
- [Release Candidate 15 (TBD)](#release-candidate-15-tbd)
- [Release Candidate 14 (12 Jul 2020)](#release-candidate-14-12-jul-2020)
- [Release Candidate 13 (16 Jun 2020)](#release-candidate-13-16-jun-2020)
- [Release Candidate 12 (27 May 2020)](#release-candidate-12-27-may-2020)
@ -19,6 +20,18 @@
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Release Candidate 15 (TBD)
#### 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
#### Fixes
* Fixed #2075
* Fixed #2093
## Release Candidate 14 (12 Jul 2020)
#### Additions
@ -95,6 +108,7 @@
* Fixed an issue with moving androids getting stuck
* Fixed Cargo nodes sometimes preventing chunks from unloading
* Fixed #2081
* Fixed a NullPointerException when Generators throw an Error Report
## Release Candidate 13 (16 Jun 2020)
https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#13

View File

@ -30,7 +30,7 @@ Here is a full summary of the differences between the two different versions of
| | development (latest) | "stable" |
| ------------------ | -------- | -------- |
| **Minecraft version(s)** | :video_game: **1.13.\* - 1.16.\*** | :video_game: **1.13.\* - 1.15.\*** |
| **Minecraft version(s)** | :video_game: **1.13.\* - 1.16.\*** | :video_game: **1.13.\* - 1.16.\*** |
| **automatic updates** | :heavy_check_mark: | :heavy_check_mark: |
| **frequent updates** | :heavy_check_mark: | :x: |
| **latest content** | :heavy_check_mark: | :x: |
@ -114,6 +114,8 @@ To compile Slimefun yourself, follow these steps:
If you are already using an IDE, make sure to import the project via git and set it as a *Maven project*. Then you should be able build it via Maven using the goals `clean package`.
If you have any further questions, then please join our [Discord Support Server](#discord) and ask your questions in the `#programming-help` channel. Note that we will not accept any bug reports from custom-compiled versions of Slimefun.
### Code Quality
Slimefun uses [Sonarcloud.io](https://sonarcloud.io/dashboard?id=TheBusyBiscuit_Slimefun4) to monitor Code Quality.

14
pom.xml
View File

@ -227,9 +227,17 @@
<packages>io.github.thebusybiscuit.slimefun4.utils*</packages>
</group>
<group>
<title>Slimefun4 - Item Implementations</title>
<title>Slimefun4 - Items</title>
<packages>io.github.thebusybiscuit.slimefun4.implementation.items*</packages>
</group>
<group>
<title>Slimefun4 - Multiblocks</title>
<packages>io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks*</packages>
</group>
<group>
<title>Slimefun4 - Electrical Machines</title>
<packages>io.github.thebusybiscuit.slimefun4.implementation.items.electric*</packages>
</group>
<group>
<title>Slimefun4 - Old packages</title>
<packages>me.mrCookieSlime.Slimefun*</packages>
@ -294,7 +302,7 @@
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.3.3</version>
<version>3.4.4</version>
<scope>test</scope>
</dependency>
@ -302,7 +310,7 @@
<dependency>
<groupId>com.github.TheBusyBiscuit</groupId>
<artifactId>CS-CoreLib2</artifactId>
<version>0.23.2</version>
<version>0.24</version>
<scope>compile</scope>
</dependency>
<dependency>

View File

@ -1,7 +1,6 @@
package io.github.thebusybiscuit.slimefun4.api;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
@ -18,6 +17,7 @@ import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.plugin.Plugin;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetProvider;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
@ -92,7 +92,7 @@ public class ErrorReport {
addon.getLogger().log(Level.WARNING, "");
}
catch (IOException x) {
catch (Exception x) {
addon.getLogger().log(Level.SEVERE, x, () -> "An Error occurred while saving an Error-Report for Slimefun " + SlimefunPlugin.getVersion());
}
});
@ -109,9 +109,19 @@ public class ErrorReport {
stream.println(" Block Data: " + l.getBlock().getBlockData().getClass().getName());
stream.println(" State: " + l.getBlock().getState().getClass().getName());
stream.println();
stream.println("Ticker-Info:");
stream.println(" Type: " + (item.getBlockTicker().isSynchronized() ? "Synchronized" : "Asynchronous"));
stream.println();
if (item.getBlockTicker() != null) {
stream.println("Ticker-Info:");
stream.println(" Type: " + (item.getBlockTicker().isSynchronized() ? "Synchronized" : "Asynchronous"));
stream.println();
}
if (item instanceof EnergyNetProvider) {
stream.println("Ticker-Info:");
stream.println(" Type: Indirect (Energy Network)");
stream.println();
}
stream.println("Slimefun Data:");
stream.println(" ID: " + item.getID());
stream.println(" Inventory: " + BlockStorage.getStorage(l.getWorld()).hasInventory(l));

View File

@ -30,7 +30,7 @@ public class WrongItemStackException extends RuntimeException {
* An error message to display
*/
public WrongItemStackException(String message) {
super("You probably wanted alter a different ItemStack: " + message);
super("You probably wanted to alter a different ItemStack: " + message);
}
}

View File

@ -21,7 +21,6 @@ import io.github.thebusybiscuit.cscorelib2.config.Config;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.attributes.WitherProof;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideImplementation;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout;
import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlock;
@ -71,21 +70,15 @@ public class SlimefunRegistry {
private final KeyMap<GEOResource> geoResources = new KeyMap<>();
private final Set<String> energyGenerators = new HashSet<>();
private final Set<String> energyCapacitors = new HashSet<>();
private final Set<String> energyConsumers = new HashSet<>();
private final Set<String> chargeableBlocks = new HashSet<>();
private final Map<String, WitherProof> witherProofBlocks = new HashMap<>();
private final Map<UUID, PlayerProfile> profiles = new ConcurrentHashMap<>();
private final Map<String, BlockStorage> worlds = new ConcurrentHashMap<>();
private final Map<String, BlockInfoConfig> chunks = new HashMap<>();
private final Map<SlimefunGuideLayout, SlimefunGuideImplementation> layouts = new EnumMap<>(SlimefunGuideLayout.class);
private final Map<EntityType, Set<ItemStack>> drops = new EnumMap<>(EntityType.class);
private final Map<EntityType, Set<ItemStack>> mobDrops = new EnumMap<>(EntityType.class);
private final Map<String, Integer> capacities = new HashMap<>();
private final Map<String, BlockMenuPreset> blockMenuPresets = new HashMap<>();
private final Map<String, UniversalBlockMenu> universalInventories = new HashMap<>();
private final Map<Class<? extends ItemHandler>, Set<ItemHandler>> itemHandlers = new HashMap<>();
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<>();
@ -200,11 +193,11 @@ public class SlimefunRegistry {
}
public Map<EntityType, Set<ItemStack>> getMobDrops() {
return drops;
return mobDrops;
}
public Set<ItemStack> getMobDrops(EntityType entity) {
return drops.get(entity);
return mobDrops.get(entity);
}
public Set<SlimefunItem> getRadioactiveItems() {
@ -240,7 +233,7 @@ public class SlimefunRegistry {
}
public Map<Class<? extends ItemHandler>, Set<ItemHandler>> getPublicItemHandlers() {
return itemHandlers;
return globalItemHandlers;
}
public Map<String, SlimefunBlockHandler> getBlockHandlers() {
@ -268,24 +261,4 @@ public class SlimefunRegistry {
return automatedCraftingChamberRecipes;
}
public Set<String> getEnergyGenerators() {
return energyGenerators;
}
public Set<String> getEnergyCapacitors() {
return energyCapacitors;
}
public Set<String> getEnergyConsumers() {
return energyConsumers;
}
public Set<String> getChargeableBlocks() {
return chargeableBlocks;
}
public Map<String, WitherProof> getWitherProofBlocks() {
return witherProofBlocks;
}
}

View File

@ -2,7 +2,6 @@ package io.github.thebusybiscuit.slimefun4.core.attributes;
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNet;
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
/**
@ -37,33 +36,4 @@ public interface EnergyNetComponent extends ItemAttribute {
*/
int getCapacity();
/**
* This method is used for internal purposes to register the component.
* You do not have to call this method yourself.
*
* @param id
* The id of the {@link SlimefunItem} this refers to
*/
default void registerComponent(String id) {
switch (getEnergyComponentType()) {
case CONSUMER:
SlimefunPlugin.getRegistry().getEnergyConsumers().add(id);
break;
case CAPACITOR:
SlimefunPlugin.getRegistry().getEnergyCapacitors().add(id);
break;
case GENERATOR:
SlimefunPlugin.getRegistry().getEnergyGenerators().add(id);
break;
default:
break;
}
int capacity = getCapacity();
if (capacity > 0) {
SlimefunPlugin.getRegistry().getEnergyCapacities().put(id, capacity);
}
}
}

View File

@ -0,0 +1,62 @@
package io.github.thebusybiscuit.slimefun4.core.attributes;
import org.bukkit.Location;
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNet;
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.AbstractEnergyProvider;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.Reactor;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator;
/**
* An {@link EnergyNetProvider} is an extension of {@link EnergyNetComponent} which provides
* energy to an {@link EnergyNet}.
* It must be implemented on any Generator or {@link Reactor}.
*
* @author TheBusyBiscuit
*
* @see EnergyNet
* @see EnergyNetComponent
* @see AbstractEnergyProvider
* @see AGenerator
* @see Reactor
*
*/
public interface EnergyNetProvider extends EnergyNetComponent {
@Override
default EnergyNetComponentType getEnergyComponentType() {
return EnergyNetComponentType.GENERATOR;
}
/**
* This method returns how much energy this {@link EnergyNetProvider} provides to the {@link EnergyNet}.
* We call this method on every tick, so make sure to keep it light and fast.
* Stored energy does not have to be handled in here.
*
* @param l
* The {@link Location} of this {@link EnergyNetProvider}
* @param data
* The stored block data
*
* @return The generated output energy of this {@link EnergyNetProvider}.
*/
int getGeneratedOutput(Location l, Config data);
/**
* This method returns whether the given {@link Location} is going to explode on the
* next tick.
*
* @param l
* The {@link Location} of this {@link EnergyNetProvider}
* @param data
* The stored block data
*
* @return Whether or not this {@link Location} will explode.
*/
default boolean willExplode(Location l, Config data) {
return false;
}
}

View File

@ -6,6 +6,7 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.lang.Validate;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
@ -14,7 +15,7 @@ import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.slimefun4.core.commands.subcommands.Commands;
import io.github.thebusybiscuit.slimefun4.core.commands.subcommands.SlimefunSubCommands;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
/**
@ -25,6 +26,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
*/
public class SlimefunCommand implements CommandExecutor, Listener {
private boolean registered = false;
private final SlimefunPlugin plugin;
private final List<SubCommand> commands = new LinkedList<>();
private final Map<SubCommand, Integer> commandUsage = new HashMap<>();
@ -40,11 +42,14 @@ public class SlimefunCommand implements CommandExecutor, Listener {
}
public void register() {
Validate.isTrue(!registered, "Slimefun's subcommands have already been registered!");
registered = true;
plugin.getServer().getPluginManager().registerEvents(this, plugin);
plugin.getCommand("slimefun").setExecutor(this);
plugin.getCommand("slimefun").setTabCompleter(new SlimefunTabCompleter(this));
Commands.addCommands(this, commands);
commands.addAll(SlimefunSubCommands.getAllCommands(this));
}
public SlimefunPlugin getPlugin() {

View File

@ -1,18 +1,28 @@
package io.github.thebusybiscuit.slimefun4.core.commands.subcommands;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
public final class Commands {
/**
* This class holds the implementations of every {@link SubCommand}.
* The implementations themselves are package-private, this class only provides
* a static setup method
*
* @author TheBusyBiscuit
*
*/
public final class SlimefunSubCommands {
private Commands() {
}
private SlimefunSubCommands() {}
public static void addCommands(SlimefunCommand cmd, Collection<SubCommand> commands) {
public static Collection<SubCommand> getAllCommands(SlimefunCommand cmd) {
SlimefunPlugin plugin = cmd.getPlugin();
List<SubCommand> commands = new LinkedList<>();
commands.add(new HelpCommand(plugin, cmd));
commands.add(new VersionsCommand(plugin, cmd));
@ -27,5 +37,7 @@ public final class Commands {
commands.add(new SearchCommand(plugin, cmd));
commands.add(new DebugFishCommand(plugin, cmd));
commands.add(new BackpackCommand(plugin, cmd));
return commands;
}
}

View File

@ -247,8 +247,9 @@ final class CargoUtils {
ItemStackWrapper wrapper = new ItemStackWrapper(stack);
for (int slot : menu.getPreset().getSlotsAccessedByItemTransport(menu, ItemTransportFlow.INSERT, stack)) {
for (int slot : menu.getPreset().getSlotsAccessedByItemTransport(menu, ItemTransportFlow.INSERT, wrapper)) {
ItemStack itemInSlot = menu.getItemInSlot(slot);
if (itemInSlot == null) {
menu.replaceExistingItem(slot, stack);
return null;
@ -337,9 +338,6 @@ final class CargoUtils {
}
itemInSlot.setAmount(Math.min(amount, maxStackSize));
// Setting item in inventory will clone the ItemStack
inv.setItem(slot, itemInSlot);
return stack;
}
}

View File

@ -12,6 +12,7 @@ import java.util.Map;
import java.util.Optional;
import java.util.Queue;
import java.util.Set;
import java.util.logging.Level;
import org.bukkit.Location;
import org.bukkit.Material;
@ -34,6 +35,7 @@ import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu;
import me.mrCookieSlime.Slimefun.api.inventory.UniversalBlockMenu;
@ -96,10 +98,9 @@ abstract class ChestTerminalNetwork extends Network {
Iterator<ItemRequest> iterator = itemRequests.iterator();
while (iterator.hasNext()) {
ItemRequest request = iterator.next();
BlockMenu menu = BlockStorage.getInventory(request.getTerminal());
if (terminals.contains(request.getTerminal()) || imports.contains(request.getTerminal()) || exports.contains(request.getTerminal())) {
BlockMenu menu = BlockStorage.getInventory(request.getTerminal());
if (menu != null) {
switch (request.getDirection()) {
case INSERT:
distributeInsertionRequest(inventories, request, menu, iterator, destinations);
@ -258,18 +259,13 @@ abstract class ChestTerminalNetwork extends Network {
}
private void collectTerminalRequests() {
SlimefunItem item = SlimefunItem.getByID("CHEST_TERMINAL");
for (Location terminal : terminals) {
long timestamp = SlimefunPlugin.getProfiler().newEntry();
BlockMenu menu = BlockStorage.getInventory(terminal);
ItemStack sendingItem = menu.getItemInSlot(TERMINAL_OUT_SLOT);
if (sendingItem != null) {
itemRequests.add(new ItemRequest(terminal, TERMINAL_OUT_SLOT, sendingItem, ItemTransportFlow.INSERT));
}
SlimefunPlugin.getProfiler().closeEntry(terminal, item, timestamp);
}
}
@ -281,6 +277,16 @@ abstract class ChestTerminalNetwork extends Network {
* A {@link Set} of providers to this {@link ChestTerminalNetwork}
*/
protected void updateTerminals(Set<Location> providers) {
if (terminals.isEmpty()) {
// Performance improvement - We don't need to compute items for
// Cargo networks without any Chest Terminals
return;
}
// Timings will be slightly inaccurate here but most often people are gonna
// use no more than one terminal anyway, so this might be fine
long timestamp = SlimefunPlugin.getProfiler().newEntry();
SlimefunItem item = SlimefunItem.getByID("CHEST_TERMINAL");
List<ItemStackAndInteger> items = findAvailableItems(providers);
for (Location l : terminals) {
@ -297,6 +303,8 @@ abstract class ChestTerminalNetwork extends Network {
int index = i + (TERMINAL_SLOTS.length * (page - 1));
updateTerminal(l, terminal, slot, index, items);
}
SlimefunPlugin.getProfiler().closeEntry(l, item, timestamp);
}
}
@ -330,7 +338,8 @@ abstract class ChestTerminalNetwork extends Network {
terminal.replaceExistingItem(slot, stack);
terminal.addMenuClickHandler(slot, (p, sl, is, action) -> {
int amount = item.getInt() > item.getItem().getMaxStackSize() ? item.getItem().getMaxStackSize() : item.getInt();
itemRequests.add(new ItemRequest(l, 44, new CustomItem(item.getItem(), action.isRightClicked() ? amount : 1), ItemTransportFlow.WITHDRAW));
ItemStack requestedItem = new CustomItem(item.getItem(), action.isRightClicked() ? amount : 1);
itemRequests.add(new ItemRequest(l, 44, requestedItem, ItemTransportFlow.WITHDRAW));
return false;
});
@ -359,10 +368,14 @@ abstract class ChestTerminalNetwork extends Network {
}
else if (BlockStorage.hasInventory(target)) {
BlockMenu blockMenu = BlockStorage.getInventory(target);
Config cfg = BlockStorage.getLocationInfo(target.getLocation());
if (cfg.getString("id").startsWith("BARREL_") && cfg.getString("storedItems") != null) {
gatherItemsFromBarrel(l, cfg, blockMenu, items);
if (blockMenu.getPreset().getID().startsWith("BARREL_")) {
Config cfg = BlockStorage.getLocationInfo(target.getLocation());
String data = cfg.getString("storedItems");
if (data != null) {
gatherItemsFromBarrel(l, data, blockMenu, items);
}
}
else {
handleWithdraw(blockMenu, items, l);
@ -386,27 +399,32 @@ abstract class ChestTerminalNetwork extends Network {
return items;
}
private void gatherItemsFromBarrel(Location l, Config cfg, BlockMenu blockMenu, List<ItemStackAndInteger> items) {
int stored = Integer.parseInt(cfg.getString("storedItems"));
private void gatherItemsFromBarrel(Location l, String data, BlockMenu blockMenu, List<ItemStackAndInteger> items) {
try {
int stored = Integer.parseInt(data);
for (int slot : blockMenu.getPreset().getSlotsAccessedByItemTransport((DirtyChestMenu) blockMenu, ItemTransportFlow.WITHDRAW, null)) {
ItemStack is = blockMenu.getItemInSlot(slot);
for (int slot : blockMenu.getPreset().getSlotsAccessedByItemTransport((DirtyChestMenu) blockMenu, ItemTransportFlow.WITHDRAW, null)) {
ItemStack is = blockMenu.getItemInSlot(slot);
if (is != null && CargoUtils.matchesFilter(l.getBlock(), is)) {
boolean add = true;
if (is != null && CargoUtils.matchesFilter(l.getBlock(), is)) {
boolean add = true;
for (ItemStackAndInteger item : items) {
if (SlimefunUtils.isItemSimilar(is, item.getItem(), true)) {
add = false;
item.add(is.getAmount() + stored);
for (ItemStackAndInteger item : items) {
if (SlimefunUtils.isItemSimilar(is, item.getItemStackWrapper(), true, false)) {
add = false;
item.add(is.getAmount() + stored);
}
}
if (add) {
items.add(new ItemStackAndInteger(is, is.getAmount() + stored));
}
}
if (add) {
items.add(new ItemStackAndInteger(is, is.getAmount() + stored));
}
}
}
catch (Exception x) {
Slimefun.getLogger().log(Level.SEVERE, "An Exception occured while trying to read data from a Barrel", x);
}
}
private void handleWithdraw(DirtyChestMenu menu, List<ItemStackAndInteger> items, Location l) {
@ -420,7 +438,7 @@ abstract class ChestTerminalNetwork extends Network {
boolean add = true;
for (ItemStackAndInteger item : items) {
if (SlimefunUtils.isItemSimilar(stack, item.getItem(), true)) {
if (SlimefunUtils.isItemSimilar(stack, item.getItemStackWrapper(), true)) {
add = false;
item.add(stack.getAmount());
}

View File

@ -2,9 +2,12 @@ package io.github.thebusybiscuit.slimefun4.core.networks.cargo;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
class ItemStackAndInteger {
private final ItemStack item;
private ItemStackWrapper wrapper;
private int number;
ItemStackAndInteger(ItemStack item, int amount) {
@ -20,6 +23,14 @@ class ItemStackAndInteger {
return item;
}
public ItemStackWrapper getItemStackWrapper() {
if (wrapper == null && item != null) {
wrapper = new ItemStackWrapper(item);
}
return wrapper;
}
public void add(int amount) {
number += amount;
}

View File

@ -1,6 +1,8 @@
package io.github.thebusybiscuit.slimefun4.core.networks.energy;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
@ -15,6 +17,7 @@ import io.github.thebusybiscuit.slimefun4.api.ErrorReport;
import io.github.thebusybiscuit.slimefun4.api.network.Network;
import io.github.thebusybiscuit.slimefun4.api.network.NetworkComponent;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetProvider;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.Reactor;
@ -35,6 +38,7 @@ import me.mrCookieSlime.Slimefun.api.energy.ChargableBlock;
*
* @see Network
* @see EnergyNetComponent
* @see EnergyNetProvider
* @see EnergyNetComponentType
*
*/
@ -49,16 +53,10 @@ public class EnergyNet extends Network {
return EnergyNetComponentType.NONE;
}
if (SlimefunPlugin.getRegistry().getEnergyGenerators().contains(id)) {
return EnergyNetComponentType.GENERATOR;
}
SlimefunItem item = SlimefunItem.getByID(id);
if (SlimefunPlugin.getRegistry().getEnergyCapacitors().contains(id)) {
return EnergyNetComponentType.CAPACITOR;
}
if (SlimefunPlugin.getRegistry().getEnergyConsumers().contains(id)) {
return EnergyNetComponentType.CONSUMER;
if (item instanceof EnergyNetComponent) {
return ((EnergyNetComponent) item).getEnergyComponentType();
}
return EnergyNetComponentType.NONE;
@ -143,10 +141,10 @@ public class EnergyNet extends Network {
SimpleHologram.update(b, "&4No Energy Network found");
}
else {
double supply = DoubleHandler.fixDouble(tickAllGenerators(timestamp::getAndAdd) + tickAllCapacitors());
double demand = 0;
int availableEnergy = (int) supply;
Map<Location, Integer> generatorsWithCapacity = new HashMap<>();
int supply = tickAllGenerators(generatorsWithCapacity, timestamp::getAndAdd) + tickAllCapacitors();
int remainingEnergy = supply;
int demand = 0;
for (Location machine : consumers) {
int capacity = ChargableBlock.getMaxCharge(machine);
@ -156,20 +154,20 @@ public class EnergyNet extends Network {
int availableSpace = capacity - charge;
demand += availableSpace;
if (availableEnergy > 0) {
if (availableEnergy > availableSpace) {
if (remainingEnergy > 0) {
if (remainingEnergy > availableSpace) {
ChargableBlock.setUnsafeCharge(machine, capacity, false);
availableEnergy -= availableSpace;
remainingEnergy -= availableSpace;
}
else {
ChargableBlock.setUnsafeCharge(machine, charge + availableEnergy, false);
availableEnergy = 0;
ChargableBlock.setUnsafeCharge(machine, charge + remainingEnergy, false);
remainingEnergy = 0;
}
}
}
}
storeExcessEnergy(availableEnergy);
storeExcessEnergy(generatorsWithCapacity, remainingEnergy);
updateHologram(b, supply, demand);
}
@ -177,7 +175,7 @@ public class EnergyNet extends Network {
SlimefunPlugin.getProfiler().closeEntry(b.getLocation(), SlimefunItems.ENERGY_REGULATOR.getItem(), timestamp.get());
}
private void storeExcessEnergy(int available) {
private void storeExcessEnergy(Map<Location, Integer> generators, int available) {
for (Location capacitor : storage) {
if (available > 0) {
int capacity = ChargableBlock.getMaxCharge(capacitor);
@ -196,40 +194,82 @@ public class EnergyNet extends Network {
}
}
for (Location generator : generators) {
int capacity = ChargableBlock.getMaxCharge(generator);
for (Map.Entry<Location, Integer> entry : generators.entrySet()) {
Location generator = entry.getKey();
int capacity = entry.getValue();
if (capacity > 0) {
if (available > 0) {
if (available > capacity) {
ChargableBlock.setUnsafeCharge(generator, capacity, false);
available = available - capacity;
}
else {
ChargableBlock.setUnsafeCharge(generator, available, false);
available = 0;
}
if (available > 0) {
if (available > capacity) {
ChargableBlock.setUnsafeCharge(generator, capacity, false);
available -= capacity;
}
else {
ChargableBlock.setUnsafeCharge(generator, 0, false);
ChargableBlock.setUnsafeCharge(generator, available, false);
available = 0;
}
}
else {
ChargableBlock.setUnsafeCharge(generator, 0, false);
}
}
}
private double tickAllGenerators(LongConsumer timeCallback) {
double supply = 0;
private int tickAllGenerators(Map<Location, Integer> generatorsWithCapacity, LongConsumer timeCallback) {
Set<Location> exploded = new HashSet<>();
int supply = 0;
for (Location source : generators) {
long timestamp = SlimefunPlugin.getProfiler().newEntry();
Config config = BlockStorage.getLocationInfo(source);
SlimefunItem item = SlimefunItem.getByID(config.getString("id"));
if (item != null) {
if (item instanceof EnergyNetProvider) {
try {
EnergyNetProvider provider = (EnergyNetProvider) item;
int energy = provider.getGeneratedOutput(source, config);
if (provider.getCapacity() > 0) {
generatorsWithCapacity.put(source, provider.getCapacity());
String charge = config.getString("energy-charge");
if (charge != null) {
energy += Integer.parseInt(charge);
}
}
if (provider.willExplode(source, config)) {
exploded.add(source);
BlockStorage.clearBlockInfo(source);
Slimefun.runSync(() -> {
source.getBlock().setType(Material.LAVA);
source.getWorld().createExplosion(source, 0F, false);
});
}
else {
supply += energy;
}
}
catch (Exception | LinkageError t) {
exploded.add(source);
new ErrorReport(t, source, item);
}
long time = SlimefunPlugin.getProfiler().closeEntry(source, item, timestamp);
timeCallback.accept(time);
}
else if (item != null) {
try {
// This will be removed very very soon
// It is only here for temporary backwards compatibility
GeneratorTicker generator = item.getEnergyTicker();
Integer capacity = SlimefunPlugin.getRegistry().getEnergyCapacities().get(item.getID());
if (capacity != null && capacity.intValue() > 0) {
generatorsWithCapacity.put(source, capacity);
}
if (generator != null) {
double energy = generator.generateEnergy(source, item, config);
@ -267,12 +307,11 @@ public class EnergyNet extends Network {
}
generators.removeAll(exploded);
return supply;
}
private double tickAllCapacitors() {
double supply = 0;
private int tickAllCapacitors() {
int supply = 0;
for (Location capacitor : storage) {
supply += ChargableBlock.getCharge(capacitor);

View File

@ -17,19 +17,22 @@ import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.chat.hover.content.Content;
import net.md_5.bungee.api.chat.hover.content.Text;
class PerformanceSummary {
// The threshold at which a Block or Chunk is significant enough to appear in /sf timings
private static final int VISIBILITY_THRESHOLD = 280_000;
private static final int MIN_ITEMS = 3;
private static final int MAX_ITEMS = 10;
private static final int VISIBILITY_THRESHOLD = 300_000;
private static final int MIN_ITEMS = 4;
private static final int MAX_ITEMS = 12;
private final SlimefunProfiler profiler;
private final PerformanceRating rating;
private final long totalElapsedTime;
private final int totalTickedBlocks;
private final float percentage;
private final int tickRate;
private final Map<String, Long> chunks;
private final Map<String, Long> plugins;
@ -41,6 +44,7 @@ class PerformanceSummary {
this.percentage = profiler.getPercentageOfTick();
this.totalElapsedTime = totalElapsedTime;
this.totalTickedBlocks = totalTickedBlocks;
this.tickRate = profiler.getTickRate();
chunks = profiler.getByChunk();
plugins = profiler.getByPlugin();
@ -50,7 +54,8 @@ class PerformanceSummary {
public void send(CommandSender sender) {
sender.sendMessage("");
sender.sendMessage(ChatColor.GREEN + "===== Slimefun Lag Profiler =====");
sender.sendMessage(ChatColor.GOLD + "Total: " + ChatColor.YELLOW + NumberUtils.getAsMillis(totalElapsedTime));
sender.sendMessage(ChatColor.GOLD + "Total time: " + ChatColor.YELLOW + NumberUtils.getAsMillis(totalElapsedTime));
sender.sendMessage(ChatColor.GOLD + "Running every: " + ChatColor.YELLOW + NumberUtils.roundDecimalNumber(tickRate / 20.0) + "s (" + tickRate + " ticks)");
sender.sendMessage(ChatColor.GOLD + "Performance: " + getPerformanceRating());
sender.sendMessage("");
@ -124,7 +129,8 @@ class PerformanceSummary {
builder.append("\n\n&c+ &6").append(hidden).append(" more");
}
hoverComponent.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(ChatColors.color(builder.toString()))));
Content content = new Text(TextComponent.fromLegacyText(ChatColors.color(builder.toString())));
hoverComponent.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, content));
component.addExtra(hoverComponent);
}

View File

@ -1,5 +1,6 @@
package io.github.thebusybiscuit.slimefun4.core.services.profiler;
import org.bukkit.Location;
import org.bukkit.block.Block;
import io.github.thebusybiscuit.cscorelib2.blocks.BlockPosition;
@ -11,6 +12,11 @@ class ProfiledBlock {
private final BlockPosition position;
private final SlimefunItem item;
ProfiledBlock(Location l, SlimefunItem item) {
this.position = new BlockPosition(l);
this.item = item;
}
ProfiledBlock(BlockPosition position, SlimefunItem item) {
this.position = position;
this.item = item;

View File

@ -10,6 +10,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import org.apache.commons.lang.Validate;
import org.bukkit.Chunk;
@ -18,12 +19,12 @@ import org.bukkit.Server;
import org.bukkit.block.Block;
import org.bukkit.command.CommandSender;
import io.github.thebusybiscuit.cscorelib2.blocks.BlockPosition;
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.tasks.TickerTask;
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/**
* The {@link SlimefunProfiler} works closely to the {@link TickerTask} and is
@ -80,8 +81,10 @@ public class SlimefunProfiler {
* Be careful to {@link #closeEntry(Location, SlimefunItem, long)} all of them again!
* No {@link PerformanceSummary} will be sent until all entires were closed.
*
* If the specified amount is negative, scheduled entries will be removed
*
* @param amount
* The amount of entries that should be scheduled.
* The amount of entries that should be scheduled. Can be negative
*/
public void scheduleEntries(int amount) {
if (running.get()) {
@ -113,8 +116,9 @@ public class SlimefunProfiler {
long elapsedTime = System.nanoTime() - timestamp;
executor.execute(() -> {
ProfiledBlock block = new ProfiledBlock(new BlockPosition(l), item);
timings.put(block, elapsedTime);
ProfiledBlock block = new ProfiledBlock(l, item);
timings.putIfAbsent(block, elapsedTime);
queued.decrementAndGet();
});
@ -132,34 +136,48 @@ public class SlimefunProfiler {
return;
}
// Since we got more than one Thread in our pool, blocking this one is completely fine
executor.execute(() -> {
// Since we got more than one Thread in our pool,
// blocking this one is (hopefully) completely fine
executor.execute(this::finishReport);
}
// Wait for all timing results to come in
while (queued.get() > 0 && !running.get()) {
// Ideally we would wait some time here but the ticker task may be faster
// than 1ms, so it would halt this summary for up to 7 minutes
// Not perfect performance-wise but this is a seperate Thread anyway
}
private void finishReport() {
// We will only wait for a maximum of this many 1ms sleeps
int iterations = 1000;
if (running.get()) {
// Looks like the next profiling has already started, abort!
return;
}
// Wait for all timing results to come in
while (!running.get() && queued.get() > 0) {
try {
Thread.sleep(1);
iterations--;
totalElapsedTime = timings.values().stream().mapToLong(Long::longValue).sum();
if (!requests.isEmpty()) {
PerformanceSummary summary = new PerformanceSummary(this, totalElapsedTime, timings.size());
Iterator<CommandSender> iterator = requests.iterator();
while (iterator.hasNext()) {
summary.send(iterator.next());
iterator.remove();
// If we waited for too long, then we should just abort
if (iterations <= 0) {
return;
}
}
});
catch (InterruptedException e) {
Slimefun.getLogger().log(Level.SEVERE, "A Profiler Thread was interrupted", e);
Thread.currentThread().interrupt();
}
}
if (running.get() && queued.get() > 0) {
// Looks like the next profiling has already started, abort!
return;
}
totalElapsedTime = timings.values().stream().mapToLong(Long::longValue).sum();
if (!requests.isEmpty()) {
PerformanceSummary summary = new PerformanceSummary(this, totalElapsedTime, timings.size());
Iterator<CommandSender> iterator = requests.iterator();
while (iterator.hasNext()) {
summary.send(iterator.next());
iterator.remove();
}
}
}
/**
@ -276,6 +294,10 @@ public class SlimefunProfiler {
return NumberUtils.getAsMillis(totalElapsedTime);
}
public int getTickRate() {
return SlimefunPlugin.getTickerTask().getTickRate();
}
/**
* This method checks whether the {@link SlimefunProfiler} has collected timings on
* the given {@link Block}

View File

@ -532,7 +532,7 @@ public abstract class ProgrammableAndroid extends SlimefunItem implements Invent
private void registerDefaultFuelTypes() {
switch (getFuelSource()) {
case SOLID:
registerFuelType(new MachineFuel(800, new ItemStack(Material.COAL_BLOCK)));
registerFuelType(new MachineFuel(80, new ItemStack(Material.COAL_BLOCK)));
registerFuelType(new MachineFuel(45, new ItemStack(Material.BLAZE_ROD)));
registerFuelType(new MachineFuel(70, new ItemStack(Material.DRIED_KELP_BLOCK)));

View File

@ -0,0 +1,28 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.blocks;
import org.bukkit.entity.Wither;
import org.bukkit.entity.WitherSkull;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.core.attributes.WitherProof;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/**
* {@link HardenedGlass} is a special kind of block which cannot be destroyed by explosions.
* It is partially {@link WitherProof}, as it cannot be destroyed through explosions caused by
* a {@link WitherSkull}. However the {@link Wither} is still able to destroy it directly.
*
* @author TheBusyBiscuit
*
* @see WitherProofBlock
*
*/
public class HardenedGlass extends WitherProofBlock {
public HardenedGlass(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
super(category, item, recipeType, recipe, recipeOutput);
}
}

View File

@ -5,17 +5,19 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.bukkit.Location;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetProvider;
import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.Reactor;
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
@ -34,7 +36,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
* @see Reactor
*
*/
public abstract class AbstractEnergyProvider extends SlimefunItem implements InventoryBlock, RecipeDisplayItem, EnergyNetComponent {
public abstract class AbstractEnergyProvider extends SlimefunItem implements InventoryBlock, RecipeDisplayItem, EnergyNetProvider {
protected final Set<MachineFuel> fuelTypes = new HashSet<>();
@ -79,13 +81,48 @@ public abstract class AbstractEnergyProvider extends SlimefunItem implements Inv
return EnergyNetComponentType.GENERATOR;
}
protected abstract GeneratorTicker onTick();
/**
* @deprecated Please implement the methods
* {@link #getGeneratedOutput(org.bukkit.Location, me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config)}
* and {@link #willExplode(org.bukkit.Location, me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config)}
* instead
*
* @return A {@link GeneratorTicker}
*/
@Deprecated
protected GeneratorTicker onTick() {
return null;
}
@Override
public int getGeneratedOutput(Location l, Config data) {
if (generatorTicker != null) {
return (int) generatorTicker.generateEnergy(l, this, data);
}
else {
return 0;
}
}
@Override
public boolean willExplode(Location l, Config data) {
if (generatorTicker != null) {
return generatorTicker.explode(l);
}
else {
return false;
}
}
@Override
public void preRegister() {
super.preRegister();
addItemHandler(onTick());
GeneratorTicker ticker = onTick();
if (ticker != null) {
addItemHandler(ticker);
}
}
public void registerFuel(MachineFuel fuel) {

View File

@ -6,23 +6,25 @@ import org.bukkit.World.Environment;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetProvider;
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler;
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.handlers.GeneratorTicker;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public abstract class SolarGenerator extends SimpleSlimefunItem<GeneratorTicker> implements EnergyNetComponent {
public class SolarGenerator extends SlimefunItem implements EnergyNetProvider {
private static final int DEFAULT_NIGHT_ENERGY = 0;
private final int dayEnergy;
private final int nightEnergy;
public SolarGenerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
public SolarGenerator(Category category, int dayEnergy, int nightEnergy, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
this.dayEnergy = dayEnergy;
this.nightEnergy = nightEnergy;
}
/**
@ -31,19 +33,18 @@ public abstract class SolarGenerator extends SimpleSlimefunItem<GeneratorTicker>
*
* @return The amount of energy generated at daylight
*/
public abstract double getDayEnergy();
public int getDayEnergy() {
return dayEnergy;
}
/**
* This method returns the amount of energy that this {@link SolarGenerator}
* produces during the night.
*
* This is 0 by default.
*
* @return The amount of energy generated at night time
*/
public double getNightEnergy() {
// Override this as necessary for highly advanced Solar Generators
return DEFAULT_NIGHT_ENERGY;
public int getNightEnergy() {
return nightEnergy;
}
@Override
@ -57,40 +58,29 @@ public abstract class SolarGenerator extends SimpleSlimefunItem<GeneratorTicker>
}
@Override
public GeneratorTicker getItemHandler() {
return new GeneratorTicker() {
public int getGeneratedOutput(Location l, Config data) {
World world = l.getWorld();
@Override
public double generateEnergy(Location l, SlimefunItem item, Config data) {
World world = l.getWorld();
if (world.getEnvironment() != Environment.NORMAL) {
return 0;
}
if (world.getEnvironment() != Environment.NORMAL) {
return 0;
}
boolean isDaytime = isDaytime(world);
boolean isDaytime = isDaytime(world);
// Performance optimization for daytime-only solar generators
if (!isDaytime && getNightEnergy() < 0.1) {
return 0;
}
// Performance optimization for daytime-only solar generators
if (!isDaytime && getNightEnergy() < 0.1) {
return 0;
}
if (!world.isChunkLoaded(l.getBlockX() >> 4, l.getBlockZ() >> 4) || l.getBlock().getLightFromSky() != 15) {
return 0;
}
if (!world.isChunkLoaded(l.getBlockX() >> 4, l.getBlockZ() >> 4) || l.getBlock().getLightFromSky() != 15) {
return 0;
}
if (isDaytime) {
return getDayEnergy();
}
if (isDaytime) {
return getDayEnergy();
}
return getNightEnergy();
}
@Override
public boolean explode(Location l) {
return false;
}
};
return getNightEnergy();
}
/**

View File

@ -29,14 +29,11 @@ import io.github.thebusybiscuit.slimefun4.utils.holograms.SimpleHologram;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
import me.mrCookieSlime.Slimefun.Objects.handlers.GeneratorTicker;
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.item_transport.ItemTransportFlow;
@ -72,6 +69,8 @@ public abstract class Reactor extends AbstractEnergyProvider {
// No coolant border
private static final int[] border_4 = { 25, 34, 43 };
private final Set<Location> explosionsQueue = new HashSet<>();
public Reactor(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
@ -107,7 +106,7 @@ public abstract class Reactor extends AbstractEnergyProvider {
BlockMenu port = getAccessPort(b.getLocation());
if (port != null) {
menu.replaceExistingItem(INFO_SLOT, new CustomItem(new ItemStack(Material.GREEN_WOOL), "&7Access Port", "", "&6Detected", "", "&7> Click to view Access Port"));
menu.replaceExistingItem(INFO_SLOT, new CustomItem(Material.GREEN_WOOL, "&7Access Port", "", "&6Detected", "", "&7> Click to view Access Port"));
menu.addMenuClickHandler(INFO_SLOT, (p, slot, item, action) -> {
port.open(p);
newInstance(menu, b);
@ -116,7 +115,7 @@ public abstract class Reactor extends AbstractEnergyProvider {
});
}
else {
menu.replaceExistingItem(INFO_SLOT, new CustomItem(new ItemStack(Material.RED_WOOL), "&7Access Port", "", "&cNot detected", "", "&7Access Port must be", "&7placed 3 blocks above", "&7a reactor!"));
menu.replaceExistingItem(INFO_SLOT, new CustomItem(Material.RED_WOOL, "&7Access Port", "", "&cNot detected", "", "&7Access Port must be", "&7placed 3 blocks above", "&7a reactor!"));
menu.addMenuClickHandler(INFO_SLOT, (p, slot, item, action) -> {
newInstance(menu, b);
menu.open(p);
@ -261,89 +260,86 @@ public abstract class Reactor extends AbstractEnergyProvider {
}
@Override
protected GeneratorTicker onTick() {
return new GeneratorTicker() {
public int getGeneratedOutput(Location l, Config data) {
BlockMenu inv = BlockStorage.getInventory(l);
BlockMenu accessPort = getAccessPort(l);
private final Set<Location> explosionsQueue = new HashSet<>();
if (isProcessing(l)) {
extraTick(l);
int timeleft = progress.get(l);
@Override
public double generateEnergy(Location l, SlimefunItem sf, Config data) {
BlockMenu inv = BlockStorage.getInventory(l);
BlockMenu accessPort = getAccessPort(l);
int charge = ChargableBlock.getCharge(l);
if (timeleft > 0) {
int produced = getEnergyProduction();
int charge = 0;
if (isProcessing(l)) {
extraTick(l);
int timeleft = progress.get(l);
if (data.contains("energy-charge")) {
charge = Integer.parseInt(data.getString("energy-charge"));
}
if (timeleft > 0) {
int produced = getEnergyProduction();
int space = getCapacity() - charge;
int space = getCapacity() - charge;
if (space >= produced || !ReactorMode.GENERATOR.toString().equals(BlockStorage.getLocationInfo(l, MODE))) {
progress.put(l, timeleft - 1);
checkForWaterBlocks(l);
if (space >= produced || !ReactorMode.GENERATOR.toString().equals(BlockStorage.getLocationInfo(l, MODE))) {
progress.put(l, timeleft - 1);
checkForWaterBlocks(l);
ChestMenuUtils.updateProgressbar(inv, 22, timeleft, processing.get(l).getTicks(), getProgressBar());
ChestMenuUtils.updateProgressbar(inv, 22, timeleft, processing.get(l).getTicks(), getProgressBar());
if (needsCooling() && !hasEnoughCoolant(l, inv, accessPort, timeleft)) {
explosionsQueue.add(l);
return 0;
}
}
if (space >= produced) {
ChargableBlock.addCharge(l, getEnergyProduction());
return (double) (charge + getEnergyProduction());
}
else {
return charge;
}
}
else {
createByproduct(l, inv, accessPort);
return charge;
if (needsCooling() && !hasEnoughCoolant(l, inv, accessPort, timeleft)) {
explosionsQueue.add(l);
return 0;
}
}
if (space >= produced) {
return getEnergyProduction();
}
else {
burnNextFuel(l, inv, accessPort);
return charge;
return 0;
}
}
@Override
public boolean explode(Location l) {
boolean explosion = explosionsQueue.contains(l);
if (explosion) {
Slimefun.runSync(() -> {
ReactorExplodeEvent event = new ReactorExplodeEvent(l, Reactor.this);
Bukkit.getPluginManager().callEvent(event);
BlockStorage.getInventory(l).close();
SimpleHologram.remove(l.getBlock());
});
explosionsQueue.remove(l);
processing.remove(l);
progress.remove(l);
}
return explosion;
else {
createByproduct(l, inv, accessPort);
return 0;
}
}
else {
burnNextFuel(l, inv, accessPort);
return 0;
}
}
private void checkForWaterBlocks(Location l) {
Slimefun.runSync(() -> {
// We will pick a surrounding block at random and see if this is water.
// If it isn't, then we will make it explode.
BlockFace randomNeighbour = WATER_BLOCKS[ThreadLocalRandom.current().nextInt(WATER_BLOCKS.length)];
@Override
public boolean willExplode(Location l, Config data) {
boolean explosion = explosionsQueue.contains(l);
if (l.getBlock().getRelative(randomNeighbour).getType() != Material.WATER) {
explosionsQueue.add(l);
}
});
if (explosion) {
Slimefun.runSync(() -> {
ReactorExplodeEvent event = new ReactorExplodeEvent(l, Reactor.this);
Bukkit.getPluginManager().callEvent(event);
BlockStorage.getInventory(l).close();
SimpleHologram.remove(l.getBlock());
});
explosionsQueue.remove(l);
processing.remove(l);
progress.remove(l);
}
return explosion;
}
private void checkForWaterBlocks(Location l) {
Slimefun.runSync(() -> {
// We will pick a surrounding block at random and see if this is water.
// If it isn't, then we will make it explode.
int index = ThreadLocalRandom.current().nextInt(WATER_BLOCKS.length);
BlockFace randomNeighbour = WATER_BLOCKS[index];
if (l.getBlock().getRelative(randomNeighbour).getType() != Material.WATER) {
explosionsQueue.add(l);
}
};
});
}
private void createByproduct(Location l, BlockMenu inv, BlockMenu accessPort) {
@ -404,7 +400,8 @@ public abstract class Reactor extends AbstractEnergyProvider {
if (accessPort != null) {
for (int slot : getCoolantSlots()) {
if (SlimefunUtils.isItemSimilar(accessPort.getItemInSlot(slot), getCoolant(), true)) {
accessPort.replaceExistingItem(slot, menu.pushItem(accessPort.getItemInSlot(slot), getCoolantSlots()));
ItemStack remainingItem = menu.pushItem(accessPort.getItemInSlot(slot), getCoolantSlots());
accessPort.replaceExistingItem(slot, remainingItem);
}
}
}

View File

@ -119,12 +119,12 @@ public class ElevatorPlate extends SimpleSlimefunItem<BlockUseHandler> {
ChatComponent line;
if (block.getY() == b.getY()) {
line = new ChatComponent("\n" + ChatColor.GRAY + "> " + (floors.size() - i) + ". " + ChatColor.RESET + floor);
line.setHoverEvent(new HoverEvent(ChatColors.color(SlimefunPlugin.getLocalization().getMessage(p, "machines.ELEVATOR.current-floor")), "", ChatColor.RESET + floor, ""));
line = new ChatComponent("\n" + ChatColor.GRAY + "> " + (floors.size() - i) + ". " + ChatColor.BLACK + floor);
line.setHoverEvent(new HoverEvent(ChatColors.color(SlimefunPlugin.getLocalization().getMessage(p, "machines.ELEVATOR.current-floor")), "", ChatColor.WHITE + floor, ""));
}
else {
line = new ChatComponent("\n" + ChatColor.GRAY.toString() + (floors.size() - i) + ". " + ChatColor.RESET + floor);
line.setHoverEvent(new HoverEvent(ChatColors.color(SlimefunPlugin.getLocalization().getMessage(p, "machines.ELEVATOR.click-to-teleport")), "", ChatColor.RESET + floor, ""));
line = new ChatComponent("\n" + ChatColor.GRAY + (floors.size() - i) + ". " + ChatColor.BLACK + floor);
line.setHoverEvent(new HoverEvent(ChatColors.color(SlimefunPlugin.getLocalization().getMessage(p, "machines.ELEVATOR.click-to-teleport")), "", ChatColor.WHITE + floor, ""));
line.setClickEvent(new ClickEvent(new NamespacedKey(SlimefunPlugin.instance(), DATA_KEY + i), player -> Slimefun.runSync(() -> {
users.add(player.getUniqueId());
@ -135,7 +135,7 @@ public class ElevatorPlate extends SimpleSlimefunItem<BlockUseHandler> {
}
player.teleport(new Location(player.getWorld(), block.getX() + 0.5, block.getY() + 0.4, block.getZ() + 0.5, yaw, player.getEyeLocation().getPitch()));
player.sendTitle(ChatColor.RESET + ChatColors.color(floor), " ", 20, 60, 20);
player.sendTitle(ChatColor.WHITE + ChatColors.color(floor), " ", 20, 60, 20);
})));
}

View File

@ -15,6 +15,7 @@ import org.bukkit.inventory.EquipmentSlot;
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.cscorelib2.skull.SkullBlock;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetProvider;
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNet;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
@ -101,8 +102,8 @@ public class DebugFishListener implements Listener {
p.sendMessage(ChatColors.color("&dTicking: " + greenCheckmark));
p.sendMessage(ChatColors.color(" &dAsync: &e" + (item.getBlockTicker().isSynchronized() ? redCross : greenCheckmark)));
}
else if (item.getEnergyTicker() != null) {
p.sendMessage(ChatColors.color("&dTicking: &3Indirect"));
else if (item instanceof EnergyNetProvider) {
p.sendMessage(ChatColors.color("&dTicking: &3Indirect (Generator)"));
}
else {
p.sendMessage(ChatColors.color("&dTicking: " + redCross));

View File

@ -9,7 +9,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityExplodeEvent;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.core.attributes.WitherProof;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunBlockHandler;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
@ -29,19 +29,16 @@ public class ExplosionsListener implements Listener {
while (blocks.hasNext()) {
Block block = blocks.next();
String id = BlockStorage.checkID(block);
if (id != null) {
SlimefunItem item = BlockStorage.check(block);
if (item != null) {
blocks.remove();
// Hardened Glass and WitherProof blocks cannot be destroyed by explosions
if (!id.equals(SlimefunItems.HARDENED_GLASS.getItemId()) && !SlimefunPlugin.getRegistry().getWitherProofBlocks().containsKey(id)) {
if (!(item instanceof WitherProof)) {
SlimefunBlockHandler blockHandler = SlimefunPlugin.getRegistry().getBlockHandlers().get(item.getID());
boolean success = true;
SlimefunItem sfItem = SlimefunItem.getByID(id);
SlimefunBlockHandler blockHandler = SlimefunPlugin.getRegistry().getBlockHandlers().get(sfItem.getID());
if (blockHandler != null) {
success = blockHandler.onBreak(null, block, sfItem, UnregisterReason.EXPLODE);
success = blockHandler.onBreak(null, block, item, UnregisterReason.EXPLODE);
}
if (success) {

View File

@ -7,7 +7,9 @@ import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityChangeBlockEvent;
import io.github.thebusybiscuit.slimefun4.core.attributes.WitherProof;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
/**
@ -28,15 +30,12 @@ public class WitherListener implements Listener {
@EventHandler(ignoreCancelled = true)
public void onWitherDestroy(EntityChangeBlockEvent e) {
if (e.getEntity().getType() == EntityType.WITHER) {
String id = BlockStorage.checkID(e.getBlock());
SlimefunItem item = BlockStorage.check(e.getBlock());
if (id != null) {
WitherProof witherproof = SlimefunPlugin.getRegistry().getWitherProofBlocks().get(id);
if (witherproof != null) {
e.setCancelled(true);
witherproof.onAttack(e.getBlock(), (Wither) e.getEntity());
}
// Hardened Glass is excluded from here
if (item instanceof WitherProof && !item.getID().equals(SlimefunItems.HARDENED_GLASS.getItemId())) {
e.setCancelled(true);
((WitherProof) item).onAttack(e.getBlock(), (Wither) e.getEntity());
}
}
}

View File

@ -10,6 +10,7 @@ import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.potion.PotionData;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.potion.PotionType;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections;
@ -43,6 +44,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.BrokenSpaw
import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.Composter;
import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.Crucible;
import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.EnhancedFurnace;
import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.HardenedGlass;
import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.HologramProjector;
import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.InfusedHopper;
import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.RainbowBlock;
@ -181,7 +183,6 @@ import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
import org.bukkit.potion.PotionType;
/**
* This static utility class holds the recipes of all items.
@ -1439,7 +1440,7 @@ public final class SlimefunItemSetup {
new ItemStack[] {new CustomItem(SlimefunItems.REINFORCED_ALLOY_INGOT, 8), null, null, null, null, null, null, null, null})
.register(plugin);
new SlimefunItem(categories.technicalComponents, SlimefunItems.HARDENED_GLASS, RecipeType.ENHANCED_CRAFTING_TABLE,
new HardenedGlass(categories.technicalComponents, SlimefunItems.HARDENED_GLASS, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {new ItemStack(Material.GLASS), new ItemStack(Material.GLASS), new ItemStack(Material.GLASS), new ItemStack(Material.GLASS), SlimefunItems.REINFORCED_PLATE, new ItemStack(Material.GLASS), new ItemStack(Material.GLASS), new ItemStack(Material.GLASS), new ItemStack(Material.GLASS)},
new CustomItem(SlimefunItems.HARDENED_GLASS, 16))
.register(plugin);
@ -1495,50 +1496,21 @@ public final class SlimefunItemSetup {
new ItemStack[] {SlimefunItems.CARBONADO, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.CARBONADO, new ItemStack(Material.REDSTONE), SlimefunItems.LARGE_CAPACITOR, new ItemStack(Material.REDSTONE), SlimefunItems.CARBONADO, SlimefunItems.REDSTONE_ALLOY, SlimefunItems.CARBONADO})
.register(plugin);
new SolarGenerator(categories.electricity, SlimefunItems.SOLAR_GENERATOR, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.SOLAR_PANEL, SlimefunItems.SOLAR_PANEL, SlimefunItems.SOLAR_PANEL, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.ALUMINUM_INGOT, null, SlimefunItems.ALUMINUM_INGOT, null}) {
new SolarGenerator(categories.electricity, 2, 0, SlimefunItems.SOLAR_GENERATOR, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.SOLAR_PANEL, SlimefunItems.SOLAR_PANEL, SlimefunItems.SOLAR_PANEL, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.ELECTRIC_MOTOR, SlimefunItems.ALUMINUM_INGOT, null, SlimefunItems.ALUMINUM_INGOT, null})
.register(plugin);
@Override
public double getDayEnergy() {
return 2;
}
}.register(plugin);
new SolarGenerator(categories.electricity, 8, 0, SlimefunItems.SOLAR_GENERATOR_2, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.SOLAR_GENERATOR, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.SOLAR_GENERATOR, SlimefunItems.ALUMINUM_INGOT, new ItemStack(Material.REDSTONE), SlimefunItems.ALUMINUM_INGOT, SlimefunItems.SOLAR_GENERATOR, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.SOLAR_GENERATOR})
.register(plugin);
new SolarGenerator(categories.electricity, SlimefunItems.SOLAR_GENERATOR_2, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.SOLAR_GENERATOR, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.SOLAR_GENERATOR, SlimefunItems.ALUMINUM_INGOT, new ItemStack(Material.REDSTONE), SlimefunItems.ALUMINUM_INGOT, SlimefunItems.SOLAR_GENERATOR, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.SOLAR_GENERATOR}) {
new SolarGenerator(categories.electricity, 32, 0, SlimefunItems.SOLAR_GENERATOR_3, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.SOLAR_GENERATOR_2, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.SOLAR_GENERATOR_2, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.CARBONADO, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.SOLAR_GENERATOR_2, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.SOLAR_GENERATOR_2})
.register(plugin);
@Override
public double getDayEnergy() {
return 8;
}
}.register(plugin);
new SolarGenerator(categories.electricity, SlimefunItems.SOLAR_GENERATOR_3, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.SOLAR_GENERATOR_2, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.SOLAR_GENERATOR_2, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.CARBONADO, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.SOLAR_GENERATOR_2, SlimefunItems.ALUMINUM_INGOT, SlimefunItems.SOLAR_GENERATOR_2}) {
@Override
public double getDayEnergy() {
return 32;
}
}.register(plugin);
new SolarGenerator(categories.electricity, SlimefunItems.SOLAR_GENERATOR_4, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.SOLAR_GENERATOR_3, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.SOLAR_GENERATOR_3, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.SOLAR_GENERATOR_3, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.SOLAR_GENERATOR_3}) {
@Override
public double getDayEnergy() {
return 128;
}
@Override
public double getNightEnergy() {
return 64;
}
}.register(plugin);
new SolarGenerator(categories.electricity, 128, 64, SlimefunItems.SOLAR_GENERATOR_4, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.SOLAR_GENERATOR_3, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.SOLAR_GENERATOR_3, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.SOLAR_GENERATOR_3, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.SOLAR_GENERATOR_3})
.register(plugin);
new ChargingBench(categories.electricity, SlimefunItems.CHARGING_BENCH, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {null, SlimefunItems.ELECTRO_MAGNET, null, SlimefunItems.BATTERY, new ItemStack(Material.CRAFTING_TABLE), SlimefunItems.BATTERY, null, SlimefunItems.SMALL_CAPACITOR, null})

View File

@ -32,6 +32,7 @@ public class TickerTask implements Runnable {
private final Map<Location, Boolean> deletionQueue = new ConcurrentHashMap<>();
private final Map<BlockPosition, Integer> bugs = new ConcurrentHashMap<>();
private int tickRate;
private boolean halted = false;
private boolean running = false;
@ -100,16 +101,20 @@ public class TickerTask implements Runnable {
if (item != null && item.getBlockTicker() != null) {
try {
long timestamp = SlimefunPlugin.getProfiler().newEntry();
Block b = l.getBlock();
item.getBlockTicker().update();
if (item.getBlockTicker().isSynchronized()) {
// We are ignoring the timestamp from above because synchronized actions
// are always ran with a 50ms delay (1 game tick)
Slimefun.runSync(() -> tickBlock(l, b, item, data, System.nanoTime()));
SlimefunPlugin.getProfiler().scheduleEntries(1);
item.getBlockTicker().update();
// We are inserting a new timestamp because synchronized
// actions are always ran with a 50ms delay (1 game tick)
Slimefun.runSync(() -> {
Block b = l.getBlock();
tickBlock(l, b, item, data, System.nanoTime());
});
}
else {
long timestamp = SlimefunPlugin.getProfiler().newEntry();
item.getBlockTicker().update();
Block b = l.getBlock();
tickBlock(l, b, item, data, timestamp);
}
@ -179,6 +184,8 @@ public class TickerTask implements Runnable {
}
public void start(SlimefunPlugin plugin) {
this.tickRate = SlimefunPlugin.getCfg().getInt("URID.custom-ticker-delay");
plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, () -> {
try {
run();
@ -187,7 +194,11 @@ public class TickerTask implements Runnable {
plugin.getLogger().log(Level.SEVERE, x, () -> "An Exception was caught while ticking the Block Tickers Task for Slimefun v" + SlimefunPlugin.getVersion());
abortTick();
}
}, 100L, SlimefunPlugin.getCfg().getInt("URID.custom-ticker-delay"));
}, 100L, tickRate);
}
public int getTickRate() {
return tickRate;
}
}

View File

@ -40,13 +40,17 @@ public final class SimpleHologram {
Location l = new Location(b.getWorld(), b.getX() + 0.5, b.getY() + 0.7F, b.getZ() + 0.5);
for (Entity n : l.getChunk().getEntities()) {
if (n instanceof ArmorStand && n.getCustomName() != null && l.distanceSquared(n.getLocation()) < 0.4D) {
if (n instanceof ArmorStand && l.distanceSquared(n.getLocation()) < 0.4D && n.getCustomName() != null) {
return (ArmorStand) n;
}
}
if (!createIfNoneExists) return null;
else return create(l);
if (!createIfNoneExists) {
return null;
}
else {
return create(l);
}
}
public static ArmorStand create(Location l) {

View File

@ -75,6 +75,7 @@ public class Category implements Keyed {
ItemMeta meta = item.getItemMeta();
meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
meta.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS);
this.item.setItemMeta(meta);
this.tier = tier;
}
@ -132,7 +133,10 @@ public class Category implements Keyed {
public ItemStack getItem(Player p) {
return new CustomItem(item, meta -> {
String name = SlimefunPlugin.getLocalization().getCategoryName(p, getKey());
if (name == null) name = item.getItemMeta().getDisplayName();
if (name == null) {
name = item.getItemMeta().getDisplayName();
}
if (this instanceof SeasonalCategory) {
meta.setDisplayName(ChatColor.GOLD + name);
@ -199,6 +203,7 @@ public class Category implements Keyed {
*
* @param p
* The {@link Player} to check for
*
* @return Whether this {@link Category} will be hidden to the given {@link Player}
*/
public boolean isHidden(Player p) {
@ -211,4 +216,14 @@ public class Category implements Keyed {
return true;
}
/**
* This method returns whether this {@link Category} has been registered yet.
* More specifically: Whether {@link #register()} was called or not.
*
* @return Whether this {@link Category} has been registered
*/
public boolean isRegistered() {
return SlimefunPlugin.getRegistry().getCategories().contains(this);
}
}

View File

@ -1,31 +0,0 @@
package me.mrCookieSlime.Slimefun.Objects.SlimefunItem;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.core.attributes.Rechargeable;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
import me.mrCookieSlime.Slimefun.api.energy.ItemEnergy;
/**
* This class is deprecated.
*
* @deprecated Please implement the {@link Rechargeable} interface from now on.
*
* @author TheBusyBiscuit
*
*/
@Deprecated
public class ChargableItem extends SlimefunItem implements Rechargeable {
public ChargableItem(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
}
@Override
public float getMaxItemCharge(ItemStack item) {
return ItemEnergy.getMaxEnergy(item);
}
}

View File

@ -28,10 +28,10 @@ import io.github.thebusybiscuit.slimefun4.api.exceptions.WrongItemStackException
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.api.items.ItemState;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetProvider;
import io.github.thebusybiscuit.slimefun4.core.attributes.Placeable;
import io.github.thebusybiscuit.slimefun4.core.attributes.Radioactive;
import io.github.thebusybiscuit.slimefun4.core.attributes.Rechargeable;
import io.github.thebusybiscuit.slimefun4.core.attributes.WitherProof;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide;
import io.github.thebusybiscuit.slimefun4.core.researching.Research;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
@ -74,7 +74,7 @@ public class SlimefunItem implements Placeable {
private boolean ticking = false;
private BlockTicker blockTicker;
private GeneratorTicker generatorTicker;
protected GeneratorTicker generatorTicker;
/**
* This creates a new {@link SlimefunItem} from the given arguments.
@ -320,7 +320,11 @@ public class SlimefunItem implements Placeable {
return blockTicker;
}
// We should maybe refactor this and move it to a subclass
/**
* @deprecated The interface {@link EnergyNetProvider} should be implemented instead
* @return A {@link GeneratorTicker}
*/
@Deprecated
public GeneratorTicker getEnergyTicker() {
return generatorTicker;
}
@ -378,17 +382,17 @@ public class SlimefunItem implements Placeable {
SlimefunPlugin.getRegistry().getRadioactiveItems().add(this);
}
if (this instanceof WitherProof) {
SlimefunPlugin.getRegistry().getWitherProofBlocks().put(id, (WitherProof) this);
}
if (this instanceof EnergyNetComponent && !SlimefunPlugin.getRegistry().getEnergyCapacities().containsKey(getID())) {
((EnergyNetComponent) this).registerComponent(id);
int capacity = ((EnergyNetComponent) this).getCapacity();
if (capacity > 0) {
SlimefunPlugin.getRegistry().getEnergyCapacities().put(id, capacity);
}
}
if (SlimefunPlugin.getItemCfg().getBoolean(id + ".enabled")) {
if (!SlimefunPlugin.getRegistry().getCategories().contains(category)) {
if (!category.isRegistered()) {
category.register();
}

View File

@ -23,8 +23,6 @@ import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu.AdvancedMenu
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ClickAction;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.handlers.GeneratorTicker;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
import me.mrCookieSlime.Slimefun.api.energy.ChargableBlock;
@ -58,8 +56,12 @@ public abstract class AGenerator extends AbstractEnergyProvider {
@Override
public int[] getSlotsAccessedByItemTransport(ItemTransportFlow flow) {
if (flow == ItemTransportFlow.INSERT) return getInputSlots();
else return getOutputSlots();
if (flow == ItemTransportFlow.INSERT) {
return getInputSlots();
}
else {
return getOutputSlots();
}
}
};
@ -80,6 +82,7 @@ public abstract class AGenerator extends AbstractEnergyProvider {
}
}
}
progress.remove(b.getLocation());
processing.remove(b.getLocation());
return true;
@ -138,71 +141,60 @@ public abstract class AGenerator extends AbstractEnergyProvider {
}
@Override
protected GeneratorTicker onTick() {
return new GeneratorTicker() {
public int getGeneratedOutput(Location l, Config data) {
BlockMenu inv = BlockStorage.getInventory(l);
boolean chargeable = getCapacity() > 0;
@Override
public double generateEnergy(Location l, SlimefunItem sf, Config data) {
BlockMenu inv = BlockStorage.getInventory(l);
boolean chargeable = getCapacity() > 0;
int charge = chargeable ? ChargableBlock.getCharge(l) : 0;
if (isProcessing(l)) {
int timeleft = progress.get(l);
if (isProcessing(l)) {
int timeleft = progress.get(l);
if (timeleft > 0) {
ChestMenuUtils.updateProgressbar(inv, 22, timeleft, processing.get(l).getTicks(), getProgressBar());
if (timeleft > 0) {
ChestMenuUtils.updateProgressbar(inv, 22, timeleft, processing.get(l).getTicks(), getProgressBar());
if (chargeable) {
int charge = ChargableBlock.getCharge(l);
if (chargeable) {
if (getCapacity() - charge >= getEnergyProduction()) {
ChargableBlock.addCharge(l, getEnergyProduction());
progress.put(l, timeleft - 1);
return (double) (charge + getEnergyProduction());
}
return charge;
}
else {
progress.put(l, timeleft - 1);
return getEnergyProduction();
}
if (getCapacity() - charge >= getEnergyProduction()) {
progress.put(l, timeleft - 1);
return getEnergyProduction();
}
else {
ItemStack fuel = processing.get(l).getInput();
if (isBucket(fuel)) {
inv.pushItem(new ItemStack(Material.BUCKET), getOutputSlots());
}
inv.replaceExistingItem(22, new CustomItem(Material.BLACK_STAINED_GLASS_PANE, " "));
progress.remove(l);
processing.remove(l);
return charge;
}
return 0;
}
else {
Map<Integer, Integer> found = new HashMap<>();
MachineFuel fuel = findRecipe(inv, found);
if (fuel != null) {
for (Map.Entry<Integer, Integer> entry : found.entrySet()) {
inv.consumeItem(entry.getKey(), entry.getValue());
}
processing.put(l, fuel);
progress.put(l, fuel.getTicks());
}
return charge;
progress.put(l, timeleft - 1);
return getEnergyProduction();
}
}
else {
ItemStack fuel = processing.get(l).getInput();
@Override
public boolean explode(Location l) {
return false;
if (isBucket(fuel)) {
inv.pushItem(new ItemStack(Material.BUCKET), getOutputSlots());
}
inv.replaceExistingItem(22, new CustomItem(Material.BLACK_STAINED_GLASS_PANE, " "));
progress.remove(l);
processing.remove(l);
return 0;
}
};
}
else {
Map<Integer, Integer> found = new HashMap<>();
MachineFuel fuel = findRecipe(inv, found);
if (fuel != null) {
for (Map.Entry<Integer, Integer> entry : found.entrySet()) {
inv.consumeItem(entry.getKey(), entry.getValue());
}
processing.put(l, fuel);
progress.put(l, fuel.getTicks());
}
return 0;
}
}
private boolean isBucket(ItemStack item) {

View File

@ -1,9 +0,0 @@
package me.mrCookieSlime.Slimefun.Objects.handlers;
/**
* @deprecated Moved to {@link io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler}
*/
@Deprecated
public interface BlockBreakHandler extends io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler {
}

View File

@ -6,11 +6,17 @@ import org.bukkit.Location;
import io.github.thebusybiscuit.slimefun4.api.exceptions.IncompatibleItemHandlerException;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetProvider;
import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
/**
* @deprecated Please implement the {@link EnergyNetProvider} interface instead.
*
*/
@Deprecated
public abstract class GeneratorTicker implements ItemHandler {
public abstract double generateEnergy(Location l, SlimefunItem item, Config data);

View File

@ -1,9 +0,0 @@
package me.mrCookieSlime.Slimefun.Objects.handlers;
/**
* @deprecated Moved to {@link io.github.thebusybiscuit.slimefun4.core.handlers.MultiBlockInteractionHandler}
*/
@Deprecated
public interface MultiBlockInteractionHandler extends io.github.thebusybiscuit.slimefun4.core.handlers.MultiBlockInteractionHandler {
}

View File

@ -1,150 +0,0 @@
package me.mrCookieSlime.Slimefun;
import java.util.Set;
import org.bukkit.plugin.Plugin;
import io.github.thebusybiscuit.cscorelib2.config.Config;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectionManager;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.gps.GPSNetwork;
import io.github.thebusybiscuit.slimefun4.core.SlimefunRegistry;
import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
import io.github.thebusybiscuit.slimefun4.core.networks.NetworkManager;
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.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.plugins.ThirdPartyPluginService;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.AncientAltarListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.BackpackListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.GrapplingHookListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunBowListener;
import io.github.thebusybiscuit.slimefun4.implementation.tasks.TickerTask;
import me.mrCookieSlime.CSCoreLibPlugin.CSCoreLib;
/**
* @deprecated This class has been moved to {@link io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin}
*
* @author TheBusyBiscuit
*
*/
@Deprecated
public final class SlimefunPlugin {
private SlimefunPlugin() {}
public static Config getCfg() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getCfg();
}
public static Config getResearchCfg() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getResearchCfg();
}
public static Config getItemCfg() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getItemCfg();
}
public static GPSNetwork getGPSNetwork() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getGPSNetwork();
}
public static TickerTask getTicker() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getTickerTask();
}
public static String getVersion() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getVersion();
}
public static ProtectionManager getProtectionManager() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getProtectionManager();
}
public static LocalizationService getLocal() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getLocalization();
}
public static MinecraftRecipeService getMinecraftRecipes() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getMinecraftRecipeService();
}
public static CustomItemDataService getItemDataService() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getItemDataService();
}
public static CustomTextureService getItemTextureService() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getItemTextureService();
}
public static PermissionsService getPermissionsService() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getPermissionsService();
}
public static BlockDataService getBlockDataService() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getBlockDataService();
}
public static ThirdPartyPluginService getThirdPartySupportService() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getThirdPartySupportService();
}
public static PerWorldSettingsService getWorldSettingsService() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getWorldSettingsService();
}
public static UpdaterService getUpdater() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getUpdater();
}
public static GitHubService getGitHubService() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getGitHubService();
}
public static SlimefunRegistry getRegistry() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getRegistry();
}
public static NetworkManager getNetworkManager() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getNetworkManager();
}
public static AncientAltarListener getAncientAltarListener() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getAncientAltarListener();
}
public static GrapplingHookListener getGrapplingHookListener() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getGrapplingHookListener();
}
public static BackpackListener getBackpackListener() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getBackpackListener();
}
public static SlimefunBowListener getBowListener() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getBowListener();
}
public static Set<Plugin> getInstalledAddons() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getInstalledAddons();
}
public static SlimefunCommand getCommand() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getCommand();
}
public static MinecraftVersion getMinecraftVersion() {
return io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin.getMinecraftVersion();
}
public static String getCSCoreLibVersion() {
return CSCoreLib.getLib().getDescription().getVersion();
}
}

View File

@ -4,7 +4,6 @@ import java.util.Optional;
import java.util.logging.Logger;
import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitTask;
@ -14,7 +13,6 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemState;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.VanillaItem;
import me.mrCookieSlime.Slimefun.Objects.Research;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
/**
@ -32,48 +30,6 @@ public final class Slimefun {
return SlimefunPlugin.instance().getLogger();
}
/**
* Registers a research.
*
* @deprecated The Research class was moved, this method is no longer valid. Please use
* {@link io.github.thebusybiscuit.slimefun4.core.researching.Research#register()} instead.
*
* @param research
* The research
* @param items
* The items
*/
@Deprecated
public static void registerResearch(Research research, ItemStack... items) {
for (ItemStack item : items) {
research.addItems(SlimefunItem.getByItem(item));
}
research.register();
}
/**
* Registers a research.
*
* @deprecated The Research class was moved, this method is no longer valid. Please use
* {@link io.github.thebusybiscuit.slimefun4.core.researching.Research#register()} instead.
*
* @param key
* The key
* @param id
* The id
* @param name
* The name
* @param cost
* The default cost
* @param items
* The items
*/
@Deprecated
public static void registerResearch(NamespacedKey key, int id, String name, int cost, ItemStack... items) {
registerResearch(new Research(key, id, name, cost), items);
}
/**
* Checks if this player can use this item.
*

View File

@ -6,7 +6,9 @@ import org.bukkit.block.Block;
import io.github.thebusybiscuit.cscorelib2.skull.SkullBlock;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.Capacitor;
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;
@ -103,7 +105,7 @@ public final class ChargableBlock {
setCharge(l, charge);
if (SlimefunPlugin.getRegistry().getEnergyCapacitors().contains(id)) {
if (SlimefunItem.getByID(id) instanceof Capacitor) {
updateCapacitor(l, charge, capacity);
}
}
@ -111,7 +113,7 @@ public final class ChargableBlock {
charge += addedCharge;
setCharge(l, charge);
if (SlimefunPlugin.getRegistry().getEnergyCapacitors().contains(id)) {
if (SlimefunItem.getByID(id) instanceof Capacitor) {
updateCapacitor(l, charge, capacity);
}
}

View File

@ -1,118 +0,0 @@
package me.mrCookieSlime.Slimefun.api.energy;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.slimefun4.core.attributes.Rechargeable;
import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
/**
* @deprecated Please implement {@link Rechargeable} on your {@link SlimefunItem} instead.
*
* @author TheBusyBiscuit
*
*/
@Deprecated
public final class ItemEnergy {
// We should find a replacement for this class
// Perhaps we could also use PersistentData here too?
private ItemEnergy() {}
// "&c&o&8\u21E8 &e\u26A1 &70 / 50 J"
public static float getStoredEnergy(ItemStack item) {
if (item == null || item.getType() == Material.AIR || item.getAmount() < 1) return 0F;
if (!item.hasItemMeta() || !item.getItemMeta().hasLore()) return 0F;
for (String line : item.getItemMeta().getLore()) {
if (line.startsWith(ChatColors.color("&c&o&8\u21E8 &e\u26A1 &7")) && line.contains(" / ") && line.endsWith(" J")) {
return Float.parseFloat(PatternUtils.SLASH_SEPARATOR.split(line)[0].replace(ChatColors.color("&c&o&8\u21E8 &e\u26A1 &7"), ""));
}
}
return 0F;
}
public static float getMaxEnergy(ItemStack item) {
if (item == null || item.getType() == Material.AIR || item.getAmount() < 1) return 0F;
if (!item.hasItemMeta() || !item.getItemMeta().hasLore()) return 0F;
for (String line : item.getItemMeta().getLore()) {
if (line.startsWith(ChatColors.color("&c&o&8\u21E8 &e\u26A1 &7")) && line.contains(" / ") && line.endsWith(" J")) {
return Float.parseFloat(PatternUtils.SLASH_SEPARATOR.split(line)[1].replace(" J", ""));
}
}
return 0F;
}
public static float addStoredEnergy(ItemStack item, float energy) {
if (item == null || item.getType() == Material.AIR || item.getAmount() < 1) return 0F;
if (!item.hasItemMeta() || !item.getItemMeta().hasLore()) return 0;
float rest = 0F;
float capacity = getMaxEnergy(item);
if ((int) capacity == 0) {
return rest;
}
float stored = getStoredEnergy(item);
if (stored + energy > capacity) {
rest = (stored + energy) - capacity;
stored = capacity;
}
else if (stored + energy < 0) {
stored = 0F;
}
else {
stored = stored + energy;
}
List<String> lore = item.getItemMeta().getLore();
int index = -1;
for (int i = 0; i < lore.size(); i++) {
String line = lore.get(i);
if (line.startsWith(ChatColors.color("&c&o&8\u21E8 &e\u26A1 &7")) && line.contains(" / ") && line.endsWith(" J")) {
index = i;
break;
}
}
BigDecimal decimal = BigDecimal.valueOf(stored).setScale(2, RoundingMode.HALF_UP);
lore.set(index, ChatColors.color("&c&o&8\u21E8 &e\u26A1 &7") + decimal.floatValue() + " / " + capacity + " J");
ItemMeta im = item.getItemMeta();
im.setLore(lore);
item.setItemMeta(im);
return rest;
}
public static ItemStack chargeItem(ItemStack item, float energy) {
addStoredEnergy(item, energy);
return item;
}
public static void chargeInventory(Player p, float energy) {
p.getInventory().setItemInMainHand(chargeItem(p.getInventory().getItemInMainHand(), energy));
p.getInventory().setItemInOffHand(chargeItem(p.getInventory().getItemInOffHand(), energy));
p.getInventory().setHelmet(chargeItem(p.getInventory().getHelmet(), energy));
p.getInventory().setChestplate(chargeItem(p.getInventory().getChestplate(), energy));
p.getInventory().setLeggings(chargeItem(p.getInventory().getLeggings(), energy));
p.getInventory().setBoots(chargeItem(p.getInventory().getBoots(), energy));
}
}

View File

@ -2,10 +2,10 @@
slimefun:
weapons: Senjata
tools: Peralatan
items: Alat Penting
items: Barang yang Berguna
food: Makanan
basic_machines: Mesin Dasar
electricity: Energi Dan Listrik
electricity: Energi dan Listrik
gps: Mesin - Mesin GPS
armor: Baju Zirah
magical_items: Benda Sihir
@ -13,13 +13,14 @@ slimefun:
misc: Lain - Lain
technical_gadgets: Alat Teknis
resources: Sumber Daya
cargo: Pengatur Muatan
cargo: Manajemen Kargo
tech_misc: Komponen Teknis
magical_armor: Pakaian Sihir
talismans: Jimat (Tingkat I)
ender_talismans: Jimat Ender (Tingkat II)
christmas: Natal (Desember)
valentines_day: Hari Valentine (14 Februari)
easter: Easter (April)
easter: Paskah (April)
birthday: Ulang Tahun TheBusyBiscuit (26 Oktober)
halloween: Halloween (31 Oktober)
androids: Mesin Berprogram

View File

@ -23,3 +23,4 @@ slimefun:
easter: Wielkanoc (Kwiecień)
birthday: Urodziny TheBusyBiscuit (26 Października)
halloween: Halloween (31 Października)
androids: Programowalne Androidy

View File

@ -1,184 +1,132 @@
---
android:
scripts:
already-uploaded: "&4Ten skrypt został już przesłany."
enter-name:
-
- "&eProszę wpisać nazwę dla tego skryptu"
instructions:
ATTACK_ANIMALS: "&4Atakuj &c(Zwierzęta)"
ATTACK_ANIMALS_ADULT: "&4Atakuj &c(Zwierzęta &7[Dorosłe]&c)"
ATTACK_MOBS: "&4Atakuj &c(Wrogie Moby)"
ATTACK_MOBS_ANIMALS: "&4Atakuj &c(Wrogie Moby i Zwierzęta)"
CATCH_FISH: "&bŁów ryby"
CHOP_TREE: "&cTnij drzewo i posadź sadzonkę"
DIG_DOWN: "&bKop w dół"
DIG_FORWARD: "&bKop do przodu"
DIG_UP: "&bKop w górę"
FARM_DOWN: "&bZbieraj i posadź z powrotem &7(Blok pod spodem)"
FARM_EXOTIC_DOWN: "&bZaawansowanie zbieraj i posadź z powrotem &7(Blok pod spodem)"
FARM_EXOTIC_FORWARD: "&6Zaawansowanie zbieraj i posadź z powrotem"
FARM_FORWARD: "&bZbieraj i posadź z powrotem"
GO_DOWN: "&7Idź w dół"
GO_FORWARD: "&7Idź do przodu"
GO_UP: "&7Idź do góry"
INTERFACE_FUEL: "&cOtrzymaj paliwo z Interfejsu w obecnym kierunku"
INTERFACE_ITEMS: "&9Wyślij zawartość ekwipunku do Interfejsu w obecnym kierunku"
MOVE_AND_DIG_DOWN: "&bIdź i kop w dół"
MOVE_AND_DIG_FORWARD: "&bIdź i kop do przodu"
MOVE_AND_DIG_UP: "&bIdź i kop w górę"
REPEAT: "&9 Powtórz skrypt"
START: "&2Uruchom skrypt"
TURN_LEFT: "&7Skręć w lewo"
TURN_RIGHT: "&7Skręć w prawo"
WAIT: "&ePoczekaj 0.5s"
rating:
already: "&4Oceniłeś już ten skrypt!"
own: "&4Nie możesz ocenić własnego skryptu!"
uploaded:
- "&bPrzesyłanie..."
- "&aPomyślnie przesłano twój skrypt!"
started: "&7Twój Android wznowił swój skrypt"
stopped: "&7Twój Android wstrzymał swój skrypt"
anvil:
not-working: "&4Nie możesz używać przedmiotów Slimefun w kowadle!"
backpack:
already-open: "&cPrzepraszamy, ten plecak jest otwarty gdzie indziej!"
no-stack: "&cNie możesz stakować plecaków"
commands:
help: Pokazuje ten ekran pomocy
cheat: Daje graczowi przedmioty Slimefun.
give: Daj graczowi przedmioty Slimefun
guide: Daje ci przewodnik Slimefun
help: Pokazuje ten ekran pomocy
timings: Informacje o opóźnieniu na twoim serwerze
teleporter: Zobacz punkty lokalizacji innych graczy
versions: Wyświetla listę wszystkich zainstalowanych dodatków
search: Przeszukuje twój przewodnik dla podanego terminu
open_guide: Otwiera przewodnik Slimefun bez korzystania z książki
stats: Pokazuje niektóre statystyki dotyczące gracza
research:
description: Odblokuj/Zresetuj badania dla gracza
reset: "&cZresetowano wiedzę gracza %player%"
reset-target: "&c Twoja wiedza została zresetowana"
search: Przeszukuje twój przewodnik dla podanego terminu
stats: Pokazuje niektóre statystyki dotyczące gracza
teleporter: Zobacz punkty lokalizacji innych graczy
timings: Informacje o opóźnieniu na twoim serwerze
versions: Wyświetla listę wszystkich zainstalowanych dodatków
cheat: Daje graczowi przedmioty Slimefun.
gps:
deathpoint: "&4Punkt śmierci &7%date%"
geo:
scan-required: "&4Wymagany jest skan GEO-Skan! &cNajpierw zeskanuj ten fragment
za pomocą skanera GEO!"
insufficient-complexity:
- "&4Niewystarczająca złożoność sieci GPS: &c%complexity%"
- "&4a) Nie masz jeszcze skonfigurowanej sieci GPS"
- "&4b) Twoja sieć GPS nie jest wystarczająco złożona"
waypoint:
added: "&aPomyślnie dodano nowy punkt trasy"
max: "&4Osiągnięto maksymalną liczbę punktów trasy"
new: "&eProszę wpisać nazwę swojego nowego punktu trasy na czacie. &7(Kody kolorów
są obsługiwane!)"
guide:
cheat:
no-multiblocks: "&4Nie możesz otrzymać Multibloków, musisz je zbudować!"
credits:
commit: Rejestracja zmian
commits: Rejestracje zmian
profile-link: Kliknij, aby odwiedzić ich profil na GitHub
roles:
developer: "&6Developer"
resourcepack: "&cArtysta paczki zasobów"
translator: "&9Tłumacz"
wiki: "&3Edytor Wiki"
languages:
select: Kliknij, aby wybrać ten język
select-default: Kliknij, aby wybrać domyślny język
selected-language: 'Aktualnie wybrane:'
translations:
lore: Kliknij, aby dodać własne tłumaczenie
name: "&aCzegoś brakuje?"
updated: "&aTwój język został pomyślnie ustawiony na: &b%lang%"
pages:
next: Kolejna strona
previous: Poprzednia strona
search:
message: "&bCo chcesz wyszukać?"
name: "&7Szukaj..."
tooltip: "&bKliknij, aby wyszukać przedmiot"
inventory: 'Wyszukiwanie dla: % item%'
lore:
- "&bCo chcesz wyszukać?"
- "&7Wpisz wyszukiwane hasło na czacie"
message: "&bCo chcesz wyszukać?"
name: "&7Szukaj..."
cheat:
no-multiblocks: "&4Nie możesz otrzymać Multibloków, musisz je zbudować!"
languages:
updated: "&aTwój język został pomyślnie ustawiony na: &b%lang%"
translations:
name: "&aCzegoś brakuje?"
lore: Kliknij, aby dodać własne tłumaczenie
select: Kliknij, aby wybrać ten język
select-default: Kliknij, aby wybrać domyślny język
selected-language: 'Aktualnie wybrane:'
title:
addons: Dodatki dla Slimefun4
bugs: Zgłaszanie błędów
credits: Autorzy Slimefun4
languages: Wybierz preferowany język
main: Przewodnik Slimefun
settings: Ustawienia i informacje
languages: Wybierz preferowany język
credits: Autorzy Slimefun4
wiki: Wiki Slimefun4
addons: Dodatki dla Slimefun4
bugs: Zgłaszanie błędów
source: Kod Źródłowy
credits:
commit: Rejestracja zmian
commits: Rejestracje zmian
roles:
developer: "&6Developer"
wiki: "&3Edytor Wiki"
resourcepack: "&cArtysta paczki zasobów"
translator: "&9Tłumacz"
profile-link: Kliknij, aby odwiedzić ich profil na GitHub
pages:
previous: Poprzednia strona
next: Kolejna strona
tooltips:
open-category: Kliknij, aby otworzyć
versions-notice: Jest to bardzo ważne przy zgłaszaniu błędów!
inventory:
no-access: "&4Nie masz dostępu do tego bloku"
languages:
cs: Czeski
de: Niemiecki
default: Domyślny serwera
el: Grecki
en: Język angielski
es: Hiszpański
fr: Francuski
he: Hebrajski
hu: Węgierski
id: Indonezyjski
it: Włoski
lv: Łotewski
nl: Holenderski
pl: Polski
pt: Portugalski (Portugalia)
pt-BR: Portugalski (Brazylia)
ru: Rosyjski
sk: Słowacki
sv: Szwedzki
vi: Wietnamski
zh-CN: Chiński (Chiny)
zh-TW: Chiński (Tajwan)
machines:
ANCIENT_ALTAR:
not-enough-pedestals: "&4Ołtarz nie jest otoczony potrzebną ilością cokołów &c(%pedestals%
/ 8)"
unknown-catalyst: "&4Nieznany katalizator! &cZamiast tego użyj prawidłowego przepisu!"
unknown-recipe: "&4Nieznany przepis! &cZamiast tego użyj prawidłowego przepisu!"
ANCIENT_PEDESTAL:
obstructed: "&4Piedestał jest zablokowany! &cUsuń wszystko nad piedestałem!"
CARGO_NODES:
must-be-placed: "&4Musi być umieszczony na skrzyni lub maszynie!"
ELEVATOR:
click-to-teleport: "&eKliknij &7aby teleportować się na to piętro:"
current-floor: "&eTo jest piętro, na którym aktualnie jesteś:"
enter-name: "&7Wprowadź żądaną nazwę piętra na czacie. &r(Kody kolorów są obsługiwane!)"
named: "&2Pomyślnie nazwano podłogę: &r% floor%"
no-destinations: "&4Nie znaleziono miejsc docelowych"
pick-a-floor: "&3- Wybierz piętro-"
full-inventory: "&eEkwipunek jest pełny!"
HOLOGRAM_PROJECTOR:
enter-text: "&7Wprowadź żądany tekst hologramu na czacie. &r(Kody kolorów są obsługiwane!)"
ignition-chamber-no-flint: "&cDo Komory Zapłonowej brakuje Krzesiwa."
in-use: "&cEkwipunek tego bloku jest na razie otworzony przez innego gracza."
pattern-not-found: "&ePrzepraszamy, nie można rozpoznać tego przepisu. Umieść przedmioty
we właściwym wzorze w Dozowniku."
TELEPORTER:
cancelled: "&4Teleportacja anulowana!"
invulnerability: "&b&l Otrzymałeś(-aś) 30 sekund Niewrażliwości!"
teleported: "&3Przeteleportowano!"
teleporting: "&3Teleportuje..."
unknown-material: "&ePrzepraszamy, nie można rozpoznać przedmiotu w tym Dozowniku.
Proszę włożyć coś, co znam."
wrong-item: "&ePrzepraszamy, nie można rozpoznać przedmiotu, którym kliknąłeś(-aś)
mnie prawym przyciskiem myszy. Sprawdź przepisy i zobacz, jakich przedmiotów możesz
użyć."
wiki: Zobacz ten przedmiot na oficjalnej stronie Wiki Slimefun
recipes:
machine: Przepisy wykonane w tym urządzeniu
miner: Zasoby, które możesz uzyskać za pomocą tego Górnika
generator: Dostępne rodzaje paliwa
gold-pan: Zasoby, które możesz zdobyć
back:
title: Wstecz
guide: Wróć Do Przewodnika Slimefun
settings: Wróć Do Panelu Ustawień
locked: Zablokowany
locked-category:
- Aby odblokować tę kategorię, będziesz
- Musisz odblokować wszystkie przedmioty z
- Następujące kategorie
messages:
cannot-place: "&cNie możesz umieścić tam tego bloku!"
diet-cookie: "&eZaczynasz czuć się bardzo lekko..."
not-researched: "&4Nie masz wystarczającej wiedzy, aby to zrozumieć"
not-enough-xp: "&4Nie masz wystarczająco doświadczenia, aby to odblokować"
unlocked: '&bOdblokowano &7"%research%"'
only-players: "&4To polecenie dotyczy tylko graczy"
unknown-player: "&4Nieznany gracz: &c%player%"
no-permission: "&4Brak uprawnień"
usage: "&4Użycie: &c%usage%"
not-online: "&4%player% &cnie jest online!"
not-valid-item: "&4%item% &cnie jest poprawnym przedmiotem!"
not-valid-amount: "&4%amount% &cnie jest prawidłową ilością: ilość musi być większa
od 0!"
given-item: '&bOtrzymano &a%amount% &7"%item%&7"'
give-item: '&bDodano przedmiot do plecaka gracza %player%: &a%amount% &7"%item%&7"'
not-valid-research: "&4%research% &cnie jest poprawnym Badaniem!"
give-research: '&bOdblokowano badanie &7"%research%&7" dla gracza %player%'
hungry: "&cJesteś zbyt głodny, żeby to zrobić!"
mode-change: "&bTryb urządzenia %device% został zmieniony na: &9%mode%"
disabled-in-world: "&4&lTen przedmiot został wyłączony na tym świecie"
disabled-item: "&4&l Ten przedmiot został wyłączony! Jak to w ogóle dostałeś(-aś)?"
no-tome-yourself: "&cNie możesz używać &4Księgi wiedzy &cna samym sobie..."
multimeter: "&bZmagazynowana energia: &3%stored% &b/ &3%capacity%"
talisman:
anvil: "&a&oTwój talizman uratował twoje narzędzie przed złamaniem"
miner: "&a&oTwój talizman podwoił twoje znaleziska"
hunter: "&a&oTwój talizman podwoił twoje znaleziska"
lava: "&a&oTwój talizman uratował cię przed spaleniem na śmierć"
water: "&a&oTwój talizman uratował cię przed utonięciem"
angel: "&a&oTwój talizman uratował cię przed odniesieniem obrażeń od upadku"
fire: "&a&oTwój talizman uratował cię przed spaleniem na śmierć"
magician: "&a&oTwój talizman dał ci dodatkowe zaklęcie"
traveller: "&a&oTwój talizman dał ci przyspieszenie prędkości"
warrior: "&a&oTwój talizman na pewien czas poprawił twoją siłę"
knight: "&a&oTwój talizman dał ci 5 sekund regeneracji"
whirlwind: "&a&oTwój talizman odbił pocisk"
wizard: "&a&oTwój talizman zapewnił ci lepszy poziom Szczęścia, ale może także
obniżył niektóre inne poziomy zaklinania"
soulbound-rune:
fail: "&cMożesz powiązać tylko jeden przedmiot ze swoją duszą na raz."
success: "&aPomyślnie powiązałeś(-aś) ten przedmiot ze swoją duszą! Zatrzymasz
go, gdy umrzesz."
research:
start: "&7Starożytne duchy szepczą ci do ucha tajemnicze słowa!"
progress: "&7 Zaczynasz się zastanawiać nad &b%research% &e(%progress%)"
fire-extinguish: "&7Ty masz zgasły siebie."
cannot-place: "&cNie możesz umieścić tam tego bloku!"
no-pvp: "&c Nie możesz tutaj bić innych graczy!"
radiation: "&4Zostałeś(-aś) narażony na śmiertelne promieniowanie! &c Pozbądź się
radioaktywnego przedmiotu lub załóż kombinezon materiałów niebezpiecznych!"
opening-guide: "&bOtwieranie przewodnika, może to potrwać kilka sekund..."
opening-backpack: "&bOtwieranie plecaka, może to potrwać kilka sekund..."
no-iron-golem-heal: "&cTo nie jest sztabka żelaza. Nie możesz tego użyć do leczenia
Żelaznych Golemów!"
link-prompt: "&eKliknij tutaj:"
diet-cookie: "&eZaczynasz czuć się bardzo lekko..."
fortune-cookie:
- "&7Pomóż mi, jestem uwięziony w fabryce ciastek z wróżbami!"
- "&7Jutro umrzesz... przez Creepera"
@ -192,56 +140,150 @@ messages:
- "&742. Odpowiedź to 42."
- "&7Walshy dziennie pomoże uniknąć kłopotów."
- "&7Nigdy nie kop prosto w dół!"
give-item: '&bDodano przedmiot do plecaka gracza %player%: &a%amount% &7"%item%&7"'
given-item: '&bOtrzymano &a%amount% &7"%item%&7"'
hungry: "&cJesteś zbyt głodny, żeby to zrobić!"
link-prompt: "&eKliknij tutaj:"
mode-change: "&bTryb urządzenia %device% został zmieniony na: &9%mode%"
multimeter: "&bZmagazynowana energia: &3%stored% &b/ &3%capacity%"
no-iron-golem-heal: "&cTo nie jest sztabka żelaza. Nie możesz tego użyć do leczenia
Żelaznych Golemów!"
no-permission: "&4Brak uprawnień"
no-pvp: "&c Nie możesz tutaj bić innych graczy!"
not-enough-xp: "&4Nie masz wystarczająco doświadczenia, aby to odblokować"
no-tome-yourself: "&cNie możesz używać &4Księgi wiedzy &cna samym sobie..."
not-online: "&4%player% &cnie jest online!"
not-researched: "&4Nie masz wystarczającej wiedzy, aby to zrozumieć"
not-valid-amount: "&4%amount% &cnie jest prawidłową ilością: ilość musi być większa
od 0!"
not-valid-item: "&4%item% &cnie jest poprawnym przedmiotem!"
not-valid-research: "&4%research% &cnie jest poprawnym Badaniem!"
only-players: "&4To polecenie dotyczy tylko graczy"
opening-backpack: "&bOtwieranie plecaka, może to potrwać kilka sekund..."
opening-guide: "&bOtwieranie przewodnika, może to potrwać kilka sekund..."
radiation: "&4Zostałeś(-aś) narażony na śmiertelne promieniowanie! &c Pozbądź się
radioaktywnego przedmiotu lub załóż kombinezon materiałów niebezpiecznych!"
research:
progress: "&7 Zaczynasz się zastanawiać nad &b%research% &e(%progress%)"
start: "&7Starożytne duchy szepczą ci do ucha tajemnicze słowa!"
soulbound-rune:
fail: "&cMożesz powiązać tylko jeden przedmiot ze swoją duszą na raz."
success: "&aPomyślnie powiązałeś(-aś) ten przedmiot ze swoją duszą! Zatrzymasz
go, gdy umrzesz."
talisman:
angel: "&a&oTwój talizman uratował cię przed odniesieniem obrażeń od upadku"
anvil: "&a&oTwój talizman uratował twoje narzędzie przed złamaniem"
fire: "&a&oTwój talizman uratował cię przed spaleniem na śmierć"
hunter: "&a&oTwój talizman podwoił twoje znaleziska"
knight: "&a&oTwój talizman dał ci 5 sekund regeneracji"
lava: "&a&oTwój talizman uratował cię przed spaleniem na śmierć"
magician: "&a&oTwój talizman dał ci dodatkowe zaklęcie"
miner: "&a&oTwój talizman podwoił twoje znaleziska"
traveller: "&a&oTwój talizman dał ci przyspieszenie prędkości"
warrior: "&a&oTwój talizman na pewien czas poprawił twoją siłę"
water: "&a&oTwój talizman uratował cię przed utonięciem"
whirlwind: "&a&oTwój talizman odbił pocisk"
wizard: "&a&oTwój talizman zapewnił ci lepszy poziom Szczęścia, ale może także
obniżył niektóre inne poziomy zaklinania"
unknown-player: "&4Nieznany gracz: &c%player%"
unlocked: '&bOdblokowano &7"%research%"'
usage: "&4Użycie: &c%usage%"
give-research: '&bOdblokowano badanie &7"%research%&7" dla gracza %player%'
miner:
no-ores: "&eNie można znaleźć żadnych rud w pobliżu!"
machines:
pattern-not-found: "&ePrzepraszamy, nie można rozpoznać tego przepisu. Umieść przedmioty
we właściwym wzorze w Dozowniku."
unknown-material: "&ePrzepraszamy, nie można rozpoznać przedmiotu w tym Dozowniku.
Proszę włożyć coś, co znam."
wrong-item: "&ePrzepraszamy, nie można rozpoznać przedmiotu, którym kliknąłeś(-aś)
mnie prawym przyciskiem myszy. Sprawdź przepisy i zobacz, jakich przedmiotów możesz
użyć."
full-inventory: "&eEkwipunek jest pełny!"
in-use: "&cEkwipunek tego bloku jest na razie otworzony przez innego gracza."
ignition-chamber-no-flint: "&cDo Komory Zapłonowej brakuje Krzesiwa."
ANCIENT_ALTAR:
not-enough-pedestals: "&4Ołtarz nie jest otoczony potrzebną ilością cokołów &c(%pedestals%
/ 8)"
unknown-catalyst: "&4Nieznany katalizator! &cZamiast tego użyj prawidłowego przepisu!"
unknown-recipe: "&4Nieznany przepis! &cZamiast tego użyj prawidłowego przepisu!"
ANCIENT_PEDESTAL:
obstructed: "&4Piedestał jest zablokowany! &cUsuń wszystko nad piedestałem!"
HOLOGRAM_PROJECTOR:
enter-text: "&7Wprowadź żądany tekst hologramu na czacie. &r(Kody kolorów są obsługiwane!)"
inventory-title: Edytor hologramów
ELEVATOR:
no-destinations: "&4Nie znaleziono miejsc docelowych"
pick-a-floor: "&3- Wybierz piętro-"
current-floor: "&eTo jest piętro, na którym aktualnie jesteś:"
click-to-teleport: "&eKliknij &7aby teleportować się na to piętro:"
enter-name: "&7Wprowadź żądaną nazwę piętra na czacie. &r(Kody kolorów są obsługiwane!)"
named: "&2Pomyślnie nazwano podłogę: &r% floor%"
TELEPORTER:
teleporting: "&3Teleportuje..."
teleported: "&3Przeteleportowano!"
cancelled: "&4Teleportacja anulowana!"
invulnerability: "&b&l Otrzymałeś(-aś) 30 sekund Niewrażliwości!"
gui:
title: Twoje punkty trasy
tooltip: Kliknij, aby się teleportować
time: Szacowany czas
CARGO_NODES:
must-be-placed: "&4Musi być umieszczony na skrzyni lub maszynie!"
GPS_CONTROL_PANEL:
title: GPS - Panel sterowania
transmitters: Transmiter Przegląd
waypoints: Waypoint Przegląd
anvil:
not-working: "&4Nie możesz używać przedmiotów Slimefun w kowadle!"
backpack:
already-open: "&cPrzepraszamy, ten plecak jest otwarty gdzie indziej!"
no-stack: "&cNie możesz stakować plecaków"
workbench:
not-enhanced: "&4Nie można używać przedmiotów Slimefun w zwykłym stole warsztatowym"
gps:
deathpoint: "&4Punkt śmierci &7%date%"
waypoint:
new: "&eProszę wpisać nazwę swojego nowego punktu trasy na czacie. &7(Kody kolorów
są obsługiwane!)"
added: "&aPomyślnie dodano nowy punkt trasy"
max: "&4Osiągnięto maksymalną liczbę punktów trasy"
insufficient-complexity:
- "&4Niewystarczająca złożoność sieci GPS: &c%complexity%"
- "&4a) Nie masz jeszcze skonfigurowanej sieci GPS"
- "&4b) Twoja sieć GPS nie jest wystarczająco złożona"
geo:
scan-required: "&4Wymagany jest skan GEO-Skan! &cNajpierw zeskanuj ten fragment
za pomocą skanera GEO!"
inventory:
no-access: "&4Nie masz dostępu do tego bloku"
android:
started: "&7Twój Android wznowił swój skrypt"
stopped: "&7Twój Android wstrzymał swój skrypt"
scripts:
already-uploaded: "&4Ten skrypt został już przesłany."
instructions:
START: "&2Uruchom skrypt"
REPEAT: "&9 Powtórz skrypt"
WAIT: "&ePoczekaj 0.5s"
GO_FORWARD: "&7Idź do przodu"
GO_UP: "&7Idź do góry"
GO_DOWN: "&7Idź w dół"
TURN_LEFT: "&7Skręć w lewo"
TURN_RIGHT: "&7Skręć w prawo"
DIG_UP: "&bKop w górę"
DIG_FORWARD: "&bKop do przodu"
DIG_DOWN: "&bKop w dół"
MOVE_AND_DIG_UP: "&bIdź i kop w górę"
MOVE_AND_DIG_FORWARD: "&bIdź i kop do przodu"
MOVE_AND_DIG_DOWN: "&bIdź i kop w dół"
ATTACK_MOBS_ANIMALS: "&4Atakuj &c(Wrogie Moby i Zwierzęta)"
ATTACK_MOBS: "&4Atakuj &c(Wrogie Moby)"
ATTACK_ANIMALS: "&4Atakuj &c(Zwierzęta)"
ATTACK_ANIMALS_ADULT: "&4Atakuj &c(Zwierzęta &7[Dorosłe]&c)"
CHOP_TREE: "&cTnij drzewo i posadź sadzonkę"
CATCH_FISH: "&bŁów ryby"
FARM_FORWARD: "&bZbieraj i posadź z powrotem"
FARM_DOWN: "&bZbieraj i posadź z powrotem &7(Blok pod spodem)"
FARM_EXOTIC_FORWARD: "&6Zaawansowanie zbieraj i posadź z powrotem"
FARM_EXOTIC_DOWN: "&bZaawansowanie zbieraj i posadź z powrotem &7(Blok pod spodem)"
INTERFACE_ITEMS: "&9Wyślij zawartość ekwipunku do Interfejsu w obecnym kierunku"
INTERFACE_FUEL: "&cOtrzymaj paliwo z Interfejsu w obecnym kierunku"
enter-name:
-
- "&eProszę wpisać nazwę dla tego skryptu"
uploaded:
- "&bPrzesyłanie..."
- "&aPomyślnie przesłano twój skrypt!"
rating:
own: "&4Nie możesz ocenić własnego skryptu!"
already: "&4Oceniłeś już ten skrypt!"
editor: Edytor skryptów
languages:
default: Domyślny serwera
en: Język angielski
de: Niemiecki
fr: Francuski
it: Włoski
es: Hiszpański
pl: Polski
sv: Szwedzki
nl: Holenderski
cs: Czeski
hu: Węgierski
lv: Łotewski
ru: Rosyjski
sk: Słowacki
zh-TW: Chiński (Tajwan)
vi: Wietnamski
id: Indonezyjski
zh-CN: Chiński (Chiny)
el: Grecki
he: Hebrajski
pt-BR: Portugalski (Brazylia)
ar: Arabski (Arabic)
af: Afrykański (Afrikaans)
da: Duński (Danish)
fi: Fiński (Finnish)
uk: Ukraiński (Ukrainian)
ms: Malajski (Malay)
'no': Norweski
ja: Japonia
fa: Perski
th: Tajski
ro: Rumuński
pt: Portugalski (Portugalia)
bg: Bułgarski
ko: Koreański
tr: Turecki
miner:
no-ores: "&eNie można znaleźć żadnych rud w pobliżu!"

View File

@ -0,0 +1,234 @@
---
slimefun:
walking_sticks: Ruchomy Patyk
portable_crafter: Przenośny Stół Rzemieślniczy
fortune_cookie: Ciastko z wróżbą
portable_dustbin: Przenośny Kosz
meat_jerky: Suszone Mięso
armor_forge: Tworzenie Zbroji
glowstone_armor: Jasnopyłowa Zbroja
lumps: Grudki i Magia
ender_backpack: Plecak Endu
ender_armor: Zbroja Endu
magic_eye_of_ender: Magiczne Oko Endera
magic_sugar: Magiczny Cukier
monster_jerky: 'Potworne Mięso '
slime_armor: Szlamowa Zbroja
sword_of_beheading: Miecz Odcinania Głów
basic_circuit_board: Podstawowa Płyta Drukowana
advanced_circuit_board: Zaawansowana Płyta Drukowana
smeltery: Wytapiacz
steel: Epoka Stali
misc_power_items: Ważne przedmioty związane z prądem
battery: Twoja pierwsza bateria
steel_plate: Stalowa Blacha
steel_thruster: Stalowy Ster Strumieniowy
parachute: Spadochron
grappling_hook: Hak do Chwytania
jetpacks: Plecaki Odrzutowe
multitools: Narzędzia Wielofunkcyjne
solar_panel_and_helmet: Energia Słoneczna
elemental_staff: Drążki Żywiołów
grind_stone: Kamień Szliferski
cactus_armor: Kaktusowy Garnitur
gold_pan: Złota Patelnia
magical_book_cover: Magiczna Oprawa do Książek
slimefun_metals: Nowe Metale
ore_crusher: Kruszarka Rud
bronze: Tworzenie Bronzu
alloys: Zaawansowane Stopy
compressor_and_carbon: Tworzenie Węgla
gilded_iron_armor: Pozłacana Żelazna Zbroja
synthetic_diamond: Diamenty Syntetyczne
pressure_chamber: Komora Ciśnieniowa
synthetic_sapphire: Szafiry Syntetyczne
damascus_steel: Stal Damasceńska
damascus_steel_armor: Zbroja ze Stali Damasceńskiej
reinforced_alloy: Wzmocniony Stop
carbonado: Czarne Diamenty
magic_workbench: Magiczny Stół Rzemieślniczy
wind_staff: Laska Wiatru
reinforced_armor: Wzmocniona Zbroja
ore_washer: Zmywacz Rud
gold_carats: Czyste Złoto
silicon: Dolina Krzemowa
fire_staff: Laska Ognia
smelters_pickaxe: Kilof Hutniczy
common_talisman: Pospolity Talizman
anvil_talisman: Talizman Kowadła
miner_talisman: Talizman Górnika
hunter_talisman: Talizman Łowcy
lava_talisman: Talizman Chodzącego po Lawie
water_talisman: Talizman Oddychacza pod Wodą
angel_talisman: Talizman Anioła
fire_talisman: Talizman Strażaka
lava_crystal: Ogniowa Sytuacja
magician_talisman: Talizman Maga
traveller_talisman: Talizman Podróżnika
warrior_talisman: Talizman Wojownika
knight_talisman: Talizman Rycerza
gilded_iron: Błyszczące Żelazo
synthetic_emerald: Fałszywy Klejnot
chainmail_armor: Kolczuga
whirlwind_talisman: Talizman Wiatru
wizard_talisman: Talizman Czarnoksiężnika
lumber_axe: Siekiera Drwala
hazmat_suit: Kombinezon Materiałów Niebezpiecznych
uranium: Radioaktywny
crushed_ore: Oczyszczanie Rud
redstone_alloy: Stop Czerwonego Proszku
carbonado_tools: Maszyny na Najwyższym Poziomie
first_aid: Pierwsza Pomoc
gold_armor: Błyszcząca Zbroja
night_vision_googles: Gogle Noktowizyjne
pickaxe_of_containment: Kilof Przechowywania
hercules_pickaxe: Kilof Herkulesa
table_saw: Piła Stołowa
slime_steel_armor: Szlamowy Pancerz Stalowy
blade_of_vampires: Ostrze Wampirów
water_staff: Laska Wody
24k_gold_block: Miasto ze Złota
composter: Kompostowanie Ziemi
farmer_shoes: Buty Rolnika
explosive_tools: Narzędzia Wybuchowe
automated_panning_machine: Zautomatyzowana Złota Patelnia
boots_of_the_stomper: Buty Stompera
pickaxe_of_the_seeker: Kilof Poszukiwacza
backpacks: Plecaki
woven_backpack: Pleciony Plecak
crucible: Tygiel
gilded_backpack: Pozłacany Plecak
armored_jetpack: Opancerzony Plecak Odrzutowy
ender_talismans: Talizmany Endera
nickel_and_cobalt: Jeszcze więcej Rud
magnet: Metale Magnetyczne
infused_magnet: Natchnione Magnesy
cobalt_pickaxe: Kobaltowy Kilof
essence_of_afterlife: Nekromancja
bound_backpack: Plecak Soulbound
jetboots: Buty Odrzutowe
armored_jetboots: Opancerzone Buty Odrzutowe
seismic_axe: Sejsmiczny Topór
pickaxe_of_vein_mining: Kilof z Żyły Górnictwa
bound_weapons: Bronie Soulbound
bound_tools: Narzędzia Soulbound
bound_armor: Soulbound Zbroja
juicer: Pyszne Drinki
repaired_spawner: Naprawianie Spawnerów
enhanced_furnace: Ulepszony Piec
more_enhanced_furnaces: Lepsze Piece
high_tier_enhanced_furnaces: Piec Wysokopoziomowy
reinforced_furnace: Wzmocniony Piec
carbonado_furnace: Karbonado Ostry Piec
electric_motor: Podgrzewać
block_placer: Blok Kładący
scroll_of_dimensional_teleposition: Odwracając rzeczy dookoła
special_bows: Robin Hood
tome_of_knowledge_sharing: Podziel się z Znajomym
flask_of_knowledge: Przechowywacz Expa
hardened_glass: Wytrzymałość na Wybuchy
golden_apple_juice: Złota Mikstura
cooler: Przenośna Chłodnica
ancient_altar: Starożytny Ołtarz
wither_proof_obsidian: Wither-Ochronne Obsydian
ancient_runes: Runy Żywiołów
special_runes: Fioletowe Runy
infernal_bonemeal: Piekielna Mączka Kostna
rainbow_blocks: Tęczowy Blok
infused_hopper: Lej Infused
wither_proof_glass: Wither-Ochronne Szkło
duct_tape: Taśma Klejąca
plastic_sheet: Plastik
android_memory_core: Rdzeń Pamięci
oil: Olej
fuel: Paliwo
hologram_projector: Projektor Hologramów
capacitors: Poziom 1 Kondensator
high_tier_capacitors: Poziom 2 Kondensator
solar_generators: Generator Słoneczny
electric_furnaces: Elektryczny Piec
electric_ore_grinding: Elektryczna Szlifierka Rudy
heated_pressure_chamber: Ogrzewana Komora Ciśnieniowa
coal_generator: Generator Węgla
bio_reactor: Bio-Reaktor
auto_enchanting: Automatyczne zaczarowanie i odczarowywanie
auto_anvil: Automatyczne Kowadło
multimeter: Pomiar Mocy
gps_setup: Podstawowa Konfiguracja GPS
gps_emergency_transmitter: Awaryjny punkt GPS
programmable_androids: Programowalne Androidy
android_interfaces: Interfejsyjny Android
geo_scanner: GEO-Skaner
combustion_reactor: Reaktor Spalania
teleporter: Komponenty Podstawowe Teleportera
teleporter_activation_plates: Aktywacja Teleportera
better_solar_generators: Ulepszony Słoneczny Generator
better_gps_transmitters: Ulepszony Transmiter
elevator: Windy
energized_solar_generator: Pełny-Czas Energia Słoneczna
energized_gps_transmitter: Transmiter Najwyższego Poziomu
energy_regulator: Regulator Energii
butcher_androids: Rzeźnik Android
organic_food: Organiczne Jedzenie
auto_breeder: Zautomatyzowane Karmienie
advanced_android: Zaawansowane Androidy
advanced_butcher_android: Zaawansowany Android - Rzeźnik
advanced_fisherman_android: Zaawansowany Android - Rybak
animal_growth_accelerator: Manipulacja Wzrostem Zwierząt
xp_collector: Kolekcjoner Expa
organic_fertilizer: Organiczny Nawóz
crop_growth_accelerator: Przyspieszenie Wzrostu Upraw
better_crop_growth_accelerator: Upgraded Crop Growth Accelerator
reactor_essentials: Podstawowy Reaktor
nuclear_reactor: Elektrownia Atomowa
freezer: Zamrażarka
cargo_basics: Podstawy Ładunku
cargo_nodes: Konfiguracja Ładunku
electric_ingot_machines: Elektryczna Fabryka Sztabek
high_tier_electric_ingot_machines: Super Szybka Produkcja Sztabek
automated_crafting_chamber: Automatyczny Stół Rzemieślniczy
better_food_fabricator: Ulepszone Wytwarzanie Żywności
reactor_access_port: Interakcja Reaktora
fluid_pump: Pompa Płynu
better_freezer: Ulepszona Zamrażarka
boosted_uranium: Niekończący się krąg
trash_can: Kosz
advanced_output_node: Zaawansowany Węzeł Wyjściowy
carbon_press: Prasa do Karbonado
electric_smeltery: Elektryczny Wytapiacz
better_electric_furnace: Ulepszony Elektryczny Piec
better_carbon_press: Ulepszona Prasa do Karbonado
empowered_android: 'Wzmocniony Android '
empowered_butcher_android: Wzmocniony Android - Rzeźnik
empowered_fisherman_android: Wzmocniony Android - Rybak
high_tier_carbon_press: Ostateczna Prasa Węglowa
wither_assembler: Automatyczny Zabijacz Withera
better_heated_pressure_chamber: Ulepszona Ogrzewana Komora Ciśnieniowa
elytra: Elytra
special_elytras: Specjalna Elytra
electric_crucible: Naelektryzowany Tygiel
better_electric_crucibles: Gorące Tygle
advanced_electric_smeltery: Zaawansowana Huta Elektryczna
advanced_farmer_android: Zaawansowany Android - Farmer
lava_generator: Generator Lawy
nether_ice: Piekielny Lód Chłodzący
nether_star_reactor: Piekielny Reaktor
blistering_ingots: Pękająca Promieniotwórczość
automatic_ignition_chamber: Automatyczna Komora Zapłonowa
output_chest: Podstawowa Skrzynia Wyjściowa Maszyn
copper_wire: Zmniejszona Przewodność
radiant_backpack: Radioaktywny Plecak
auto_drier: Suchy Dzień
diet_cookie: Dietetyczne Ciasteczko
storm_staff: Laska Burzowa
soulbound_rune: Soulbound Rune
geo_miner: GEO-Górnik
lightning_rune: Błyskawiczna Runa
totem_of_undying: Totem Nieśmiertelności
charging_bench: Stół do Ładowania
nether_gold_pan: Piekielna Złota Patelnia
electric_press: Prasa Elektryczna
magnesium_generator: Moc z Magnezu
kelp_cookie: Ciastko z Wodorostów
makeshift_smeltery: Improwizowana huta
tree_growth_accelerator: Szybsze drzewa

View File

@ -1,17 +1,17 @@
---
slimefun:
walking_sticks: Mga Lumalakad na Tusok
walking_sticks: Walking Sticks
portable_crafter: Portable Crafter
fortune_cookie: Fortune Cookie
portable_dustbin: Portable Dustbin
meat_jerky: Meat Jerky
armor_forge: Armor Crafting
glowstone_armor: Glowstone Armor
lumps: Tipak at Mahika
lumps: Lumps and Magic
ender_backpack: Ender Backpack
ender_armor: Ender Armor
magic_eye_of_ender: Ang Mahiwagang Mata ng Ender
magic_sugar: Mahiwagang Asukal
magic_eye_of_ender: Magic Eye of Ender
magic_sugar: Magic Sugar
monster_jerky: Monster Jerky
slime_armor: Slime Armor
sword_of_beheading: Espada sa Pagpugot ng Ulo