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

Merge branch 'master' into NitwitRune

This commit is contained in:
TheBusyBiscuit 2020-08-17 00:25:18 +02:00 committed by GitHub
commit c98fe74ea9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
81 changed files with 1630 additions and 989 deletions

View File

@ -17,13 +17,13 @@ Rules for all types of posts:
Rules for posting an Issue on GitHub:
1. This Issue Section is ONLY for Slimefun-related Issues, Issues about other Plugins or Slimefun Addons should not be posted here.
2. Please consult our [Troubleshooting Guide](#troubleshooting-guide) before posting.
2. Please consult our [Troubleshooting Guide](https://github.com/TheBusyBiscuit/Slimefun4/wiki/How-to-report-bugs) before posting.
3. Check other Issues before posting to make sure you are not posting a duplicate.
4. Do not put any Tags inside your title like [IMPORTANT], [URGENT] or [SUGGESTION]. Try to be professional by making your title as short as possible, we will assign it the required labels if necessary.
5. Do not post your Issue more than once, this is considered spam and does not benefit our community in any way. Do not repost your Issue if it was closed either.
4. Please do not put any Tags inside your title like [IMPORTANT], [URGENT] or [SUGGESTION]. Try to be professional by making your title as short as possible, we will assign it the required labels if necessary.
5. Do not post your Issue more than once, this is considered spam and does not benefit our community in any way. Do not repost your Issue if it was closed either, just leave a comment stating that the issue has still persisted and give more context on it.
6. Give us all available information right away, it may be a bit of time-wasting for us to keep asking for more Info. And this includes any Information to reproduce your Issue step-by-step.
7. Check whether there are newer versions available than the ones you are using, it might be that your Issue has been fixed already.
8. All text logs must be posted via a link to http://pastebin.com or similiar websites.
8. All text logs must be posted via a link to https://pastebin.com/ or similiar websites, long logs are very hard to read and get weirdly formatted when you post them on here. Using a proper pasting site allows us to keep things clean and easy to read.
Your Issue will be CLOSED WITHOUT WARNING if we think you violated these Rules.
@ -35,26 +35,3 @@ Guidelines for making a Pull Request on GitHub:
2. Try to make your values configurable in the config.yml / Items.yml or any additional file. This may not be necessary at every instance but it does give the end-users a way to customize their experience.
3. If your Pull Request is made in response to an Issue opened on GitHub, comment on that Issue and reference your Pull Request to show that you are proposing a fix for it.
4. Name your commits appropriately. Standards like "Add files via upload" or "Update Readme.md" are lame. Make sure that the commit message stands for it's changes. (e.g. "Fixed Furnaces duplicating Items")
## Troubleshooting Guide
### Step 1: Check whether you have installed Slimefun correctly
Slimefun requires [CS-CoreLib](http://dev.bukkit.org/bukkit-plugins/cs-corelib) to run.
If it has not been installed automatically for you, then please download & install it manually.
### Step 2: Check whether you are running on the latest Versions
Both, [Slimefun](http://dev.bukkit.org/bukkit-plugins/slimefun/files) and [CS-CoreLib](http://dev.bukkit.org/bukkit-plugins/cs-corelib/files) are updated from time to time.
You should be sure that you run the latest Versions (at the time you post your Issue) of both Plugins.
### Step 3: Does it have to do with Items called 'CS-CoreLib's Head'?
Well in that case, you have been the victim of corruption, unless you have an Error/Crash Report that we can work with, there is literally nothing we can do about it.
Corrupting Files/Data can happen from time to time and getting completely rid of it would require a ton of work and even then it is still not completely impossible to occur.
### Step 4: Do you get an Error, do you have an Error Report?
Check your /plugins/Slimefun/error-reports/ directory and if it contains any Files, then please upload those to http://pastebin.com
and provide us with a link.
When providing us Errors from your Server Log MAKE SURE THEY ARE ERRORS.
It has happened more often than you may think that people send us messages.
Try to read the suspected 'Error' before uploading it to http://pastebin.com
If it says "Please install CS-CoreLib", then you may want to rethink whether you want to ask us what it means...

View File

@ -6,7 +6,10 @@ on:
jobs:
comment:
name: Invalid Issues
runs-on: ubuntu-latest
if: contains(github.event.issue.labels.*.name, 'Bug Report') == false
steps:
- name: Close Issue

View File

@ -9,6 +9,7 @@ on:
jobs:
report:
name: Discord Webhook
runs-on: ubuntu-latest
if: github.repository == 'TheBusyBiscuit/Slimefun4'

View File

@ -6,7 +6,10 @@ on:
jobs:
comment:
name: Mark Issue as duplicate
runs-on: ubuntu-latest
if: contains(github.event.comment.body, 'Duplicate of ')
steps:
- name: Add label to the Issue

View File

@ -17,6 +17,7 @@ on:
jobs:
build:
name: Maven build
runs-on: ubuntu-latest
steps:

26
.github/workflows/url-checker.yml vendored Normal file
View File

@ -0,0 +1,26 @@
name: URL Validator
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
build:
name: URL Checker
runs-on: ubuntu-latest
steps:
- name: URL-checker
uses: SuperKogito/URLs-checker@0.2.1
with:
git_path: https://github.com/TheBusyBiscuit/Slimefun4
file_types: .md,.java,.yml
print_all: False
retry_count: 2
## These URLs will always be correct, even if their services may be offline right now
white_listed_patterns: http://textures.minecraft.net/texture/,https://pastebin.com/,https://www.spigotmc.org/threads/spigot-bungeecord-1-16-1.447405/#post-3852349

View File

@ -11,8 +11,9 @@ on:
- '**.yml'
jobs:
build:
linter:
name: YAML Linter
runs-on: ubuntu-latest
steps:

View File

@ -29,6 +29,9 @@
* (API) Added support for adding custom Piglin Barter drops
* (API) Added BlockPlacerPlaceEvent
* (API) Added ToolUseHandler
* Added "Sand -> Sandstone" recipe to the Electric Press
* Added "Red Sand -> Red Sandstone" recipe to the Electric Press
* Industrial Miners can now also mine Gilded Blackstone
#### Changes
* Performance improvement for Programmable Android rotations
@ -36,6 +39,7 @@
* Performance improvements for miner talismans
* Performance improvements for idling Enhanced Furnaces when using Paper
* Performance improvements for Rainbow Blocks
* Crafting a Rag now yields two items
#### Fixes
* Fixed Programmable Androids rotating in the wrong direction
@ -50,6 +54,14 @@
* Fixed #2183
* Fixed #2181
* Fixed #2180
* Fixed #2122
* Fixed #2168
* Fixed #2203
* Fixed #2205
* Fixed #2209
* Fixed #2217
* Fixed Miner Talisman sending messages when drops were not even doubled
* Fixed #2077
## Release Candidate 15 (01 Aug 2020)

View File

@ -192,5 +192,5 @@ This information includes (but is not limited to)
* date of the last commit to this repository
</details>
Additionally the plugin connects to https://mojang.com/ to retrieve the Minecraft skins of our contributors (if possible).<br>
Additionally the plugin connects to [textures.minecraft.net](https://www.minecraft.net/en-us) to retrieve the Minecraft skins of our contributors (if possible).<br>
Note that Slimefun is not associated with `Mojang Studios` or Minecraft.

20
pom.xml
View File

@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.github.thebusybiscuit</groupId>
<groupId>com.github.thebusybiscuit</groupId>
<artifactId>Slimefun</artifactId>
<!-- Our default version will be UNOFFICIAL, this will prevent auto updates -->
@ -47,6 +47,16 @@
</licenses>
<repositories>
<repository>
<id>sonatype-snapshots</id>
<url>http://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
@ -57,7 +67,7 @@
</repository>
<repository>
<id>paper-repo</id>
<url>https://repo.destroystokyo.com/repository/maven-public/</url>
<url>https://papermc.io/repo/repository/maven-public/</url>
</repository>
<repository>
<id>worldedit-repo</id>
@ -303,14 +313,14 @@
</dependency>
<dependency>
<groupId>com.github.seeseemelk</groupId>
<artifactId>MockBukkit</artifactId>
<version>v1.15-d952559324-1</version>
<artifactId>MockBukkit-v1.15</artifactId>
<version>0.3.1-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.4.6</version>
<version>3.5.0</version>
<scope>test</scope>
</dependency>

View File

@ -84,7 +84,7 @@ public class ErrorReport {
addon.getLogger().log(Level.WARNING, "");
addon.getLogger().log(Level.WARNING, "An Error occurred! It has been saved as: ");
addon.getLogger().log(Level.WARNING, "/plugins/Slimefun/error-reports/{0}", file.getName());
addon.getLogger().log(Level.WARNING, "Please put this file on https://pastebin.com and report this to the developer(s).");
addon.getLogger().log(Level.WARNING, "Please put this file on https://pastebin.com/ and report this to the developer(s).");
if (addon.getBugTrackerURL() != null) {
addon.getLogger().log(Level.WARNING, "Bug Tracker: {0}", addon.getBugTrackerURL());

View File

@ -32,6 +32,8 @@ public class BlockPlacerPlaceEvent extends BlockEvent implements Cancellable {
*
* @param blockPlacer
* The {@link BlockPlacer}
* @param placedItem
* The {@link ItemStack} of the {@link Block} that was placed
* @param block
* The placed {@link Block}
*/

View File

@ -283,6 +283,14 @@ public class GPSNetwork {
if (!event.isCancelled()) {
String id = ChatColor.stripColor(ChatColors.color(event.getName())).toUpperCase(Locale.ROOT).replace(' ', '_');
for (Waypoint wp : profile.getWaypoints()) {
if (wp.getId().equals(id)) {
SlimefunPlugin.getLocalization().sendMessage(p, "gps.waypoint.duplicate", true, msg -> msg.replace("%waypoint%", event.getName()));
return;
}
}
profile.addWaypoint(new Waypoint(profile, id, event.getLocation(), event.getName()));
p.playSound(p.getLocation(), Sound.BLOCK_NOTE_BLOCK_PLING, 1F, 1F);

View File

@ -1,6 +1,7 @@
package io.github.thebusybiscuit.slimefun4.core.attributes;
import org.bukkit.entity.Piglin;
import org.bukkit.event.entity.EntityDropItemEvent;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.PiglinListener;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
@ -8,7 +9,7 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
/**
* This interface, when attached to a {@link SlimefunItem}, provides a variable (0-100%) chance for
* a {@link SlimefunItem} to be dropped by a {@link Piglin} on {@link EntityItemDropEvent}.
* a {@link SlimefunItem} to be dropped by a {@link Piglin} on {@link EntityDropItemEvent}.
*
* @author dNiym
*

View File

@ -19,7 +19,8 @@ class GuideCommand extends SubCommand {
public void onExecute(CommandSender sender, String[] args) {
if (sender instanceof Player) {
if (sender.hasPermission("slimefun.command.guide")) {
((Player) sender).getInventory().addItem(SlimefunGuide.getItem(SlimefunPlugin.getCfg().getBoolean("guide.default-view-book") ? SlimefunGuideLayout.BOOK : SlimefunGuideLayout.CHEST));
SlimefunGuideLayout design = SlimefunGuide.getDefaultLayout();
((Player) sender).getInventory().addItem(SlimefunGuide.getItem(design).clone());
}
else {
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true);

View File

@ -1,16 +1,10 @@
package io.github.thebusybiscuit.slimefun4.core.guide;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
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.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.guide.BookSlimefunGuide;
@ -36,31 +30,7 @@ public final class SlimefunGuide {
private SlimefunGuide() {}
public static ItemStack getItem(SlimefunGuideLayout design) {
ItemStack item = new ItemStack(Material.ENCHANTED_BOOK);
ItemMeta meta = item.getItemMeta();
List<String> lore = new LinkedList<>();
lore.addAll(Arrays.asList("", ChatColors.color("&eRight Click &8\u21E8 &7Browse Items"), ChatColors.color("&eShift + Right Click &8\u21E8 &7Open Settings / Credits")));
switch (design) {
case BOOK:
meta.setDisplayName(ChatColors.color("&aSlimefun Guide &7(Book GUI)"));
break;
case CHEAT_SHEET:
meta.setDisplayName(ChatColors.color("&cSlimefun Guide &4(Cheat Sheet)"));
lore.add(0, ChatColors.color("&4&lOnly openable by Admins"));
lore.add(0, "");
break;
case CHEST:
meta.setDisplayName(ChatColors.color("&aSlimefun Guide &7(Chest GUI)"));
break;
default:
return null;
}
meta.setLore(lore);
SlimefunPlugin.getItemTextureService().setTexture(meta, "SLIMEFUN_GUIDE");
item.setItemMeta(meta);
return item;
return SlimefunPlugin.getRegistry().getGuideLayout(design).getItem();
}
public static void openCheatMenu(Player p) {
@ -132,4 +102,13 @@ public final class SlimefunGuide {
public static boolean isGuideItem(ItemStack item) {
return SlimefunUtils.isItemSimilar(item, getItem(SlimefunGuideLayout.CHEST), true) || SlimefunUtils.isItemSimilar(item, getItem(SlimefunGuideLayout.BOOK), true) || SlimefunUtils.isItemSimilar(item, getItem(SlimefunGuideLayout.CHEAT_SHEET), true);
}
public static SlimefunGuideLayout getDefaultLayout() {
if (SlimefunPlugin.getCfg().getBoolean("guide.default-view-book")) {
return SlimefunGuideLayout.BOOK;
}
else {
return SlimefunGuideLayout.CHEST;
}
}
}

View File

@ -21,6 +21,12 @@ import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
/**
* This menu shows a list of every {@link Contributor} to this project.
*
* @author TheBusyBiscuit
*
*/
final class ContributorsMenu {
private ContributorsMenu() {}

View File

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

View File

@ -1,5 +1,7 @@
package io.github.thebusybiscuit.slimefun4.core.guide.options;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.bukkit.ChatColor;
@ -8,6 +10,7 @@ import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.cscorelib2.data.PersistentDataAPI;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
@ -16,6 +19,7 @@ import io.github.thebusybiscuit.slimefun4.core.services.localization.Language;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.ChatUtils;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
@ -37,7 +41,16 @@ class PlayerLanguageOption implements SlimefunGuideOption<String> {
Language language = SlimefunPlugin.getLocalization().getLanguage(p);
String languageName = language.isDefault() ? (SlimefunPlugin.getLocalization().getMessage(p, "languages.default") + ChatColor.DARK_GRAY + " (" + language.getName(p) + ")") : SlimefunPlugin.getLocalization().getMessage(p, "languages." + language.getId());
return Optional.of(new CustomItem(language.getItem(), "&7" + SlimefunPlugin.getLocalization().getMessage(p, "guide.languages.selected-language") + " &a" + languageName, "", "&7You now have the option to change", "&7the language in which Slimefun", "&7will send you messages.", "&7Note that this only translates", "&7some messages, not items.", "&7&oThis feature is still being worked on", "", "&7\u21E8 &eClick to change your language"));
List<String> lore = new ArrayList<>();
lore.add("");
lore.add(ChatColors.color("&e&o") + SlimefunPlugin.getLocalization().getMessage(p, "guide.work-in-progress"));
lore.add("");
lore.addAll(SlimefunPlugin.getLocalization().getMessages(p, "guide.languages.description"));
lore.add("");
lore.add("&7\u21E8 &e" + SlimefunPlugin.getLocalization().getMessage(p, "guide.languages.change"));
ItemStack item = new CustomItem(language.getItem(), "&7" + SlimefunPlugin.getLocalization().getMessage(p, "guide.languages.selected-language") + " &a" + languageName, lore.toArray(new String[0]));
return Optional.of(item);
}
else {
return Optional.empty();
@ -78,7 +91,7 @@ class PlayerLanguageOption implements SlimefunGuideOption<String> {
});
}
else if (i == 7) {
menu.addItem(7, new CustomItem(SlimefunUtils.getCustomHead("3edd20be93520949e6ce789dc4f43efaeb28c717ee6bfcbbe02780142f716"), SlimefunPlugin.getLocalization().getMessage(p, "guide.languages.translations.name"), "", "&7\u21E8 &e" + SlimefunPlugin.getLocalization().getMessage(p, "guide.languages.translations.lore")), (pl, slot, item, action) -> {
menu.addItem(7, new CustomItem(SlimefunUtils.getCustomHead(HeadTexture.ADD_NEW_LANGUAGE.getTexture()), SlimefunPlugin.getLocalization().getMessage(p, "guide.languages.translations.name"), "", "&7\u21E8 &e" + SlimefunPlugin.getLocalization().getMessage(p, "guide.languages.translations.lore")), (pl, slot, item, action) -> {
ChatUtils.sendURL(pl, "https://github.com/TheBusyBiscuit/Slimefun4/wiki/Translating-Slimefun");
pl.closeInventory();
return false;

View File

@ -5,6 +5,7 @@ import java.util.List;
import java.util.Optional;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
@ -78,7 +79,7 @@ public final class SlimefunGuideSettings {
return false;
});
menu.addItem(4, new CustomItem(Material.WRITABLE_BOOK, "&aSlimefun Version", "&7&o" + SlimefunPlugin.getLocalization().getMessage(p, "guide.tooltips.versions-notice"), "", "&fMinecraft Version: &a" + Bukkit.getBukkitVersion(), "&fSlimefun Version: &a" + SlimefunPlugin.getVersion(), "&fCS-CoreLib Version: &a" + SlimefunPlugin.getCSCoreLibVersion()), ChestMenuUtils.getEmptyClickHandler());
menu.addItem(4, new CustomItem(Material.WRITABLE_BOOK, "&aSlimefun Version", "&7&o" + SlimefunPlugin.getLocalization().getMessage(p, "guide.tooltips.versions-notice"), "", "&fMinecraft: &a" + Bukkit.getBukkitVersion(), "&fSlimefun: &a" + SlimefunPlugin.getVersion(), "&fCS-CoreLib: &a" + SlimefunPlugin.getCSCoreLibVersion()), ChestMenuUtils.getEmptyClickHandler());
menu.addItem(6, new CustomItem(Material.COMPARATOR, "&e" + SlimefunPlugin.getLocalization().getMessage(p, "guide.title.source"), "", "&7Last Activity: &a" + NumberUtils.getElapsedTime(SlimefunPlugin.getGitHubService().getLastUpdate()) + " ago", "&7Forks: &e" + SlimefunPlugin.getGitHubService().getForks(), "&7Stars: &e" + SlimefunPlugin.getGitHubService().getStars(), "", "&7&oSlimefun 4 is a community project,", "&7&othe source code is available on GitHub", "&7&oand if you want to keep this Plugin alive,", "&7&othen please consider contributing to it", "", "&7\u21E8 &eClick to go to GitHub"));
menu.addMenuClickHandler(6, (pl, slot, item, action) -> {
@ -110,7 +111,7 @@ public final class SlimefunGuideSettings {
menu.addItem(49, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler());
}
menu.addItem(51, new CustomItem(Material.TOTEM_OF_UNDYING, "&cSoon", "", "&7Something will be added here later..."), (pl, slot, item, action) -> {
menu.addItem(51, new CustomItem(Material.TOTEM_OF_UNDYING, ChatColor.RED + SlimefunPlugin.getLocalization().getMessage(p, "guide.work-in-progress")), (pl, slot, item, action) -> {
// Add something here
return false;
});

View File

@ -3,10 +3,12 @@ package io.github.thebusybiscuit.slimefun4.core.handlers;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.EntityInteractionListener;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler;
@ -15,9 +17,9 @@ import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler;
*
* @author Linox
*
* @see EntityInteractionListener
* @see ItemHandler
* @see SimpleSlimefunItem
* @see PlayerInteractAtEntityEvent
*
*/
@FunctionalInterface
@ -27,16 +29,14 @@ public interface EntityInteractHandler extends ItemHandler {
* This function is triggered when a {@link Player} right clicks with the assigned {@link SlimefunItem}
* in his hand.
*
* @param p
* The {@link Player} that right clicked
* @param entity
* The {@link Entity} that was right clicked on
* @param e
* The {@link PlayerInteractAtEntityEvent} which was called
* @param item
* The {@link ItemStack} that was held and used while triggering
* @param offHand
* <code>true</code> if the {@link EquipmentSlot} is off hand
*/
void onInteract(Player p, Entity entity, ItemStack item, boolean offHand);
void onInteract(PlayerInteractEntityEvent e, ItemStack item, boolean offHand);
@Override
default Class<? extends ItemHandler> getIdentifier() {

View File

@ -32,9 +32,11 @@ import org.bukkit.plugin.Plugin;
*/
public class MetricsService {
private static final String API_URL = "https://api.github.com/";
private static final String REPO_NAME = "MetricsModule";
private static final String GH_API = "https://api.github.com/repos/Slimefun/" + REPO_NAME;
private static final String GH_RELEASES = "https://github.com/Slimefun/" + REPO_NAME + "/releases/download";
private static final String RELEASES_URL = API_URL + "repos/Slimefun/" + REPO_NAME + "/releases/latest";
private static final String DOWNLOAD_URL = "https://github.com/Slimefun/" + REPO_NAME + "/releases/download";
private final SlimefunPlugin plugin;
private final File parentFolder;
@ -160,7 +162,7 @@ public class MetricsService {
*/
private int getLatestVersion() {
try {
HttpResponse<JsonNode> response = Unirest.get(GH_API + "/releases/latest").asJson();
HttpResponse<JsonNode> response = Unirest.get(RELEASES_URL).asJson();
if (!response.isSuccess()) {
return -1;
@ -198,7 +200,7 @@ public class MetricsService {
}
AtomicInteger lastPercentPosted = new AtomicInteger();
GetRequest request = Unirest.get(GH_RELEASES + "/" + version + "/" + REPO_NAME + ".jar");
GetRequest request = Unirest.get(DOWNLOAD_URL + "/" + version + "/" + REPO_NAME + ".jar");
HttpResponse<File> response = request.downloadMonitor((b, fileName, bytesWritten, totalBytes) -> {
int percent = (int) (20 * (Math.round((((double) bytesWritten / totalBytes) * 100) / 20)));

View File

@ -17,6 +17,8 @@ import kong.unirest.json.JSONException;
import me.mrCookieSlime.Slimefun.api.Slimefun;
abstract class GitHubConnector {
private static final String API_URL = "https://api.github.com/";
protected File file;
protected String repository;
@ -45,7 +47,7 @@ abstract class GitHubConnector {
}
try {
HttpResponse<JsonNode> resp = Unirest.get("https://api.github.com/repos/" + repository + getURLSuffix())
HttpResponse<JsonNode> resp = Unirest.get(API_URL + "repos/" + repository + getURLSuffix())
.header("User-Agent", "Slimefun4 (https://github.com/Slimefun)")
.asJson();

View File

@ -144,11 +144,11 @@ public final class SlimefunItems {
public static final SlimefunItemStack DIET_COOKIE = new SlimefunItemStack("DIET_COOKIE", Material.COOKIE, "&6Diet Cookie", "", "&aA very &olightweight &f&acookie.");
public static final SlimefunItemStack MAGIC_SUGAR = new SlimefunItemStack("MAGIC_SUGAR", Material.SUGAR, "&6Magic Sugar", "", "&a&oFeel the Power of Hermes!");
public static final SlimefunItemStack MONSTER_JERKY = new SlimefunItemStack("MONSTER_JERKY", Material.ROTTEN_FLESH, "&6Monster Jerky", "", "&a&oNo longer hungry");
public static final SlimefunItemStack APPLE_JUICE = new SlimefunItemStack("APPLE_JUICE", Color.RED, new PotionEffect(PotionEffectType.SATURATION, 6, 0), "&cApple Juice", "", LoreBuilder.hunger(3));
public static final SlimefunItemStack MELON_JUICE = new SlimefunItemStack("MELON_JUICE", Color.RED, new PotionEffect(PotionEffectType.SATURATION, 6, 0), "&cMelon Juice", "", LoreBuilder.hunger(3));
public static final SlimefunItemStack CARROT_JUICE = new SlimefunItemStack("CARROT_JUICE", Color.ORANGE, new PotionEffect(PotionEffectType.SATURATION, 6, 0), "&6Carrot Juice", "", LoreBuilder.hunger(3));
public static final SlimefunItemStack PUMPKIN_JUICE = new SlimefunItemStack("PUMPKIN_JUICE", Color.ORANGE, new PotionEffect(PotionEffectType.SATURATION, 6, 0), "&6Pumpkin Juice", "", LoreBuilder.hunger(3));
public static final SlimefunItemStack SWEET_BERRY_JUICE = new SlimefunItemStack("SWEET_BERRY_JUICE", Color.RED, new PotionEffect(PotionEffectType.SATURATION, 6, 0), "&cSweet Berry Juice", "", LoreBuilder.hunger(3));
public static final SlimefunItemStack APPLE_JUICE = new SlimefunItemStack("APPLE_JUICE", Color.RED, new PotionEffect(PotionEffectType.SATURATION, 5, 0), "&cApple Juice", "", LoreBuilder.hunger(3));
public static final SlimefunItemStack MELON_JUICE = new SlimefunItemStack("MELON_JUICE", Color.RED, new PotionEffect(PotionEffectType.SATURATION, 5, 0), "&cMelon Juice", "", LoreBuilder.hunger(3));
public static final SlimefunItemStack CARROT_JUICE = new SlimefunItemStack("CARROT_JUICE", Color.ORANGE, new PotionEffect(PotionEffectType.SATURATION, 5, 0), "&6Carrot Juice", "", LoreBuilder.hunger(3));
public static final SlimefunItemStack PUMPKIN_JUICE = new SlimefunItemStack("PUMPKIN_JUICE", Color.ORANGE, new PotionEffect(PotionEffectType.SATURATION, 5, 0), "&6Pumpkin Juice", "", LoreBuilder.hunger(3));
public static final SlimefunItemStack SWEET_BERRY_JUICE = new SlimefunItemStack("SWEET_BERRY_JUICE", Color.RED, new PotionEffect(PotionEffectType.SATURATION, 5, 0), "&cSweet Berry Juice", "", LoreBuilder.hunger(3));
public static final SlimefunItemStack GOLDEN_APPLE_JUICE = new SlimefunItemStack("GOLDEN_APPLE_JUICE", Color.YELLOW, new PotionEffect(PotionEffectType.ABSORPTION, 20 * 20, 0), "&bGolden Apple Juice");
public static final SlimefunItemStack BEEF_JERKY = new SlimefunItemStack("BEEF_JERKY", Material.COOKED_BEEF, "&6Beef Jerky", "", "&fExtra saturating!");
@ -161,14 +161,14 @@ public final class SlimefunItems {
public static final SlimefunItemStack KELP_COOKIE = new SlimefunItemStack("KELP_COOKIE", Material.COOKIE, "&2Kelp Cookie");
/* Christmas */
public static final SlimefunItemStack CHRISTMAS_MILK = new SlimefunItemStack("CHRISTMAS_MILK", Color.WHITE, new PotionEffect(PotionEffectType.SATURATION, 5, 0), "&6Glass of Milk", "", LoreBuilder.hunger(2.5));
public static final SlimefunItemStack CHRISTMAS_CHOCOLATE_MILK = new SlimefunItemStack("CHRISTMAS_CHOCOLATE_MILK", Color.MAROON, new PotionEffect(PotionEffectType.SATURATION, 12, 0), "&6Chocolate Milk", "", LoreBuilder.hunger(6));
public static final SlimefunItemStack CHRISTMAS_EGG_NOG = new SlimefunItemStack("CHRISTMAS_EGG_NOG", Color.GRAY, new PotionEffect(PotionEffectType.SATURATION, 7, 0), "&aEgg Nog", "", LoreBuilder.hunger(3.5));
public static final SlimefunItemStack CHRISTMAS_APPLE_CIDER = new SlimefunItemStack("CHRISTMAS_APPLE_CIDER", Color.RED, new PotionEffect(PotionEffectType.SATURATION, 14, 0), "&cApple Cider", "", LoreBuilder.hunger(7));
public static final SlimefunItemStack CHRISTMAS_MILK = new SlimefunItemStack("CHRISTMAS_MILK", Color.WHITE, new PotionEffect(PotionEffectType.SATURATION, 4, 0), "&6Glass of Milk", "", LoreBuilder.hunger(2.5));
public static final SlimefunItemStack CHRISTMAS_CHOCOLATE_MILK = new SlimefunItemStack("CHRISTMAS_CHOCOLATE_MILK", Color.MAROON, new PotionEffect(PotionEffectType.SATURATION, 11, 0), "&6Chocolate Milk", "", LoreBuilder.hunger(6));
public static final SlimefunItemStack CHRISTMAS_EGG_NOG = new SlimefunItemStack("CHRISTMAS_EGG_NOG", Color.GRAY, new PotionEffect(PotionEffectType.SATURATION, 6, 0), "&aEgg Nog", "", LoreBuilder.hunger(3.5));
public static final SlimefunItemStack CHRISTMAS_APPLE_CIDER = new SlimefunItemStack("CHRISTMAS_APPLE_CIDER", Color.RED, new PotionEffect(PotionEffectType.SATURATION, 13, 0), "&cApple Cider", "", LoreBuilder.hunger(7));
public static final SlimefunItemStack CHRISTMAS_COOKIE = new SlimefunItemStack("CHRISTMAS_COOKIE", Material.COOKIE, ChatUtils.christmas("Christmas Cookie"));
public static final SlimefunItemStack CHRISTMAS_FRUIT_CAKE = new SlimefunItemStack("CHRISTMAS_FRUIT_CAKE", Material.PUMPKIN_PIE, ChatUtils.christmas("Fruit Cake"));
public static final SlimefunItemStack CHRISTMAS_APPLE_PIE = new SlimefunItemStack("CHRISTMAS_APPLE_PIE", Material.PUMPKIN_PIE, "&fApple Pie");
public static final SlimefunItemStack CHRISTMAS_HOT_CHOCOLATE = new SlimefunItemStack("CHRISTMAS_HOT_CHOCOLATE", Color.MAROON, new PotionEffect(PotionEffectType.SATURATION, 14, 0), "&6Hot Chocolate", "", LoreBuilder.hunger(7));
public static final SlimefunItemStack CHRISTMAS_HOT_CHOCOLATE = new SlimefunItemStack("CHRISTMAS_HOT_CHOCOLATE", Color.MAROON, new PotionEffect(PotionEffectType.SATURATION, 13, 0), "&6Hot Chocolate", "", LoreBuilder.hunger(7));
public static final SlimefunItemStack CHRISTMAS_CAKE = new SlimefunItemStack("CHRISTMAS_CAKE", Material.PUMPKIN_PIE, ChatUtils.christmas("Christmas Cake"));
public static final SlimefunItemStack CHRISTMAS_CARAMEL = new SlimefunItemStack("CHRISTMAS_CARAMEL", Material.BRICK, "&6Caramel");
public static final SlimefunItemStack CHRISTMAS_CARAMEL_APPLE = new SlimefunItemStack("CHRISTMAS_CARAMEL_APPLE", Material.APPLE, "&6Caramel Apple");
@ -286,10 +286,10 @@ public final class SlimefunItems {
public static final SlimefunItemStack GILDED_IRON_LEGGINGS = new SlimefunItemStack("GILDED_IRON_LEGGINGS", Material.GOLDEN_LEGGINGS, "&6Gilded Iron Leggings");
public static final SlimefunItemStack GILDED_IRON_BOOTS = new SlimefunItemStack("GILDED_IRON_BOOTS", Material.GOLDEN_BOOTS, "&6Gilded Iron Boots");
public static final SlimefunItemStack GOLD_HELMET = new SlimefunItemStack("GOLD_12K_HELMET", Material.GOLDEN_HELMET, "&6Gold Helmet", "&912-Carat");
public static final SlimefunItemStack GOLD_CHESTPLATE = new SlimefunItemStack("GOLD_12K_CHESTPLATE", Material.GOLDEN_CHESTPLATE, "&6Gold Chestplate", "&912-Carat");
public static final SlimefunItemStack GOLD_LEGGINGS = new SlimefunItemStack("GOLD_12K_LEGGINGS", Material.GOLDEN_LEGGINGS, "&6Gold Leggings", "&912-Carat");
public static final SlimefunItemStack GOLD_BOOTS = new SlimefunItemStack("GOLD_12K_BOOTS", Material.GOLDEN_BOOTS, "&6Gold Boots", "&912-Carat");
public static final SlimefunItemStack GOLDEN_HELMET_12K = new SlimefunItemStack("GOLD_12K_HELMET", Material.GOLDEN_HELMET, "&6Golden Helmet &7(12-Carat)");
public static final SlimefunItemStack GOLDEN_CHESTPLATE_12K = new SlimefunItemStack("GOLD_12K_CHESTPLATE", Material.GOLDEN_CHESTPLATE, "&6Golden Chestplate &7(12-Carat)");
public static final SlimefunItemStack GOLDEN_LEGGINGS_12K = new SlimefunItemStack("GOLD_12K_LEGGINGS", Material.GOLDEN_LEGGINGS, "&6Golden Leggings &7(12-Carat)");
public static final SlimefunItemStack GOLDEN_BOOTS_12K = new SlimefunItemStack("GOLD_12K_BOOTS", Material.GOLDEN_BOOTS, "&6Golden Boots &7(12-Carat)");
public static final SlimefunItemStack SLIME_HELMET_STEEL = new SlimefunItemStack("SLIME_STEEL_HELMET", Material.IRON_HELMET, "&a&lSlime Helmet", "&7&oReinforced", "", "&a&oBouncy Feeling");
public static final SlimefunItemStack SLIME_CHESTPLATE_STEEL = new SlimefunItemStack("SLIME_STEEL_CHESTPLATE", Material.IRON_CHESTPLATE, "&a&lSlime Chestplate", "&7&oReinforced", "", "&a&oBouncy Feeling");
@ -335,10 +335,10 @@ public final class SlimefunItems {
GILDED_IRON_LEGGINGS.addUnsafeEnchantments(gilded);
GILDED_IRON_BOOTS.addUnsafeEnchantments(gilded);
GOLD_HELMET.addUnsafeEnchantment(Enchantment.DURABILITY, 10);
GOLD_CHESTPLATE.addUnsafeEnchantment(Enchantment.DURABILITY, 10);
GOLD_LEGGINGS.addUnsafeEnchantment(Enchantment.DURABILITY, 10);
GOLD_BOOTS.addUnsafeEnchantment(Enchantment.DURABILITY, 10);
GOLDEN_HELMET_12K.addUnsafeEnchantment(Enchantment.DURABILITY, 10);
GOLDEN_CHESTPLATE_12K.addUnsafeEnchantment(Enchantment.DURABILITY, 10);
GOLDEN_LEGGINGS_12K.addUnsafeEnchantment(Enchantment.DURABILITY, 10);
GOLDEN_BOOTS_12K.addUnsafeEnchantment(Enchantment.DURABILITY, 10);
Map<Enchantment, Integer> slime = new HashMap<>();
slime.put(Enchantment.DURABILITY, 4);
@ -407,12 +407,13 @@ public final class SlimefunItems {
public static final SlimefunItemStack ANCIENT_ALTAR = new SlimefunItemStack("ANCIENT_ALTAR", Material.ENCHANTING_TABLE, "&dAncient Altar", "", "&5Multi-Block Altar for", "&5magical Crafting Processes");
public static final SlimefunItemStack COPPER_WIRE = new SlimefunItemStack("COPPER_WIRE", Material.STRING, "&6Copper Wire", "", "&6Crucial component in electric modules");
public static final SlimefunItemStack RAINBOW_WOOL = new SlimefunItemStack("RAINBOW_WOOL", Material.WHITE_WOOL, "&5Rainbow Wool", "", "&dCycles through all Colors of the Rainbow!");
public static final SlimefunItemStack RAINBOW_GLASS = new SlimefunItemStack("RAINBOW_GLASS", Material.WHITE_STAINED_GLASS, "&5Rainbow Glass", "", "&dCycles through all Colors of the Rainbow!");
public static final SlimefunItemStack RAINBOW_CLAY = new SlimefunItemStack("RAINBOW_CLAY", Material.WHITE_TERRACOTTA, "&5Rainbow Clay", "", "&dCycles through all Colors of the Rainbow!");
public static final SlimefunItemStack RAINBOW_GLASS_PANE = new SlimefunItemStack("RAINBOW_GLASS_PANE", Material.WHITE_STAINED_GLASS_PANE, "&5Rainbow Glass Pane", "", "&dCycles through all Colors of the Rainbow!");
public static final SlimefunItemStack RAINBOW_CONCRETE = new SlimefunItemStack("RAINBOW_CONCRETE", Material.WHITE_CONCRETE, "&5Rainbow Concrete", "", "&dCycles through all Colors of the Rainbow!");
public static final SlimefunItemStack RAINBOW_GLAZED_TERRACOTTA = new SlimefunItemStack("RAINBOW_GLAZED_TERRACOTTA", Material.WHITE_GLAZED_TERRACOTTA, "&5Rainbow Glazed Terracotta", "", "&dCycles through all Colors of the Rainbow!");
private static final String RAINBOW = "&dCycles through all Colors of the Rainbow!";
public static final SlimefunItemStack RAINBOW_WOOL = new SlimefunItemStack("RAINBOW_WOOL", Material.WHITE_WOOL, "&5Rainbow Wool", "", RAINBOW);
public static final SlimefunItemStack RAINBOW_GLASS = new SlimefunItemStack("RAINBOW_GLASS", Material.WHITE_STAINED_GLASS, "&5Rainbow Glass", "", RAINBOW);
public static final SlimefunItemStack RAINBOW_CLAY = new SlimefunItemStack("RAINBOW_CLAY", Material.WHITE_TERRACOTTA, "&5Rainbow Clay", "", RAINBOW);
public static final SlimefunItemStack RAINBOW_GLASS_PANE = new SlimefunItemStack("RAINBOW_GLASS_PANE", Material.WHITE_STAINED_GLASS_PANE, "&5Rainbow Glass Pane", "", RAINBOW);
public static final SlimefunItemStack RAINBOW_CONCRETE = new SlimefunItemStack("RAINBOW_CONCRETE", Material.WHITE_CONCRETE, "&5Rainbow Concrete", "", RAINBOW);
public static final SlimefunItemStack RAINBOW_GLAZED_TERRACOTTA = new SlimefunItemStack("RAINBOW_GLAZED_TERRACOTTA", Material.WHITE_GLAZED_TERRACOTTA, "&5Rainbow Glazed Terracotta", "", RAINBOW);
/* Seasonal */
private static final String CHRISTMAS = ChatUtils.christmas("[Christmas Edition]");

View File

@ -70,7 +70,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.ItemPickupLis
import io.github.thebusybiscuit.slimefun4.implementation.listeners.MobDropListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.MultiBlockListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.PiglinListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.PlayerInteractEntityListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.EntityInteractionListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.PlayerProfileListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.SeismicAxeListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunBootsListener;
@ -82,6 +82,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.SoulboundList
import io.github.thebusybiscuit.slimefun4.implementation.listeners.TalismanListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.VampireBladeListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.VanillaMachinesListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.VillagerTradingListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.WitherListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.WorldListener;
import io.github.thebusybiscuit.slimefun4.implementation.resources.GEOResourcesSetup;
@ -165,6 +166,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
local = new LocalizationService(this, "", null);
gpsNetwork = new GPSNetwork();
command.register();
registry.load(config);
}
else if (getServer().getPluginManager().isPluginEnabled("CS-CoreLib")) {
long timestamp = System.nanoTime();
@ -440,8 +442,9 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
new FireworksListener(this);
new WitherListener(this);
new IronGolemListener(this);
new PlayerInteractEntityListener(this);
new EntityInteractionListener(this);
new MobDropListener(this);
new VillagerTradingListener(this);
if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_15)) {
new BeeListener(this);

View File

@ -10,6 +10,7 @@ import org.bukkit.Material;
import org.bukkit.NamespacedKey;
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.cscorelib2.chat.ChatInput;
@ -18,7 +19,6 @@ import io.github.thebusybiscuit.cscorelib2.chat.json.ClickEvent;
import io.github.thebusybiscuit.cscorelib2.chat.json.CustomBookInterface;
import io.github.thebusybiscuit.cscorelib2.chat.json.HoverEvent;
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.categories.FlexCategory;
import io.github.thebusybiscuit.slimefun4.core.categories.LockedCategory;
@ -36,6 +36,24 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
public class BookSlimefunGuide implements SlimefunGuideImplementation {
private final NamespacedKey guideSearch = new NamespacedKey(SlimefunPlugin.instance(), "search");
private final ItemStack item;
public BookSlimefunGuide() {
item = new ItemStack(Material.ENCHANTED_BOOK);
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(ChatColors.color("&aSlimefun Guide &7(Book GUI)"));
List<String> lore = new LinkedList<>();
lore.add("");
lore.add(ChatColors.color("&eRight Click &8\u21E8 &7Browse Items"));
lore.add(ChatColors.color("&eShift + Right Click &8\u21E8 &7Open Settings / Credits"));
meta.setLore(lore);
SlimefunPlugin.getItemTextureService().setTexture(meta, "SLIMEFUN_GUIDE");
item.setItemMeta(meta);
}
@Override
public SlimefunGuideLayout getLayout() {
@ -49,7 +67,7 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation {
@Override
public ItemStack getItem() {
return new CustomItem(new ItemStack(Material.ENCHANTED_BOOK), "&aSlimefun Guide &7(Book GUI)", "", "&eRight Click &8\u21E8 &7Browse Items", "&eShift + Right Click &8\u21E8 &7Open Settings / Credits");
return item;
}
private void openBook(Player p, PlayerProfile profile, List<ChatComponent> lines, boolean backButton) {
@ -112,37 +130,41 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation {
lines.add(new ChatComponent(ChatColor.DARK_GRAY + "\u21E8" + ChatColor.DARK_BLUE + " Tier " + tier + "\n"));
}
if (category instanceof LockedCategory && !((LockedCategory) category).hasUnlocked(p, profile)) {
List<String> lore = new LinkedList<>();
lore.add(ChatColor.DARK_RED + SlimefunPlugin.getLocalization().getMessage(p, "guide.locked") + " " + ChatColor.GRAY + "- " + ChatColor.RESET + category.getItem(p).getItemMeta().getDisplayName());
lore.add("");
for (String line : SlimefunPlugin.getLocalization().getMessages(p, "guide.locked-category")) {
lore.add(ChatColor.RESET + line);
}
lore.add("");
for (Category parent : ((LockedCategory) category).getParents()) {
lore.add(parent.getItem(p).getItemMeta().getDisplayName());
}
ChatComponent chatComponent = new ChatComponent(ChatUtils.crop(ChatColor.RED, ItemUtils.getItemName(category.getItem(p))) + "\n");
chatComponent.setHoverEvent(new HoverEvent(lore));
lines.add(chatComponent);
}
else {
ChatComponent chatComponent = new ChatComponent(ChatUtils.crop(ChatColor.DARK_GREEN, ItemUtils.getItemName(category.getItem(p))) + "\n");
chatComponent.setHoverEvent(new HoverEvent(ItemUtils.getItemName(category.getItem(p)), "", ChatColor.GRAY + "\u21E8 " + ChatColor.GREEN + SlimefunPlugin.getLocalization().getMessage(p, "guide.tooltips.open-category")));
chatComponent.setClickEvent(new ClickEvent(category.getKey(), pl -> openCategory(profile, category, 1)));
lines.add(chatComponent);
}
addCategory(p, profile, category, lines);
}
}
openBook(p, profile, lines, false);
}
private void addCategory(Player p, PlayerProfile profile, Category category, List<ChatComponent> lines) {
if (category instanceof LockedCategory && !((LockedCategory) category).hasUnlocked(p, profile)) {
List<String> lore = new LinkedList<>();
lore.add(ChatColor.DARK_RED + SlimefunPlugin.getLocalization().getMessage(p, "guide.locked") + " " + ChatColor.GRAY + "- " + ChatColor.RESET + category.getItem(p).getItemMeta().getDisplayName());
lore.add("");
for (String line : SlimefunPlugin.getLocalization().getMessages(p, "guide.locked-category")) {
lore.add(ChatColor.RESET + line);
}
lore.add("");
for (Category parent : ((LockedCategory) category).getParents()) {
lore.add(parent.getItem(p).getItemMeta().getDisplayName());
}
ChatComponent chatComponent = new ChatComponent(ChatUtils.crop(ChatColor.RED, ItemUtils.getItemName(category.getItem(p))) + "\n");
chatComponent.setHoverEvent(new HoverEvent(lore));
lines.add(chatComponent);
}
else {
ChatComponent chatComponent = new ChatComponent(ChatUtils.crop(ChatColor.DARK_GREEN, ItemUtils.getItemName(category.getItem(p))) + "\n");
chatComponent.setHoverEvent(new HoverEvent(ItemUtils.getItemName(category.getItem(p)), "", ChatColor.GRAY + "\u21E8 " + ChatColor.GREEN + SlimefunPlugin.getLocalization().getMessage(p, "guide.tooltips.open-category")));
chatComponent.setClickEvent(new ClickEvent(category.getKey(), pl -> openCategory(profile, category, 1)));
lines.add(chatComponent);
}
}
@Override
public void openCategory(PlayerProfile profile, Category category, int page) {
Player p = profile.getPlayer();
@ -159,20 +181,20 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation {
List<ChatComponent> items = new LinkedList<>();
for (SlimefunItem item : category.getItems()) {
if (Slimefun.hasPermission(p, item, false)) {
if (Slimefun.isEnabled(p, item, false)) {
appendSlimefunItem(category, page, p, profile, item, items);
for (SlimefunItem slimefunItem : category.getItems()) {
if (Slimefun.hasPermission(p, slimefunItem, false)) {
if (Slimefun.isEnabled(p, slimefunItem, false)) {
addSlimefunItem(category, page, p, profile, slimefunItem, items);
}
}
else {
ChatComponent component = new ChatComponent(ChatUtils.crop(ChatColor.DARK_RED, ItemUtils.getItemName(item.getItem())) + "\n");
ChatComponent component = new ChatComponent(ChatUtils.crop(ChatColor.DARK_RED, ItemUtils.getItemName(slimefunItem.getItem())) + "\n");
List<String> lore = new ArrayList<>();
lore.add(ChatColor.DARK_RED + ChatColor.stripColor(ItemUtils.getItemName(item.getItem())));
lore.add(ChatColor.DARK_RED + ChatColor.stripColor(ItemUtils.getItemName(slimefunItem.getItem())));
lore.add("");
for (String line : SlimefunPlugin.getPermissionsService().getLore(item)) {
for (String line : SlimefunPlugin.getPermissionsService().getLore(slimefunItem)) {
lore.add(ChatColors.color(line));
}
@ -188,7 +210,7 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation {
}
}
private void appendSlimefunItem(Category category, int page, Player p, PlayerProfile profile, SlimefunItem item, List<ChatComponent> items) {
private void addSlimefunItem(Category category, int page, Player p, PlayerProfile profile, SlimefunItem item, List<ChatComponent> items) {
NamespacedKey key = new NamespacedKey(SlimefunPlugin.instance(), item.getID().toLowerCase(Locale.ROOT));
if (!Slimefun.hasUnlocked(p, item, false) && item.getResearch() != null) {
@ -196,21 +218,7 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation {
ChatComponent component = new ChatComponent(ChatUtils.crop(ChatColor.RED, item.getItemName()) + "\n");
component.setHoverEvent(new HoverEvent(ChatColor.RESET + item.getItemName(), ChatColor.DARK_RED.toString() + ChatColor.BOLD + SlimefunPlugin.getLocalization().getMessage(p, "guide.locked"), "", ChatColor.GREEN + "> Click to unlock", "", ChatColor.GRAY + "Cost: " + ChatColor.AQUA.toString() + research.getCost() + " Level(s)"));
component.setClickEvent(new ClickEvent(key, player -> Slimefun.runSync(() -> {
if (!SlimefunPlugin.getRegistry().getCurrentlyResearchingPlayers().contains(p.getUniqueId())) {
if (research.canUnlock(p)) {
if (profile.hasUnlocked(research)) {
openCategory(profile, category, page);
}
else {
unlockItem(p, item, pl -> openCategory(profile, category, page));
}
}
else {
SlimefunPlugin.getLocalization().sendMessage(p, "messages.not-enough-xp", true);
}
}
})));
component.setClickEvent(new ClickEvent(key, player -> research(player, profile, item, research, category, page)));
items.add(component);
}
@ -230,6 +238,24 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation {
}
}
private void research(Player p, PlayerProfile profile, SlimefunItem item, Research research, Category category, int page) {
Slimefun.runSync(() -> {
if (!SlimefunPlugin.getRegistry().getCurrentlyResearchingPlayers().contains(p.getUniqueId())) {
if (research.canUnlock(p)) {
if (profile.hasUnlocked(research)) {
openCategory(profile, category, page);
}
else {
unlockItem(p, item, pl -> openCategory(profile, category, page));
}
}
else {
SlimefunPlugin.getLocalization().sendMessage(p, "messages.not-enough-xp", true);
}
}
});
}
@Override
public void openSearch(PlayerProfile profile, String input, boolean addToHistory) {
// We need to write a book implementation for this at some point

View File

@ -1,16 +1,41 @@
package io.github.thebusybiscuit.slimefun4.implementation.guide;
import org.bukkit.entity.Player;
import java.util.LinkedList;
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.api.player.PlayerProfile;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
public class CheatSheetSlimefunGuide extends ChestSlimefunGuide {
private final ItemStack item;
public CheatSheetSlimefunGuide() {
super(false);
item = new ItemStack(Material.ENCHANTED_BOOK);
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(ChatColors.color("&cSlimefun Guide &4(Cheat Sheet)"));
List<String> lore = new LinkedList<>();
lore.add(ChatColors.color("&4&lOnly openable by Admins"));
lore.add(ChatColors.color("&eRight Click &8\u21E8 &7Browse Items"));
lore.add(ChatColors.color("&eShift + Right Click &8\u21E8 &7Open Settings / Credits"));
meta.setLore(lore);
SlimefunPlugin.getItemTextureService().setTexture(meta, "SLIMEFUN_GUIDE");
item.setItemMeta(meta);
}
@Override
@ -23,6 +48,11 @@ public class CheatSheetSlimefunGuide extends ChestSlimefunGuide {
return SlimefunGuideLayout.CHEAT_SHEET;
}
@Override
public ItemStack getItem() {
return item;
}
@Override
protected void createHeader(Player p, PlayerProfile profile, ChestMenu menu) {
super.createHeader(p, profile, menu);

View File

@ -18,7 +18,9 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Recipe;
import org.bukkit.inventory.RecipeChoice;
import org.bukkit.inventory.RecipeChoice.MaterialChoice;
import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.cscorelib2.chat.ChatInput;
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
@ -50,6 +52,7 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
private static final int CATEGORY_SIZE = 36;
private final ItemStack item;
private final int[] recipeSlots = { 3, 4, 5, 12, 13, 14, 21, 22, 23 };
private final Sound sound;
private final boolean showVanillaRecipes;
@ -63,6 +66,21 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
else {
sound = Sound.ENTITY_BAT_TAKEOFF;
}
item = new ItemStack(Material.ENCHANTED_BOOK);
ItemMeta meta = item.getItemMeta();
meta.setDisplayName(ChatColors.color("&aSlimefun Guide &7(Chest GUI)"));
List<String> lore = new LinkedList<>();
lore.add("");
lore.add(ChatColors.color("&eRight Click &8\u21E8 &7Browse Items"));
lore.add(ChatColors.color("&eShift + Right Click &8\u21E8 &7Open Settings / Credits"));
meta.setLore(lore);
SlimefunPlugin.getItemTextureService().setTexture(meta, "SLIMEFUN_GUIDE");
item.setItemMeta(meta);
}
@Override
@ -72,7 +90,7 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
@Override
public ItemStack getItem() {
return new CustomItem(new ItemStack(Material.ENCHANTED_BOOK), "&aSlimefun Guide &7(Chest GUI)", "", "&eRight Click &8\u21E8 &7Browse Items", "&eShift + Right Click &8\u21E8 &7Open Settings / Credits");
return item;
}
@Override
@ -313,17 +331,17 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
int index = 9;
// Find items and add them
for (SlimefunItem item : SlimefunPlugin.getRegistry().getEnabledSlimefunItems()) {
String itemName = ChatColor.stripColor(item.getItemName()).toLowerCase(Locale.ROOT);
for (SlimefunItem slimefunItem : SlimefunPlugin.getRegistry().getEnabledSlimefunItems()) {
String itemName = ChatColor.stripColor(slimefunItem.getItemName()).toLowerCase(Locale.ROOT);
if (index == 44) {
break;
}
if (!itemName.isEmpty() && (itemName.equals(searchTerm) || itemName.contains(searchTerm))) {
ItemStack itemstack = new CustomItem(item.getItem(), meta -> {
ItemStack itemstack = new CustomItem(slimefunItem.getItem(), meta -> {
List<String> lore = null;
Category category = item.getCategory();
Category category = slimefunItem.getCategory();
if (category != null) {
ItemStack categoryItem = category.getItem(p);
@ -341,10 +359,10 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
menu.addMenuClickHandler(index, (pl, slot, itm, action) -> {
try {
if (!isSurvivalMode()) {
pl.getInventory().addItem(item.getItem().clone());
pl.getInventory().addItem(slimefunItem.getItem().clone());
}
else {
displayItem(profile, item, true);
displayItem(profile, slimefunItem, true);
}
}
catch (Exception | LinkageError x) {
@ -400,30 +418,9 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
RecipeChoiceTask task = new RecipeChoiceTask();
if (optional.isPresent()) {
MinecraftRecipe<?> mcRecipe = optional.get();
showRecipeChoices(recipe, recipeItems, task);
RecipeChoice[] choices = SlimefunPlugin.getMinecraftRecipeService().getRecipeShape(recipe);
if (choices.length == 1 && choices[0] instanceof MaterialChoice) {
recipeItems[4] = new ItemStack(((MaterialChoice) choices[0]).getChoices().get(0));
if (((MaterialChoice) choices[0]).getChoices().size() > 1) {
task.add(recipeSlots[4], (MaterialChoice) choices[0]);
}
}
else {
for (int i = 0; i < choices.length; i++) {
if (choices[i] instanceof MaterialChoice) {
recipeItems[i] = new ItemStack(((MaterialChoice) choices[i]).getChoices().get(0));
if (((MaterialChoice) choices[i]).getChoices().size() > 1) {
task.add(recipeSlots[i], (MaterialChoice) choices[i]);
}
}
}
}
recipeType = new RecipeType(mcRecipe);
recipeType = new RecipeType(optional.get());
result = recipe.getResult();
}
else {
@ -465,6 +462,29 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
}
}
private <T extends Recipe> void showRecipeChoices(T recipe, ItemStack[] recipeItems, RecipeChoiceTask task) {
RecipeChoice[] choices = SlimefunPlugin.getMinecraftRecipeService().getRecipeShape(recipe);
if (choices.length == 1 && choices[0] instanceof MaterialChoice) {
recipeItems[4] = new ItemStack(((MaterialChoice) choices[0]).getChoices().get(0));
if (((MaterialChoice) choices[0]).getChoices().size() > 1) {
task.add(recipeSlots[4], (MaterialChoice) choices[0]);
}
}
else {
for (int i = 0; i < choices.length; i++) {
if (choices[i] instanceof MaterialChoice) {
recipeItems[i] = new ItemStack(((MaterialChoice) choices[i]).getChoices().get(0));
if (((MaterialChoice) choices[i]).getChoices().size() > 1) {
task.add(recipeSlots[i], (MaterialChoice) choices[i]);
}
}
}
}
}
@Override
public void displayItem(PlayerProfile profile, SlimefunItem item, boolean addToHistory) {
Player p = profile.getPlayer();
@ -670,15 +690,15 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
private void addDisplayRecipe(ChestMenu menu, PlayerProfile profile, List<ItemStack> recipes, int slot, int i, int page) {
if ((i + (page * 18)) < recipes.size()) {
ItemStack item = recipes.get(i + (page * 18));
ItemStack displayItem = recipes.get(i + (page * 18));
// We want to clone this item to avoid corrupting the original
// but we wanna make sure no stupid addon creator sneaked some nulls in here
if (item != null) {
item = item.clone();
if (displayItem != null) {
displayItem = displayItem.clone();
}
menu.replaceExistingItem(slot, item);
menu.replaceExistingItem(slot, displayItem);
if (page == 0) {
menu.addMenuClickHandler(slot, (pl, s, itemstack, action) -> {

View File

@ -174,7 +174,9 @@ public abstract class ProgrammableAndroid extends SlimefunItem implements Invent
*
* @return The type of this {@link ProgrammableAndroid}
*/
public abstract AndroidType getAndroidType();
public AndroidType getAndroidType() {
return AndroidType.NONE;
}
/**
* This returns the {@link AndroidFuelSource} for this {@link ProgrammableAndroid}.

View File

@ -2,19 +2,33 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.cargo;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.ChatUtils;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow;
/**
* This abstract class is the super class of all cargo nodes.
*
* @author TheBusyBiscuit
*
*/
abstract class AbstractCargoNode extends SlimefunItem {
protected static final String FREQUENCY = "frequency";
@ -22,6 +36,21 @@ abstract class AbstractCargoNode extends SlimefunItem {
public AbstractCargoNode(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
super(category, item, recipeType, recipe, recipeOutput);
addItemHandler(new BlockPlaceHandler(false) {
@Override
public void onPlayerPlace(BlockPlaceEvent e) {
Block b = e.getBlock();
// The owner and frequency are required by every node
BlockStorage.addBlockInfo(b, "owner", e.getPlayer().getUniqueId().toString());
BlockStorage.addBlockInfo(b, FREQUENCY, "0");
onPlace(e);
}
});
new BlockMenuPreset(getID(), ChatUtils.removeColorCodes(item.getItemMeta().getDisplayName())) {
@Override
@ -46,6 +75,59 @@ abstract class AbstractCargoNode extends SlimefunItem {
};
}
protected void addChannelSelector(Block b, BlockMenu menu, int slotPrev, int slotCurrent, int slotNext) {
boolean isChestTerminalInstalled = SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled();
menu.replaceExistingItem(slotPrev, new CustomItem(SlimefunUtils.getCustomHead(HeadTexture.CARGO_ARROW_LEFT.getTexture()), "&bPrevious Channel", "", "&e> Click to decrease the Channel ID by 1"));
menu.addMenuClickHandler(slotPrev, (p, slot, item, action) -> {
int channel = Integer.parseInt(BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY)) - 1;
if (channel < 0) {
if (isChestTerminalInstalled) {
channel = 16;
}
else {
channel = 15;
}
}
BlockStorage.addBlockInfo(b, FREQUENCY, String.valueOf(channel));
updateBlockMenu(menu, b);
return false;
});
int channel = ((!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY) == null) ? 0 : (Integer.parseInt(BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY))));
if (channel == 16) {
menu.replaceExistingItem(slotCurrent, new CustomItem(SlimefunUtils.getCustomHead(HeadTexture.CHEST_TERMINAL.getTexture()), "&bChannel ID: &3" + (channel + 1)));
menu.addMenuClickHandler(slotCurrent, ChestMenuUtils.getEmptyClickHandler());
}
else {
menu.replaceExistingItem(slotCurrent, new CustomItem(MaterialCollections.getAllWoolColors().get(channel), "&bChannel ID: &3" + (channel + 1)));
menu.addMenuClickHandler(slotCurrent, ChestMenuUtils.getEmptyClickHandler());
}
menu.replaceExistingItem(slotNext, new CustomItem(SlimefunUtils.getCustomHead(HeadTexture.CARGO_ARROW_RIGHT.getTexture()), "&bNext Channel", "", "&e> Click to increase the Channel ID by 1"));
menu.addMenuClickHandler(slotNext, (p, slot, item, action) -> {
int channeln = Integer.parseInt(BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY)) + 1;
if (isChestTerminalInstalled) {
if (channeln > 16) {
channeln = 0;
}
}
else if (channeln > 15) {
channeln = 0;
}
BlockStorage.addBlockInfo(b, FREQUENCY, String.valueOf(channeln));
updateBlockMenu(menu, b);
return false;
});
}
protected abstract void onPlace(BlockPlaceEvent e);
protected abstract void createBorder(BlockMenuPreset preset);
protected abstract void updateBlockMenu(BlockMenu menu, Block b);

View File

@ -0,0 +1,140 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.cargo;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
/**
* This abstract super class represents all filtered Cargo nodes.
*
* @author TheBusyBiscuit
*
* @see CargoInputNode
* @see AdvancedCargoOutputNode
*
*/
abstract class AbstractFilterNode extends AbstractCargoNode {
protected static final int[] SLOTS = { 19, 20, 21, 28, 29, 30, 37, 38, 39 };
public AbstractFilterNode(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
super(category, item, recipeType, recipe, recipeOutput);
registerBlockHandler(getID(), (p, b, stack, reason) -> {
BlockMenu inv = BlockStorage.getInventory(b);
if (inv != null) {
inv.dropItems(b.getLocation(), SLOTS);
}
return true;
});
}
protected abstract int[] getBorder();
@Override
protected void onPlace(BlockPlaceEvent e) {
Block b = e.getBlock();
BlockStorage.addBlockInfo(b, "index", "0");
BlockStorage.addBlockInfo(b, "filter-type", "whitelist");
BlockStorage.addBlockInfo(b, "filter-lore", String.valueOf(true));
BlockStorage.addBlockInfo(b, "filter-durability", String.valueOf(false));
}
@Override
protected void createBorder(BlockMenuPreset preset) {
for (int i : getBorder()) {
preset.addItem(i, new CustomItem(Material.CYAN_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler());
}
preset.addItem(2, new CustomItem(Material.PAPER, "&3Items", "", "&bPut in all Items you want to", "&bblacklist/whitelist"), ChestMenuUtils.getEmptyClickHandler());
}
@Override
protected void updateBlockMenu(BlockMenu menu, Block b) {
String filterType = BlockStorage.getLocationInfo(b.getLocation(), "filter-type");
if (!BlockStorage.hasBlockInfo(b) || filterType == null || filterType.equals("whitelist")) {
menu.replaceExistingItem(15, new CustomItem(Material.WHITE_WOOL, "&7Type: &rWhitelist", "", "&e> Click to change it to Blacklist"));
menu.addMenuClickHandler(15, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, "filter-type", "blacklist");
updateBlockMenu(menu, b);
return false;
});
}
else {
menu.replaceExistingItem(15, new CustomItem(Material.BLACK_WOOL, "&7Type: &8Blacklist", "", "&e> Click to change it to Whitelist"));
menu.addMenuClickHandler(15, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, "filter-type", "whitelist");
updateBlockMenu(menu, b);
return false;
});
}
String durability = BlockStorage.getLocationInfo(b.getLocation(), "filter-durability");
if (!BlockStorage.hasBlockInfo(b) || durability == null || durability.equals(String.valueOf(false))) {
ItemStack is = new ItemStack(Material.STONE_SWORD);
ItemMeta meta = is.getItemMeta();
meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
is.setItemMeta(meta);
menu.replaceExistingItem(16, new CustomItem(is, "&7Include Sub-IDs/Durability: &4\u2718", "", "&e> Click to toggle whether the Durability has to match"));
menu.addMenuClickHandler(16, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, "filter-durability", String.valueOf(true));
updateBlockMenu(menu, b);
return false;
});
}
else {
ItemStack is = new ItemStack(Material.GOLDEN_SWORD);
ItemMeta meta = is.getItemMeta();
meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
((Damageable) meta).setDamage(20);
is.setItemMeta(meta);
menu.replaceExistingItem(16, new CustomItem(is, "&7Include Sub-IDs/Durability: &2\u2714", "", "&e> Click to toggle whether the Durability has to match"));
menu.addMenuClickHandler(16, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, "filter-durability", String.valueOf(false));
updateBlockMenu(menu, b);
return false;
});
}
String lore = BlockStorage.getLocationInfo(b.getLocation(), "filter-lore");
if (!BlockStorage.hasBlockInfo(b) || lore == null || lore.equals(String.valueOf(true))) {
menu.replaceExistingItem(25, new CustomItem(Material.MAP, "&7Include Lore: &2\u2714", "", "&e> Click to toggle whether the Lore has to match"));
menu.addMenuClickHandler(25, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, "filter-lore", String.valueOf(false));
updateBlockMenu(menu, b);
return false;
});
}
else {
menu.replaceExistingItem(25, new CustomItem(Material.MAP, "&7Include Lore: &4\u2718", "", "&e> Click to toggle whether the Lore has to match"));
menu.addMenuClickHandler(25, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, "filter-lore", String.valueOf(true));
updateBlockMenu(menu, b);
return false;
});
}
addChannelSelector(b, menu, 41, 42, 43);
}
}

View File

@ -1,165 +1,22 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.cargo;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections;
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
public class AdvancedCargoOutputNode extends AbstractCargoNode {
public class AdvancedCargoOutputNode extends AbstractFilterNode {
private static final int[] BORDER = { 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 18, 22, 23, 24, 26, 27, 31, 32, 33, 34, 35, 36, 40, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53 };
private static final int[] SLOTS = { 19, 20, 21, 28, 29, 30, 37, 38, 39 };
public AdvancedCargoOutputNode(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
super(category, item, recipeType, recipe, recipeOutput);
addItemHandler(onPlace());
registerBlockHandler(getID(), (p, b, stack, reason) -> {
BlockMenu inv = BlockStorage.getInventory(b);
if (inv != null) {
inv.dropItems(b.getLocation(), SLOTS);
}
return true;
});
}
private BlockPlaceHandler onPlace() {
return new BlockPlaceHandler(false) {
@Override
public void onPlayerPlace(BlockPlaceEvent e) {
Block b = e.getBlock();
BlockStorage.addBlockInfo(b, "owner", e.getPlayer().getUniqueId().toString());
BlockStorage.addBlockInfo(b, "index", "0");
BlockStorage.addBlockInfo(b, FREQUENCY, "0");
BlockStorage.addBlockInfo(b, "filter-type", "whitelist");
BlockStorage.addBlockInfo(b, "filter-lore", String.valueOf(true));
BlockStorage.addBlockInfo(b, "filter-durability", String.valueOf(false));
}
};
public AdvancedCargoOutputNode(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe, null);
}
@Override
protected void createBorder(BlockMenuPreset preset) {
for (int i : BORDER) {
preset.addItem(i, new CustomItem(Material.CYAN_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler());
}
preset.addItem(2, new CustomItem(Material.PAPER, "&3Items", "", "&bPut in all Items you want to", "&bblacklist/whitelist"), ChestMenuUtils.getEmptyClickHandler());
}
@Override
protected void updateBlockMenu(BlockMenu menu, Block b) {
if (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), "filter-type") == null || BlockStorage.getLocationInfo(b.getLocation(), "filter-type").equals("whitelist")) {
menu.replaceExistingItem(15, new CustomItem(Material.WHITE_WOOL, "&7Type: &rWhitelist", "", "&e> Click to change it to Blacklist"));
menu.addMenuClickHandler(15, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, "filter-type", "blacklist");
updateBlockMenu(menu, b);
return false;
});
}
else {
menu.replaceExistingItem(15, new CustomItem(Material.BLACK_WOOL, "&7Type: &8Blacklist", "", "&e> Click to change it to Whitelist"));
menu.addMenuClickHandler(15, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, "filter-type", "whitelist");
updateBlockMenu(menu, b);
return false;
});
}
if (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), "filter-durability") == null || BlockStorage.getLocationInfo(b.getLocation(), "filter-durability").equals(String.valueOf(false))) {
menu.replaceExistingItem(16, new CustomItem(Material.STONE_SWORD, "&7Include Sub-IDs/Durability: &4\u2718", "", "&e> Click to toggle whether the Durability has to match"));
menu.addMenuClickHandler(16, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, "filter-durability", String.valueOf(true));
updateBlockMenu(menu, b);
return false;
});
}
else {
ItemStack is = new ItemStack(Material.GOLDEN_SWORD);
Damageable dmg = (Damageable) is.getItemMeta();
dmg.setDamage(20);
is.setItemMeta((ItemMeta) dmg);
menu.replaceExistingItem(16, new CustomItem(is, "&7Include Sub-IDs/Durability: &2\u2714", "", "&e> Click to toggle whether the Durability has to match"));
menu.addMenuClickHandler(16, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, "filter-durability", String.valueOf(false));
updateBlockMenu(menu, b);
return false;
});
}
if (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), "filter-lore") == null || BlockStorage.getLocationInfo(b.getLocation(), "filter-lore").equals(String.valueOf(true))) {
menu.replaceExistingItem(25, new CustomItem(Material.MAP, "&7Include Lore: &2\u2714", "", "&e> Click to toggle whether the Lore has to match"));
menu.addMenuClickHandler(25, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, "filter-lore", String.valueOf(false));
updateBlockMenu(menu, b);
return false;
});
}
else {
menu.replaceExistingItem(25, new CustomItem(Material.MAP, "&7Include Lore: &4\u2718", "", "&e> Click to toggle whether the Lore has to match"));
menu.addMenuClickHandler(25, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, "filter-lore", String.valueOf(true));
updateBlockMenu(menu, b);
return false;
});
}
menu.replaceExistingItem(41, new CustomItem(SlimefunUtils.getCustomHead("f2599bd986659b8ce2c4988525c94e19ddd39fad08a38284a197f1b70675acc"), "&bChannel", "", "&e> Click to decrease the Channel ID by 1"));
menu.addMenuClickHandler(41, (p, slot, item, action) -> {
int channel = Integer.parseInt(BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY)) - 1;
if (channel < 0) {
if (SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled()) channel = 16;
else channel = 15;
}
BlockStorage.addBlockInfo(b, FREQUENCY, String.valueOf(channel));
updateBlockMenu(menu, b);
return false;
});
int channel = ((!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY) == null) ? 0 : (Integer.parseInt(BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY))));
if (channel == 16) {
menu.replaceExistingItem(42, new CustomItem(SlimefunUtils.getCustomHead("7a44ff3a5f49c69cab676bad8d98a063fa78cfa61916fdef3e267557fec18283"), "&bChannel ID: &3" + (channel + 1)));
menu.addMenuClickHandler(42, ChestMenuUtils.getEmptyClickHandler());
}
else {
menu.replaceExistingItem(42, new CustomItem(MaterialCollections.getAllWoolColors().get(channel), "&bChannel ID: &3" + (channel + 1)));
menu.addMenuClickHandler(42, ChestMenuUtils.getEmptyClickHandler());
}
menu.replaceExistingItem(43, new CustomItem(SlimefunUtils.getCustomHead("c2f910c47da042e4aa28af6cc81cf48ac6caf37dab35f88db993accb9dfe516"), "&bChannel", "", "&e> Click to increase the Channel ID by 1"));
menu.addMenuClickHandler(43, (p, slot, item, action) -> {
int channeln = Integer.parseInt(BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY)) + 1;
if (SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled()) {
if (channeln > 16) channeln = 0;
}
else {
if (channeln > 15) channeln = 0;
}
BlockStorage.addBlockInfo(b, FREQUENCY, String.valueOf(channeln));
updateBlockMenu(menu, b);
return false;
});
protected int[] getBorder() {
return BORDER;
}
}

View File

@ -1,114 +1,44 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.cargo;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections;
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
public class CargoInputNode extends AbstractCargoNode {
public class CargoInputNode extends AbstractFilterNode {
private static final int[] BORDER = { 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 18, 22, 23, 26, 27, 31, 32, 33, 34, 35, 36, 40, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53 };
private static final int[] SLOTS = { 19, 20, 21, 28, 29, 30, 37, 38, 39 };
public CargoInputNode(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
super(category, item, recipeType, recipe, recipeOutput);
addItemHandler(onPlace());
registerBlockHandler(getID(), (p, b, stack, reason) -> {
BlockMenu inv = BlockStorage.getInventory(b);
if (inv != null) {
inv.dropItems(b.getLocation(), SLOTS);
}
return true;
});
}
private BlockPlaceHandler onPlace() {
return new BlockPlaceHandler(false) {
@Override
public void onPlayerPlace(BlockPlaceEvent e) {
Block b = e.getBlock();
BlockStorage.addBlockInfo(b, "owner", e.getPlayer().getUniqueId().toString());
BlockStorage.addBlockInfo(b, "index", "0");
BlockStorage.addBlockInfo(b, FREQUENCY, "0");
BlockStorage.addBlockInfo(b, "filter-type", "whitelist");
BlockStorage.addBlockInfo(b, "filter-lore", String.valueOf(true));
BlockStorage.addBlockInfo(b, "filter-durability", String.valueOf(false));
BlockStorage.addBlockInfo(b, "round-robin", String.valueOf(false));
}
};
}
@Override
protected void createBorder(BlockMenuPreset preset) {
for (int i : BORDER) {
preset.addItem(i, new CustomItem(Material.CYAN_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler());
}
protected int[] getBorder() {
return BORDER;
}
preset.addItem(2, new CustomItem(Material.PAPER, "&3Items", "", "&bPut in all Items you want to", "&bblacklist/whitelist"), ChestMenuUtils.getEmptyClickHandler());
@Override
protected void onPlace(BlockPlaceEvent e) {
super.onPlace(e);
BlockStorage.addBlockInfo(e.getBlock(), "round-robin", String.valueOf(false));
}
@Override
protected void updateBlockMenu(BlockMenu menu, Block b) {
if (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), "filter-type") == null || BlockStorage.getLocationInfo(b.getLocation(), "filter-type").equals("whitelist")) {
menu.replaceExistingItem(15, new CustomItem(Material.WHITE_WOOL, "&7Type: &rWhitelist", "", "&e> Click to change it to Blacklist"));
menu.addMenuClickHandler(15, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, "filter-type", "blacklist");
updateBlockMenu(menu, b);
return false;
});
}
else {
menu.replaceExistingItem(15, new CustomItem(Material.BLACK_WOOL, "&7Type: &8Blacklist", "", "&e> Click to change it to Whitelist"));
menu.addMenuClickHandler(15, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, "filter-type", "whitelist");
updateBlockMenu(menu, b);
return false;
});
}
super.updateBlockMenu(menu, b);
if (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), "filter-durability") == null || BlockStorage.getLocationInfo(b.getLocation(), "filter-durability").equals(String.valueOf(false))) {
menu.replaceExistingItem(16, new CustomItem(Material.STONE_SWORD, "&7Include Sub-IDs/Durability: &4\u2718", "", "&e> Click to toggle whether the Durability has to match"));
menu.addMenuClickHandler(16, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, "filter-durability", String.valueOf(true));
updateBlockMenu(menu, b);
return false;
});
}
else {
ItemStack is = new ItemStack(Material.GOLDEN_SWORD);
Damageable dmg = (Damageable) is.getItemMeta();
dmg.setDamage(20);
is.setItemMeta((ItemMeta) dmg);
menu.replaceExistingItem(16, new CustomItem(is, "&7Include Sub-IDs/Durability: &2\u2714", "", "&e> Click to toggle whether the Durability has to match"));
menu.addMenuClickHandler(16, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, "filter-durability", String.valueOf(false));
updateBlockMenu(menu, b);
return false;
});
}
if (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), "round-robin") == null || BlockStorage.getLocationInfo(b.getLocation(), "round-robin").equals(String.valueOf(false))) {
menu.replaceExistingItem(24, new CustomItem(SlimefunUtils.getCustomHead("d78f2b7e5e75639ea7fb796c35d364c4df28b4243e66b76277aadcd6261337"), "&7Round-Robin Mode: &4\u2718", "", "&e> Click to enable Round Robin Mode", "&e(Items will be equally distributed on the Channel)"));
String roundRobinMode = BlockStorage.getLocationInfo(b.getLocation(), "round-robin");
if (!BlockStorage.hasBlockInfo(b) || roundRobinMode == null || roundRobinMode.equals(String.valueOf(false))) {
menu.replaceExistingItem(24, new CustomItem(SlimefunUtils.getCustomHead(HeadTexture.ENERGY_REGULATOR.getTexture()), "&7Round-Robin Mode: &4\u2718", "", "&e> Click to enable Round Robin Mode", "&e(Items will be equally distributed on the Channel)"));
menu.addMenuClickHandler(24, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, "round-robin", String.valueOf(true));
updateBlockMenu(menu, b);
@ -116,69 +46,13 @@ public class CargoInputNode extends AbstractCargoNode {
});
}
else {
menu.replaceExistingItem(24, new CustomItem(SlimefunUtils.getCustomHead("d78f2b7e5e75639ea7fb796c35d364c4df28b4243e66b76277aadcd6261337"), "&7Round-Robin Mode: &2\u2714", "", "&e> Click to disable Round Robin Mode", "&e(Items will be equally distributed on the Channel)"));
menu.replaceExistingItem(24, new CustomItem(SlimefunUtils.getCustomHead(HeadTexture.ENERGY_REGULATOR.getTexture()), "&7Round-Robin Mode: &2\u2714", "", "&e> Click to disable Round Robin Mode", "&e(Items will be equally distributed on the Channel)"));
menu.addMenuClickHandler(24, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, "round-robin", String.valueOf(false));
updateBlockMenu(menu, b);
return false;
});
}
if (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), "filter-lore") == null || BlockStorage.getLocationInfo(b.getLocation(), "filter-lore").equals(String.valueOf(true))) {
menu.replaceExistingItem(25, new CustomItem(Material.MAP, "&7Include Lore: &2\u2714", "", "&e> Click to toggle whether the Lore has to match"));
menu.addMenuClickHandler(25, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, "filter-lore", String.valueOf(false));
updateBlockMenu(menu, b);
return false;
});
}
else {
menu.replaceExistingItem(25, new CustomItem(Material.MAP, "&7Include Lore: &4\u2718", "", "&e> Click to toggle whether the Lore has to match"));
menu.addMenuClickHandler(25, (p, slot, item, action) -> {
BlockStorage.addBlockInfo(b, "filter-lore", String.valueOf(true));
updateBlockMenu(menu, b);
return false;
});
}
menu.replaceExistingItem(41, new CustomItem(SlimefunUtils.getCustomHead("f2599bd986659b8ce2c4988525c94e19ddd39fad08a38284a197f1b70675acc"), "&bChannel", "", "&e> Click to decrease the Channel ID by 1"));
menu.addMenuClickHandler(41, (p, slot, item, action) -> {
int channel = Integer.parseInt(BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY)) - 1;
if (channel < 0) {
if (SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled()) channel = 16;
else channel = 15;
}
BlockStorage.addBlockInfo(b, FREQUENCY, String.valueOf(channel));
updateBlockMenu(menu, b);
return false;
});
int channel = ((!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY) == null) ? 0 : (Integer.parseInt(BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY))));
if (channel == 16) {
menu.replaceExistingItem(42, new CustomItem(SlimefunUtils.getCustomHead("7a44ff3a5f49c69cab676bad8d98a063fa78cfa61916fdef3e267557fec18283"), "&bChannel ID: &3" + (channel + 1)));
menu.addMenuClickHandler(42, ChestMenuUtils.getEmptyClickHandler());
}
else {
menu.replaceExistingItem(42, new CustomItem(new ItemStack(MaterialCollections.getAllWoolColors().get(channel)), "&bChannel ID: &3" + (channel + 1)));
menu.addMenuClickHandler(42, ChestMenuUtils.getEmptyClickHandler());
}
menu.replaceExistingItem(43, new CustomItem(SlimefunUtils.getCustomHead("c2f910c47da042e4aa28af6cc81cf48ac6caf37dab35f88db993accb9dfe516"), "&bChannel", "", "&e> Click to increase the Channel ID by 1"));
menu.addMenuClickHandler(43, (p, slot, item, action) -> {
int channeln = Integer.parseInt(BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY)) + 1;
if (SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled()) {
if (channeln > 16) channeln = 0;
}
else {
if (channeln > 15) channeln = 0;
}
BlockStorage.addBlockInfo(b, FREQUENCY, String.valueOf(channeln));
updateBlockMenu(menu, b);
return false;
});
}
}

View File

@ -6,14 +6,9 @@ import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections;
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
@ -24,20 +19,11 @@ public class CargoOutputNode extends AbstractCargoNode {
public CargoOutputNode(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
super(category, item, recipeType, recipe, recipeOutput);
addItemHandler(onPlace());
}
private BlockPlaceHandler onPlace() {
return new BlockPlaceHandler(false) {
@Override
public void onPlayerPlace(BlockPlaceEvent e) {
Block b = e.getBlock();
BlockStorage.addBlockInfo(b, "owner", e.getPlayer().getUniqueId().toString());
BlockStorage.addBlockInfo(b, FREQUENCY, "0");
}
};
@Override
protected void onPlace(BlockPlaceEvent e) {
// We only require the default values
}
@Override
@ -49,46 +35,7 @@ public class CargoOutputNode extends AbstractCargoNode {
@Override
protected void updateBlockMenu(BlockMenu menu, Block b) {
menu.replaceExistingItem(12, new CustomItem(SlimefunUtils.getCustomHead("f2599bd986659b8ce2c4988525c94e19ddd39fad08a38284a197f1b70675acc"), "&bChannel", "", "&e> Click to decrease the Channel ID by 1"));
menu.addMenuClickHandler(12, (p, slot, item, action) -> {
int channel = Integer.parseInt(BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY)) - 1;
if (channel < 0) {
if (SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled()) channel = 16;
else channel = 15;
}
BlockStorage.addBlockInfo(b, FREQUENCY, String.valueOf(channel));
updateBlockMenu(menu, b);
return false;
});
int channel = ((!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY) == null) ? 0 : (Integer.parseInt(BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY))));
if (channel == 16) {
menu.replaceExistingItem(13, new CustomItem(SlimefunUtils.getCustomHead("7a44ff3a5f49c69cab676bad8d98a063fa78cfa61916fdef3e267557fec18283"), "&bChannel ID: &3" + (channel + 1)));
menu.addMenuClickHandler(13, ChestMenuUtils.getEmptyClickHandler());
}
else {
menu.replaceExistingItem(13, new CustomItem(MaterialCollections.getAllWoolColors().get(channel), "&bChannel ID: &3" + (channel + 1)));
menu.addMenuClickHandler(13, ChestMenuUtils.getEmptyClickHandler());
}
menu.replaceExistingItem(14, new CustomItem(SlimefunUtils.getCustomHead("c2f910c47da042e4aa28af6cc81cf48ac6caf37dab35f88db993accb9dfe516"), "&bChannel", "", "&e> Click to increase the Channel ID by 1"));
menu.addMenuClickHandler(14, (p, slot, item, action) -> {
int channeln = Integer.parseInt(BlockStorage.getLocationInfo(b.getLocation(), FREQUENCY)) + 1;
if (SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled()) {
if (channeln > 16) channeln = 0;
}
else {
if (channeln > 15) channeln = 0;
}
BlockStorage.addBlockInfo(b, FREQUENCY, String.valueOf(channeln));
updateBlockMenu(menu, b);
return false;
});
addChannelSelector(b, menu, 12, 13, 14);
}
}

View File

@ -11,6 +11,7 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.core.attributes.Rechargeable;
import io.github.thebusybiscuit.slimefun4.core.handlers.EntityInteractHandler;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
@ -42,6 +43,21 @@ public class MultiTool extends SlimefunItem implements Rechargeable {
return capacity;
}
private int nextIndex(int i) {
int index = i;
do {
index++;
if (index >= modes.size()) {
index = 0;
}
}
while (index != i && !modes.get(index).isEnabled());
return index;
}
protected ItemUseHandler getItemUseHandler() {
return e -> {
Player p = e.getPlayer();
@ -64,29 +80,33 @@ public class MultiTool extends SlimefunItem implements Rechargeable {
SlimefunItem selectedItem = modes.get(index).getItem();
String itemName = selectedItem != null ? selectedItem.getItemName() : "Unknown";
SlimefunPlugin.getLocalization().sendMessage(p, "messages.mode-change", true, msg -> msg.replace("%device%", "Multi Tool").replace("%mode%", ChatColor.stripColor(itemName)));
SlimefunPlugin.getLocalization().sendMessage(p, "messages.multi-tool.mode-change", true, msg -> msg.replace("%device%", "Multi Tool").replace("%mode%", ChatColor.stripColor(itemName)));
selectedMode.put(p.getUniqueId(), index);
}
};
}
private int nextIndex(int i) {
int index = i;
do {
index++;
if (index >= modes.size()) {
index = 0;
}
}
while (index != i && !modes.get(index).isEnabled());
return index;
private ToolUseHandler getToolUseHandler() {
return (e, tool, fortune, drops) -> {
SlimefunPlugin.getLocalization().sendMessage(e.getPlayer(), "messages.multi-tool.not-shears");
e.setCancelled(true);
};
}
private ToolUseHandler getToolUseHandler() {
return (e, tool, fortune, drops) -> e.setCancelled(true);
private EntityInteractHandler getEntityInteractionHandler() {
return (e, item, offhand) -> {
// Fixes #2217 - Prevent them from being used to shear entities
switch (e.getRightClicked().getType()) {
case MUSHROOM_COW:
case SHEEP:
case SNOWMAN:
SlimefunPlugin.getLocalization().sendMessage(e.getPlayer(), "messages.multi-tool.not-shears");
e.setCancelled(true);
break;
default:
break;
}
};
}
@Override
@ -95,6 +115,7 @@ public class MultiTool extends SlimefunItem implements Rechargeable {
addItemHandler(getItemUseHandler());
addItemHandler(getToolUseHandler());
addItemHandler(getEntityInteractionHandler());
}
}

View File

@ -11,23 +11,23 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public abstract class LavaGenerator extends AGenerator {
public LavaGenerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
}
public LavaGenerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
}
@Override
protected void registerDefaultFuelTypes() {
registerFuel(new MachineFuel(40, new ItemStack(Material.LAVA_BUCKET)));
}
registerFuel(new MachineFuel(40, new ItemStack(Material.LAVA_BUCKET)));
}
@Override
public ItemStack getProgressBar() {
return new ItemStack(Material.FLINT_AND_STEEL);
}
@Override
public ItemStack getProgressBar() {
return new ItemStack(Material.FLINT_AND_STEEL);
}
@Override
public String getInventoryTitle() {
return "&4Lava Generator";
}
@Override
public String getInventoryTitle() {
return "&4Lava Generator";
}
}

View File

@ -5,22 +5,14 @@ import java.util.List;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.block.Block;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
import me.mrCookieSlime.Slimefun.api.energy.ChargableBlock;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
/**
* The {@link AutoDrier} is an implementation of {@link AContainer} that features recipes
@ -32,11 +24,15 @@ import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
*/
public class AutoDrier extends AContainer implements RecipeDisplayItem {
private final List<ItemStack> recipeList = new ArrayList<>();
private List<ItemStack> recipeList;
public AutoDrier(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
}
@Override
protected void registerDefaultRecipes() {
recipeList = new ArrayList<>();
recipeList.add(new ItemStack(Material.ROTTEN_FLESH));
recipeList.add(new ItemStack(Material.LEATHER));
@ -49,11 +45,11 @@ public class AutoDrier extends AContainer implements RecipeDisplayItem {
recipeList.add(new ItemStack(Material.POTION));
recipeList.add(new ItemStack(Material.GLASS_BOTTLE));
recipeList.add(new ItemStack(Material.OAK_SAPLING));
recipeList.add(new ItemStack(Material.STICK, 2));
recipeList.add(new ItemStack(Material.SPLASH_POTION));
recipeList.add(new ItemStack(Material.GLASS_BOTTLE));
recipeList.add(new ItemStack(Material.OAK_LEAVES));
recipeList.add(new ItemStack(Material.STICK));
recipeList.add(new ItemStack(Material.LINGERING_POTION));
recipeList.add(new ItemStack(Material.GLASS_BOTTLE));
recipeList.add(new ItemStack(Material.WATER_BUCKET));
recipeList.add(new ItemStack(Material.BUCKET));
@ -78,6 +74,21 @@ public class AutoDrier extends AContainer implements RecipeDisplayItem {
recipeList.add(new ItemStack(Material.COOKED_SALMON));
recipeList.add(SlimefunItems.FISH_JERKY);
for (Material sapling : Tag.SAPLINGS.getValues()) {
recipeList.add(new ItemStack(sapling));
recipeList.add(new ItemStack(Material.STICK, 2));
}
for (Material leaves : Tag.LEAVES.getValues()) {
recipeList.add(new ItemStack(leaves));
recipeList.add(new ItemStack(Material.STICK));
}
// Now convert them to machine recipes
for (int i = 0; i < recipeList.size(); i += 2) {
registerRecipe(6, recipeList.get(i), recipeList.get(i + 1));
}
}
@Override
@ -95,78 +106,6 @@ public class AutoDrier extends AContainer implements RecipeDisplayItem {
return recipeList;
}
@Override
protected void tick(Block b) {
BlockMenu menu = BlockStorage.getInventory(b);
if (isProcessing(b)) {
int timeleft = progress.get(b);
if (timeleft > 0) {
ChestMenuUtils.updateProgressbar(menu, 22, timeleft, processing.get(b).getTicks(), getProgressBar());
if (ChargableBlock.getCharge(b) < getEnergyConsumption()) {
return;
}
ChargableBlock.addCharge(b, -getEnergyConsumption());
progress.put(b, timeleft - 1);
}
else {
menu.replaceExistingItem(22, new CustomItem(new ItemStack(Material.BLACK_STAINED_GLASS_PANE), " "));
menu.pushItem(processing.get(b).getOutput()[0], getOutputSlots());
progress.remove(b);
processing.remove(b);
}
}
else {
MachineRecipe r = null;
int inputSlot = -1;
for (int slot : getInputSlots()) {
ItemStack item = menu.getItemInSlot(slot);
if (item != null) {
ItemStack output = getOutput(item);
if (output != null) {
r = new MachineRecipe(6, new ItemStack[] { item }, new ItemStack[] { output.clone() });
inputSlot = slot;
break;
}
}
}
if (r != null) {
if (inputSlot == -1) return;
if (!menu.fits(r.getOutput()[0], getOutputSlots())) return;
menu.consumeItem(inputSlot);
processing.put(b, r);
progress.put(b, r.getTicks());
}
}
}
private ItemStack getOutput(ItemStack item) {
for (int i = 0; i < recipeList.size(); i += 2) {
if (SlimefunUtils.isItemSimilar(item, recipeList.get(i), true)) {
return recipeList.get(i + 1);
}
}
if (Tag.SAPLINGS.isTagged(item.getType())) {
return new ItemStack(Material.STICK, 2);
}
else if (Tag.LEAVES.isTagged(item.getType())) {
return new ItemStack(Material.STICK, 1);
}
else if (item.getType() == Material.SPLASH_POTION || item.getType() == Material.LINGERING_POTION) {
return new ItemStack(Material.GLASS_BOTTLE);
}
return null;
}
@Override
public int getEnergyConsumption() {
return 5;

View File

@ -48,7 +48,9 @@ public abstract class ElectricPress extends AContainer implements RecipeDisplayI
addRecipe(4, new ItemStack(Material.IRON_NUGGET, 9), new ItemStack(Material.IRON_INGOT));
addRecipe(4, new ItemStack(Material.GOLD_NUGGET, 9), new ItemStack(Material.GOLD_INGOT));
addRecipe(4, new ItemStack(Material.COAL, 9), new ItemStack(Material.COAL_BLOCK));
addRecipe(4, new ItemStack(Material.SAND, 4), new ItemStack(Material.SANDSTONE));
addRecipe(4, new ItemStack(Material.RED_SAND, 4), new ItemStack(Material.RED_SANDSTONE));
addRecipe(5, new ItemStack(Material.IRON_INGOT, 9), new ItemStack(Material.IRON_BLOCK));
addRecipe(5, new ItemStack(Material.GOLD_INGOT, 9), new ItemStack(Material.GOLD_BLOCK));

View File

@ -1,12 +1,25 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.food;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
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 org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemConsumptionHandler;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.CoolerListener;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.Slimefun;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/**
@ -19,10 +32,69 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
* @see CoolerListener
*
*/
public class Juice extends SlimefunItem {
public class Juice extends SimpleSlimefunItem<ItemConsumptionHandler> {
private final List<PotionEffect> effects;
public Juice(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
this(category, item, recipeType, recipe, null);
}
public Juice(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
super(category, item, recipeType, recipe, recipeOutput);
ItemMeta meta = item.getItemMeta();
if (meta instanceof PotionMeta) {
effects = ((PotionMeta) meta).getCustomEffects();
}
else {
effects = new ArrayList<>();
}
}
@Override
public ItemConsumptionHandler getItemHandler() {
return (e, p, item) -> {
// Fix for Saturation on potions is no longer working,
// Minecraft has been broken when it comes to Saturation potions for a long time
for (PotionEffect effect : effects) {
if (effect.getType().equals(PotionEffectType.SATURATION)) {
p.addPotionEffect(effect);
break;
}
}
removeGlassBottle(p, item);
};
}
/**
* Determines from which hand the juice is being drunk, and its amount
*
* @param p
* The {@link Player} that triggered this
* @param item
* The {@link ItemStack} in question
*/
private void removeGlassBottle(Player p, ItemStack item) {
if (SlimefunUtils.isItemSimilar(item, p.getInventory().getItemInMainHand(), true)) {
if (p.getInventory().getItemInMainHand().getAmount() == 1) {
Slimefun.runSync(() -> p.getEquipment().getItemInMainHand().setAmount(0));
}
else {
Slimefun.runSync(() -> p.getInventory().removeItem(new ItemStack(Material.GLASS_BOTTLE, 1)));
}
}
else if (SlimefunUtils.isItemSimilar(item, p.getInventory().getItemInOffHand(), true)) {
if (p.getInventory().getItemInOffHand().getAmount() == 1) {
Slimefun.runSync(() -> p.getEquipment().getItemInOffHand().setAmount(0));
}
else {
Slimefun.runSync(() -> p.getInventory().removeItem(new ItemStack(Material.GLASS_BOTTLE, 1)));
}
}
}
}

View File

@ -25,14 +25,13 @@ import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.interfaces.InventoryBlock;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
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;
public abstract class GEOMiner extends AContainer implements InventoryBlock, RecipeDisplayItem {
public abstract class GEOMiner extends AContainer implements RecipeDisplayItem {
private static final int[] BORDER = { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 26, 27, 35, 36, 44, 45, 53 };
private static final int[] OUTPUT_BORDER = { 19, 20, 21, 22, 23, 24, 25, 28, 34, 37, 43, 46, 47, 48, 49, 50, 51, 52 };

View File

@ -1,14 +1,15 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.magical;
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
import org.bukkit.GameMode;
import org.bukkit.Sound;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.entity.Villager;
import org.bukkit.entity.ZombieVillager;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.core.handlers.EntityInteractHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
@ -38,8 +39,11 @@ public class MagicalZombiePills extends SimpleSlimefunItem<EntityInteractHandler
@Override
public EntityInteractHandler getItemHandler() {
return (p, entity, item, offhand) -> {
return (e, item, offhand) -> {
Entity entity = e.getRightClicked();
if (entity.getType() == EntityType.ZOMBIE_VILLAGER) {
Player p = e.getPlayer();
if (p.getGameMode() != GameMode.CREATIVE) {
ItemUtils.consumeItem(item, false);

View File

@ -11,6 +11,7 @@ import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockDropItemEvent;
import org.bukkit.event.enchantment.EnchantItemEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.entity.EntityEvent;
@ -127,7 +128,7 @@ public class Talisman extends SlimefunItem {
}
private static boolean hasMessage(Talisman talisman) {
return !("").equalsIgnoreCase(talisman.getMessageSuffix());
return talisman.getMessageSuffix() != null;
}
public static boolean checkFor(Event e, SlimefunItemStack stack) {
@ -224,6 +225,9 @@ public class Talisman extends SlimefunItem {
else if (e instanceof BlockBreakEvent) {
return ((BlockBreakEvent) e).getPlayer();
}
else if (e instanceof BlockDropItemEvent) {
return ((BlockDropItemEvent) e).getPlayer();
}
else if (e instanceof PlayerEvent) {
return ((PlayerEvent) e).getPlayer();
}

View File

@ -16,10 +16,21 @@ import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/**
* A {@link Bandage} or Rag is a medical supply which heals the {@link Player} and extinguishes
* fire.
*
* @author TheBusyBiscuit
*
*/
public class Bandage extends SimpleSlimefunItem<ItemUseHandler> {
public Bandage(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
private final int healingLevel;
public Bandage(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput, int healingLevel) {
super(category, item, recipeType, recipe, recipeOutput);
this.healingLevel = healingLevel;
}
@Override
@ -37,7 +48,7 @@ public class Bandage extends SimpleSlimefunItem<ItemUseHandler> {
}
p.getWorld().playEffect(p.getLocation(), Effect.STEP_SOUND, Material.WHITE_WOOL);
p.addPotionEffect(new PotionEffect(PotionEffectType.HEAL, 1, 1));
p.addPotionEffect(new PotionEffect(PotionEffectType.HEAL, 1, healingLevel));
p.setFireTicks(0);
e.cancel();

View File

@ -1,47 +0,0 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.medical;
import org.bukkit.Effect;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.attribute.Attribute;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
public class Rag extends SimpleSlimefunItem<ItemUseHandler> {
public Rag(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
}
@Override
public ItemUseHandler getItemHandler() {
return e -> {
Player p = e.getPlayer();
// Player is neither burning nor injured
if (p.getFireTicks() <= 0 && p.getHealth() >= p.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()) {
return;
}
if (p.getGameMode() != GameMode.CREATIVE) {
ItemUtils.consumeItem(e.getItem(), false);
}
p.getWorld().playEffect(p.getLocation(), Effect.STEP_SOUND, Material.WHITE_WOOL);
p.addPotionEffect(new PotionEffect(PotionEffectType.HEAL, 1, 0));
p.setFireTicks(0);
e.cancel();
};
}
}

View File

@ -0,0 +1,29 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.misc;
import org.bukkit.entity.Villager;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.VillagerTradingListener;
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;
/**
* The {@link SyntheticEmerald} is an almost normal emerald.
* It can even be used to trade with {@link Villager Villagers}.
*
* @author TheBusyBiscuit
*
* @see VillagerTradingListener
*
*/
public class SyntheticEmerald extends SlimefunItem {
public SyntheticEmerald(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
setUseableInWorkbench(true);
}
}

View File

@ -131,10 +131,8 @@ public class IndustrialMiner extends MultiBlockMachine {
return new ItemStack(Material.REDSTONE, 4 + random.nextInt(2));
case LAPIS_ORE:
return new ItemStack(Material.LAPIS_LAZULI, 4 + random.nextInt(4));
case ANCIENT_DEBRIS:
return new ItemStack(Material.ANCIENT_DEBRIS);
default:
// This includes Iron and Gold ore
// This includes Iron and Gold ore (and Ancient Debris)
return new ItemStack(ore);
}
}
@ -212,7 +210,19 @@ public class IndustrialMiner extends MultiBlockMachine {
* @return Whether this {@link IndustrialMiner} is capable of mining this {@link Material}
*/
public boolean canMine(Material type) {
return type.name().endsWith("_ORE") || (type == Material.ANCIENT_DEBRIS && canMineAncientDebris.getValue());
if (type.name().endsWith("_ORE")) {
return true;
}
else if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
if (type == Material.GILDED_BLACKSTONE) {
return true;
}
else if (type == Material.ANCIENT_DEBRIS) {
return canMineAncientDebris.getValue();
}
}
return false;
}
}

View File

@ -27,6 +27,7 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.util.Vector;
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
@ -53,6 +54,8 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
*/
public class AncientAltarListener implements Listener {
public static final String ITEM_PREFIX = ChatColors.color("&dALTAR &3Probe - &e");
private AncientAltar altar;
private final Set<AltarRecipe> altarRecipes = new HashSet<>();
@ -303,7 +306,7 @@ public class AncientAltarListener implements Listener {
}
String nametag = ItemUtils.getItemName(stack);
Item entity = b.getWorld().dropItem(b.getLocation().add(0.5, 1.2, 0.5), new CustomItem(stack, "&5&dALTAR &3Probe - &e" + System.nanoTime()));
Item entity = b.getWorld().dropItem(b.getLocation().add(0.5, 1.2, 0.5), new CustomItem(stack, ITEM_PREFIX + System.nanoTime()));
entity.setVelocity(new Vector(0, 0.1, 0));
SlimefunUtils.markAsNoPickup(entity, "altar_item");
entity.setCustomNameVisible(true);

View File

@ -32,6 +32,17 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/**
* The {@link BlockListener} is responsible for listening to the {@link BlockPlaceEvent}
* and {@link BlockBreakEvent}.
*
* @author TheBusyBiscuit
*
* @see BlockPlaceHandler
* @see BlockBreakHandler
* @see ToolUseHandler
*
*/
public class BlockListener implements Listener {
// Materials that require a Block under it, e.g. Pressure Plates
@ -49,7 +60,7 @@ public class BlockListener implements Listener {
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlockRegister(BlockPlaceEvent e) {
public void onBlockPlace(BlockPlaceEvent e) {
if (BlockStorage.hasBlockInfo(e.getBlock())) {
e.setCancelled(true);
return;
@ -81,7 +92,7 @@ public class BlockListener implements Listener {
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlockUnregister(BlockBreakEvent e) {
public void onBlockBreak(BlockBreakEvent e) {
checkForSensitiveBlockAbove(e.getPlayer(), e.getBlock());
ItemStack item = e.getPlayer().getInventory().getItemInMainHand();
@ -89,50 +100,58 @@ public class BlockListener implements Listener {
List<ItemStack> drops = new ArrayList<>();
if (item.getType() != Material.AIR) {
SlimefunItem tool = SlimefunItem.getByItem(item);
if (tool != null) {
if (Slimefun.hasUnlocked(e.getPlayer(), tool, true)) {
tool.callItemHandler(ToolUseHandler.class, handler -> handler.onToolUse(e, item, fortune, drops));
}
else {
e.setCancelled(true);
}
}
callToolHandler(e, item, fortune, drops);
}
if (!e.isCancelled()) {
SlimefunItem sfItem = BlockStorage.check(e.getBlock());
if (sfItem == null && SlimefunPlugin.getBlockDataService().isTileEntity(e.getBlock().getType())) {
Optional<String> blockData = SlimefunPlugin.getBlockDataService().getBlockData(e.getBlock());
if (blockData.isPresent()) {
sfItem = SlimefunItem.getByID(blockData.get());
}
}
if (sfItem != null && !sfItem.useVanillaBlockBreaking()) {
SlimefunBlockHandler blockHandler = SlimefunPlugin.getRegistry().getBlockHandlers().get(sfItem.getID());
if (blockHandler != null) {
if (!blockHandler.onBreak(e.getPlayer(), e.getBlock(), sfItem, UnregisterReason.PLAYER_BREAK)) {
e.setCancelled(true);
return;
}
}
else {
sfItem.callItemHandler(BlockBreakHandler.class, handler -> handler.onBlockBreak(e, item, fortune, drops));
}
drops.addAll(sfItem.getDrops());
BlockStorage.clearBlockInfo(e.getBlock());
}
callBlockHandler(e, item, fortune, drops);
}
dropItems(e, drops);
}
private void callToolHandler(BlockBreakEvent e, ItemStack item, int fortune, List<ItemStack> drops) {
SlimefunItem tool = SlimefunItem.getByItem(item);
if (tool != null) {
if (Slimefun.hasUnlocked(e.getPlayer(), tool, true)) {
tool.callItemHandler(ToolUseHandler.class, handler -> handler.onToolUse(e, item, fortune, drops));
}
else {
e.setCancelled(true);
}
}
}
private void callBlockHandler(BlockBreakEvent e, ItemStack item, int fortune, List<ItemStack> drops) {
SlimefunItem sfItem = BlockStorage.check(e.getBlock());
if (sfItem == null && SlimefunPlugin.getBlockDataService().isTileEntity(e.getBlock().getType())) {
Optional<String> blockData = SlimefunPlugin.getBlockDataService().getBlockData(e.getBlock());
if (blockData.isPresent()) {
sfItem = SlimefunItem.getByID(blockData.get());
}
}
if (sfItem != null && !sfItem.useVanillaBlockBreaking()) {
SlimefunBlockHandler blockHandler = SlimefunPlugin.getRegistry().getBlockHandlers().get(sfItem.getID());
if (blockHandler != null) {
if (!blockHandler.onBreak(e.getPlayer(), e.getBlock(), sfItem, UnregisterReason.PLAYER_BREAK)) {
e.setCancelled(true);
return;
}
}
else {
sfItem.callItemHandler(BlockBreakHandler.class, handler -> handler.onBlockBreak(e, item, fortune, drops));
}
drops.addAll(sfItem.getDrops());
BlockStorage.clearBlockInfo(e.getBlock());
}
}
private void dropItems(BlockBreakEvent e, List<ItemStack> drops) {
if (!drops.isEmpty()) {
e.getBlock().setType(Material.AIR);

View File

@ -4,6 +4,7 @@ import java.util.logging.Level;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Skull;
import org.bukkit.block.data.Directional;
import org.bukkit.block.data.Rotatable;
@ -60,29 +61,10 @@ public class DebugFishListener implements Listener {
if (p.hasPermission("slimefun.debugging")) {
if (e.getAction() == Action.LEFT_CLICK_BLOCK) {
if (p.isSneaking()) {
if (BlockStorage.hasBlockInfo(e.getClickedBlock())) {
BlockStorage.clearBlockInfo(e.getClickedBlock());
}
}
else {
e.setCancelled(false);
}
onLeftClick(p, e.getClickedBlock(), e);
}
else if (e.getAction() == Action.RIGHT_CLICK_BLOCK) {
if (p.isSneaking()) {
Block b = e.getClickedBlock().getRelative(e.getBlockFace());
b.setType(Material.PLAYER_HEAD);
SkullBlock.setFromHash(b, HeadTexture.MISSING_TEXTURE.getTexture());
}
else if (BlockStorage.hasBlockInfo(e.getClickedBlock())) {
try {
sendInfo(p, e.getClickedBlock());
}
catch (Exception x) {
Slimefun.getLogger().log(Level.SEVERE, "An Exception occured while using a Debug-Fish", x);
}
}
onRightClick(p, e.getClickedBlock(), e.getBlockFace());
}
}
else {
@ -91,6 +73,33 @@ public class DebugFishListener implements Listener {
}
}
private void onLeftClick(Player p, Block b, PlayerInteractEvent e) {
if (p.isSneaking()) {
if (BlockStorage.hasBlockInfo(b)) {
BlockStorage.clearBlockInfo(b);
}
}
else {
e.setCancelled(false);
}
}
private void onRightClick(Player p, Block b, BlockFace face) {
if (p.isSneaking()) {
Block block = b.getRelative(face);
block.setType(Material.PLAYER_HEAD);
SkullBlock.setFromHash(block, HeadTexture.MISSING_TEXTURE.getTexture());
}
else if (BlockStorage.hasBlockInfo(b)) {
try {
sendInfo(p, b);
}
catch (Exception x) {
Slimefun.getLogger().log(Level.SEVERE, "An Exception occured while using a Debug-Fish", x);
}
}
}
private void sendInfo(Player p, Block b) {
SlimefunItem item = BlockStorage.check(b);

View File

@ -4,7 +4,7 @@ import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
@ -21,14 +21,14 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
* @see EntityInteractHandler
*
*/
public class PlayerInteractEntityListener implements Listener {
public class EntityInteractionListener implements Listener {
public PlayerInteractEntityListener(SlimefunPlugin plugin) {
public EntityInteractionListener(SlimefunPlugin plugin) {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler
public void onInteractEntity(PlayerInteractAtEntityEvent e) {
public void onInteractEntity(PlayerInteractEntityEvent e) {
if (!e.getRightClicked().isValid()) {
return;
}
@ -45,7 +45,7 @@ public class PlayerInteractEntityListener implements Listener {
SlimefunItem sfItem = SlimefunItem.getByItem(itemStack);
if (sfItem != null && Slimefun.hasUnlocked(e.getPlayer(), sfItem, true)) {
sfItem.callItemHandler(EntityInteractHandler.class, handler -> handler.onInteract(e.getPlayer(), e.getRightClicked(), itemStack, e.getHand() == EquipmentSlot.OFF_HAND));
sfItem.callItemHandler(EntityInteractHandler.class, handler -> handler.onInteract(e, itemStack, e.getHand() == EquipmentSlot.OFF_HAND));
}
}
}

View File

@ -4,8 +4,8 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.event.inventory.InventoryPickupItemEvent;
import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
@ -16,8 +16,6 @@ import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
*/
public class ItemPickupListener implements Listener {
private static final String ITEM_PREFIX = ChatColors.color("&5&dALTAR &3Probe - &e");
public ItemPickupListener(SlimefunPlugin plugin) {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@ -27,9 +25,13 @@ public class ItemPickupListener implements Listener {
if (SlimefunUtils.hasNoPickupFlag(e.getItem())) {
e.setCancelled(true);
}
else if (e.getItem().getItemStack().hasItemMeta() && e.getItem().getItemStack().getItemMeta().hasDisplayName() && e.getItem().getItemStack().getItemMeta().getDisplayName().startsWith(ITEM_PREFIX)) {
e.setCancelled(true);
e.getItem().remove();
else if (e.getItem().getItemStack().hasItemMeta()) {
ItemMeta meta = e.getItem().getItemStack().getItemMeta();
if (meta.hasDisplayName() && meta.getDisplayName().startsWith(AncientAltarListener.ITEM_PREFIX)) {
e.setCancelled(true);
e.getItem().remove();
}
}
}
@ -38,9 +40,13 @@ public class ItemPickupListener implements Listener {
if (SlimefunUtils.hasNoPickupFlag(e.getItem())) {
e.setCancelled(true);
}
else if (e.getItem().getItemStack().hasItemMeta() && e.getItem().getItemStack().getItemMeta().hasDisplayName() && e.getItem().getItemStack().getItemMeta().getDisplayName().startsWith(ITEM_PREFIX)) {
e.setCancelled(true);
e.getItem().remove();
else if (e.getItem().getItemStack().hasItemMeta()) {
ItemMeta meta = e.getItem().getItemStack().getItemMeta();
if (meta.hasDisplayName() && meta.getDisplayName().startsWith(AncientAltarListener.ITEM_PREFIX)) {
e.setCancelled(true);
e.getItem().remove();
}
}
}
}

View File

@ -36,7 +36,7 @@ public class PiglinListener implements Listener {
}
@EventHandler
public void onEntityPickup(EntityPickupItemEvent e) {
public void onPickup(EntityPickupItemEvent e) {
if (e.getEntityType() == EntityType.PIGLIN) {
ItemStack item = e.getItem().getItemStack();
@ -47,6 +47,33 @@ public class PiglinListener implements Listener {
}
}
@EventHandler
public void onInteract(PlayerInteractEntityEvent e) {
if (!e.getRightClicked().isValid() || e.getRightClicked().getType() != EntityType.PIGLIN) {
return;
}
Player p = e.getPlayer();
ItemStack item;
if (e.getHand() == EquipmentSlot.OFF_HAND) {
item = p.getInventory().getItemInOffHand();
}
else {
item = p.getInventory().getItemInMainHand();
}
// We only care about Gold since it's the actual "Bartering" we wanna prevent
if (item.getType() == Material.GOLD_INGOT) {
SlimefunItem sfItem = SlimefunItem.getByItem(item);
if (sfItem != null) {
SlimefunPlugin.getLocalization().sendMessage(p, "messages.piglin-barter", true);
e.setCancelled(true);
}
}
}
@EventHandler
public void onPiglinDropItem(EntityDropItemEvent e) {
if (e.getEntity() instanceof Piglin) {
@ -76,31 +103,4 @@ public class PiglinListener implements Listener {
}
}
}
@EventHandler
public void onInteractEntity(PlayerInteractEntityEvent e) {
if (!e.getRightClicked().isValid() || e.getRightClicked().getType() != EntityType.PIGLIN) {
return;
}
Player p = e.getPlayer();
ItemStack item;
if (e.getHand() == EquipmentSlot.OFF_HAND) {
item = p.getInventory().getItemInOffHand();
}
else {
item = p.getInventory().getItemInMainHand();
}
// We only care about Gold since it's the actual "Bartering" we wanna prevent
if (item.getType() == Material.GOLD_INGOT) {
SlimefunItem sfItem = SlimefunItem.getByItem(item);
if (sfItem != null) {
SlimefunPlugin.getLocalization().sendMessage(p, "messages.piglin-barter", true);
e.setCancelled(true);
}
}
}
}

View File

@ -33,8 +33,8 @@ public class SlimefunGuideListener implements Listener {
return;
}
SlimefunGuideLayout type = SlimefunPlugin.getCfg().getBoolean("guide.default-view-book") ? SlimefunGuideLayout.BOOK : SlimefunGuideLayout.CHEST;
p.getInventory().addItem(SlimefunGuide.getItem(type));
SlimefunGuideLayout type = SlimefunGuide.getDefaultLayout();
p.getInventory().addItem(SlimefunGuide.getItem(type).clone());
}
}
@ -69,7 +69,7 @@ public class SlimefunGuideListener implements Listener {
Player p = e.getPlayer();
ItemStack item = e.getItem();
if (SlimefunUtils.isItemSimilar(item, SlimefunGuide.getItem(layout), true)) {
if (SlimefunUtils.isItemSimilar(item, SlimefunGuide.getItem(layout), true, false)) {
e.cancel();
if (!SlimefunPlugin.getWorldSettingsService().isWorldEnabled(p.getWorld())) {

View File

@ -1,22 +1,23 @@
package io.github.thebusybiscuit.slimefun4.implementation.listeners;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerItemConsumeEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemConsumptionHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.food.Juice;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.Slimefun;
/**
* This {@link Listener} is responsible for handling the {@link ItemConsumptionHandler}
* for any {@link SlimefunItem}.
*
* @author TheBusyBiscuit
*
*/
public class SlimefunItemConsumeListener implements Listener {
public SlimefunItemConsumeListener(SlimefunPlugin plugin) {
@ -31,53 +32,11 @@ public class SlimefunItemConsumeListener implements Listener {
if (sfItem != null) {
if (Slimefun.hasUnlocked(p, sfItem, true)) {
if (sfItem instanceof Juice) {
// Fix for Saturation on potions is no longer working
for (PotionEffect effect : ((PotionMeta) item.getItemMeta()).getCustomEffects()) {
if (effect.getType().equals(PotionEffectType.SATURATION)) {
p.addPotionEffect(new PotionEffect(PotionEffectType.SATURATION, effect.getDuration(), effect.getAmplifier()));
break;
}
}
removeGlassBottle(p, item);
}
else {
sfItem.callItemHandler(ItemConsumptionHandler.class, handler -> handler.onConsume(e, p, item));
}
sfItem.callItemHandler(ItemConsumptionHandler.class, handler -> handler.onConsume(e, p, item));
}
else {
e.setCancelled(true);
}
}
}
/**
* Determines from which hand the juice is being drunk, and its amount
*
* @param p
* The {@link Player} that triggered this
* @param item
* The {@link ItemStack} in question
*/
private void removeGlassBottle(Player p, ItemStack item) {
if (SlimefunUtils.isItemSimilar(item, p.getInventory().getItemInMainHand(), true)) {
if (p.getInventory().getItemInMainHand().getAmount() == 1) {
Slimefun.runSync(() -> p.getEquipment().getItemInMainHand().setAmount(0));
}
else {
Slimefun.runSync(() -> p.getInventory().removeItem(new ItemStack(Material.GLASS_BOTTLE, 1)));
}
}
else if (SlimefunUtils.isItemSimilar(item, p.getInventory().getItemInOffHand(), true)) {
if (p.getInventory().getItemInOffHand().getAmount() == 1) {
Slimefun.runSync(() -> p.getEquipment().getItemInOffHand().setAmount(0));
}
else {
Slimefun.runSync(() -> p.getInventory().removeItem(new ItemStack(Material.GLASS_BOTTLE, 1)));
}
}
}
}

View File

@ -13,13 +13,14 @@ import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.AbstractArrow;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.ChestedHorse;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockDropItemEvent;
import org.bukkit.event.enchantment.EnchantItemEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
@ -35,7 +36,6 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.util.Vector;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.materials.MaterialCollections;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans.MagicianTalisman;
@ -229,32 +229,48 @@ public class TalismanListener implements Listener {
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBlockBreak(BlockBreakEvent e) {
@EventHandler(ignoreCancelled = true)
public void onBlockDropItems(BlockDropItemEvent e) {
// We only want to double ores
if (MaterialCollections.getAllOres().contains(e.getBlock().getType())) {
Material type = e.getBlockState().getType();
if (type.name().endsWith("_ORE")) {
ItemStack item = e.getPlayer().getInventory().getItemInMainHand();
if (item.getType() != Material.AIR && item.getAmount() > 0) {
Collection<ItemStack> drops = e.getBlock().getDrops(item);
int dropAmount = 1;
if (item.getType() != Material.AIR && item.getAmount() > 0 && !item.containsEnchantment(Enchantment.SILK_TOUCH)) {
Collection<Item> drops = e.getItems();
if (item.getEnchantments().containsKey(Enchantment.LOOT_BONUS_BLOCKS) && !item.getEnchantments().containsKey(Enchantment.SILK_TOUCH)) {
Random random = ThreadLocalRandom.current();
dropAmount = random.nextInt(item.getEnchantmentLevel(Enchantment.LOOT_BONUS_BLOCKS) + 2) - 1;
dropAmount = Math.max(dropAmount, 1);
dropAmount = (e.getBlock().getType() == Material.LAPIS_ORE ? 4 + random.nextInt(5) : 1) * (dropAmount + 1);
}
if (Talisman.checkFor(e, SlimefunItems.TALISMAN_MINER)) {
int dropAmount = getAmountWithFortune(type, item.getEnchantmentLevel(Enchantment.LOOT_BONUS_BLOCKS));
boolean doubledDrops = false;
if (!item.getEnchantments().containsKey(Enchantment.SILK_TOUCH) && Talisman.checkFor(e, SlimefunItems.TALISMAN_MINER)) {
for (ItemStack drop : drops) {
if (!drop.getType().isBlock()) {
int amount = Math.max(1, (dropAmount * 2) - drop.getAmount());
e.getBlock().getWorld().dropItemNaturally(e.getBlock().getLocation(), new CustomItem(drop, amount));
for (Item drop : drops) {
ItemStack droppedItem = drop.getItemStack();
if (!droppedItem.getType().isBlock()) {
int amount = Math.max(1, (dropAmount * 2) - droppedItem.getAmount());
e.getBlock().getWorld().dropItemNaturally(e.getBlock().getLocation(), new CustomItem(droppedItem, amount));
doubledDrops = true;
}
}
if (doubledDrops) {
SlimefunPlugin.getLocalization().sendMessage(e.getPlayer(), "messages.talisman.miner", true);
}
}
}
}
}
private int getAmountWithFortune(Material type, int fortuneLevel) {
if (fortuneLevel > 0) {
Random random = ThreadLocalRandom.current();
int amount = random.nextInt(fortuneLevel + 2) - 1;
amount = Math.max(amount, 1);
amount = (type == Material.LAPIS_ORE ? 4 + random.nextInt(5) : 1) * (amount + 1);
return amount;
}
else {
return 1;
}
}
}

View File

@ -6,6 +6,7 @@ import org.bukkit.event.Event.Result;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.CraftItemEvent;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.inventory.PrepareItemCraftEvent;
@ -95,10 +96,24 @@ public class VanillaMachinesListener implements Listener {
@EventHandler(ignoreCancelled = true)
public void onPreBrew(InventoryClickEvent e) {
Inventory inventory = e.getInventory();
Inventory clickedInventory = e.getClickedInventory();
Inventory topInventory = e.getView().getTopInventory();
if (inventory.getType() == InventoryType.BREWING && e.getRawSlot() < inventory.getSize() && inventory.getHolder() instanceof BrewingStand) {
e.setCancelled(isUnallowed(SlimefunItem.getByItem(e.getCursor())));
if (clickedInventory != null && topInventory.getType() == InventoryType.BREWING && topInventory.getHolder() instanceof BrewingStand) {
if (e.getAction() == InventoryAction.HOTBAR_SWAP) {
e.setCancelled(true);
return;
}
if (clickedInventory.getType() == InventoryType.BREWING) {
e.setCancelled(isUnallowed(SlimefunItem.getByItem(e.getCursor())));
} else {
e.setCancelled(isUnallowed(SlimefunItem.getByItem(e.getCurrentItem())));
}
if (e.getResult() == Result.DENY) {
SlimefunPlugin.getLocalization().sendMessage((Player) e.getWhoClicked(), "brewing_stand.not-working", true);
}
}
}

View File

@ -0,0 +1,57 @@
package io.github.thebusybiscuit.slimefun4.implementation.listeners;
import org.bukkit.entity.Player;
import org.bukkit.event.Event.Result;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.VanillaItem;
import io.github.thebusybiscuit.slimefun4.implementation.items.misc.SyntheticEmerald;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
/**
* This {@link Listener} prevents any {@link SlimefunItem} from being used to trade with
* Villagers, with one exception being {@link SyntheticEmerald}.
*
* @author TheBusyBiscuit
*
*/
public class VillagerTradingListener implements Listener {
public VillagerTradingListener(SlimefunPlugin plugin) {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler(ignoreCancelled = true)
public void onPreBrew(InventoryClickEvent e) {
Inventory clickedInventory = e.getClickedInventory();
Inventory topInventory = e.getView().getTopInventory();
if (clickedInventory != null && topInventory.getType() == InventoryType.MERCHANT) {
if (e.getAction() == InventoryAction.HOTBAR_SWAP) {
e.setCancelled(true);
return;
}
if (clickedInventory.getType() == InventoryType.MERCHANT) {
e.setCancelled(isUnallowed(SlimefunItem.getByItem(e.getCursor())));
}
else {
e.setCancelled(isUnallowed(SlimefunItem.getByItem(e.getCurrentItem())));
}
if (e.getResult() == Result.DENY) {
SlimefunPlugin.getLocalization().sendMessage((Player) e.getWhoClicked(), "villagers.no-trading", true);
}
}
}
private boolean isUnallowed(SlimefunItem item) {
return item != null && !(item instanceof VanillaItem) && !(item instanceof SyntheticEmerald) && !item.isDisabled();
}
}

View File

@ -110,7 +110,7 @@ public final class ResearchSetup {
register("redstone_alloy", 84, "Redstone Alloy", 16, SlimefunItems.REDSTONE_ALLOY);
register("carbonado_tools", 85, "Top Tier Machines", 24, SlimefunItems.CARBONADO_MULTI_TOOL, SlimefunItems.CARBONADO_JETPACK, SlimefunItems.CARBONADO_JETBOOTS);
register("first_aid", 86, "First Aid", 2, SlimefunItems.CLOTH, SlimefunItems.RAG, SlimefunItems.BANDAGE, SlimefunItems.SPLINT, SlimefunItems.TIN_CAN, SlimefunItems.VITAMINS, SlimefunItems.MEDICINE);
register("gold_armor", 87, "Shiny Armor", 13, SlimefunItems.GOLD_HELMET, SlimefunItems.GOLD_CHESTPLATE, SlimefunItems.GOLD_LEGGINGS, SlimefunItems.GOLD_BOOTS);
register("gold_armor", 87, "Shiny Armor", 13, SlimefunItems.GOLDEN_HELMET_12K, SlimefunItems.GOLDEN_CHESTPLATE_12K, SlimefunItems.GOLDEN_LEGGINGS_12K, SlimefunItems.GOLDEN_BOOTS_12K);
register("night_vision_googles", 89, "Night Vision Goggles", 10, SlimefunItems.NIGHT_VISION_GOGGLES);
register("pickaxe_of_containment", 90, "Pickaxe of Containment", 14, SlimefunItems.PICKAXE_OF_CONTAINMENT, SlimefunItems.BROKEN_SPAWNER);
register("hercules_pickaxe", 91, "Hercules Pickaxe", 28, SlimefunItems.HERCULES_PICKAXE);

View File

@ -390,10 +390,6 @@ public final class SlimefunItemSetup {
new ItemStack[] {null, null, null, null, new CustomItem(SlimefunUtils.getCustomHead(HeadTexture.IRON_GOLEM.getTexture()), "&aIron Golem"), null, null, null, null})
.register(plugin);
new OrganicNetherGoo(categories.resources, SlimefunItems.ORGANIC_NETHER_GOO, RecipeType.BARTER_DROP,
new ItemStack[] {null, null, null, null, new CustomItem(HeadTexture.PIGLIN_HEAD.getAsItemStack(), "&aPiglins"), null, null, null, null})
.register(plugin);
new UnplaceableBlock(categories.technicalComponents, SlimefunItems.ADVANCED_CIRCUIT_BOARD, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {new ItemStack(Material.LAPIS_BLOCK), new ItemStack(Material.LAPIS_BLOCK), new ItemStack(Material.LAPIS_BLOCK), new ItemStack(Material.REDSTONE_BLOCK), SlimefunItems.BASIC_CIRCUIT_BOARD, new ItemStack(Material.REDSTONE_BLOCK), new ItemStack(Material.LAPIS_BLOCK), new ItemStack(Material.LAPIS_BLOCK), new ItemStack(Material.LAPIS_BLOCK)})
.register(plugin);
@ -2458,10 +2454,6 @@ public final class SlimefunItemSetup {
new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, SlimefunItems.MAGICAL_GLASS, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.MAGICAL_GLASS, SlimefunItems.LIGHTNING_RUNE, SlimefunItems.MAGICAL_GLASS, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.MAGICAL_GLASS, SlimefunItems.MAGIC_LUMP_3})
.register(plugin);
new RuneOfUnemployment(categories.magicalResources, SlimefunItems.UNEMPLOYMENT_RUNE, RecipeType.ANCIENT_ALTAR,
new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, SlimefunItems.FLASK_OF_KNOWLEDGE, SlimefunItems.ENDER_LUMP_3, SlimefunItems.ORGANIC_NETHER_GOO, new ItemStack(Material.CRYING_OBSIDIAN), SlimefunItems.ORGANIC_NETHER_GOO, SlimefunItems.MAGICAL_GLASS, SlimefunItems.FLASK_OF_KNOWLEDGE, SlimefunItems.MAGICAL_GLASS })
.register(plugin);
new InfernalBonemeal(categories.magicalGadgets, SlimefunItems.INFERNAL_BONEMEAL, RecipeType.ANCIENT_ALTAR,
new ItemStack[] {new ItemStack(Material.NETHER_WART), SlimefunItems.EARTH_RUNE, new ItemStack(Material.NETHER_WART), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.BONE_MEAL), SlimefunItems.MAGIC_LUMP_2, new ItemStack(Material.NETHER_WART), new ItemStack(Material.BLAZE_POWDER), new ItemStack(Material.NETHER_WART)},
new SlimefunItemStack(SlimefunItems.INFERNAL_BONEMEAL, 8))
@ -2506,7 +2498,6 @@ public final class SlimefunItemSetup {
new ItemStack[] {new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA), new ItemStack(Material.WHITE_TERRACOTTA)},
new SlimefunItemStack(SlimefunItems.RAINBOW_CLAY, 8), new RainbowTickHandler(MaterialCollections.getAllTerracottaColors()))
.register(plugin);
new RainbowBlock(categories.magicalGadgets, SlimefunItems.RAINBOW_CONCRETE, RecipeType.ANCIENT_ALTAR,
new ItemStack[] {new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), SlimefunItems.RAINBOW_RUNE, new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE), new ItemStack(Material.WHITE_CONCRETE)},
new SlimefunItemStack(SlimefunItems.RAINBOW_CONCRETE, 8), new RainbowTickHandler(MaterialCollections.getAllConcreteColors()))
@ -3233,6 +3224,16 @@ public final class SlimefunItemSetup {
new ItemStack[] {SlimefunItems.SILICON, new ItemStack(Material.YELLOW_DYE), SlimefunItems.SILICON, new ItemStack(Material.YELLOW_DYE), new ItemStack(Material.STRING), new ItemStack(Material.YELLOW_DYE), SlimefunItems.GILDED_IRON, new ItemStack(Material.YELLOW_DYE), SlimefunItems.SILICON})
.register(plugin);
}
if (SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
new OrganicNetherGoo(categories.resources, SlimefunItems.ORGANIC_NETHER_GOO, RecipeType.BARTER_DROP,
new ItemStack[] {null, null, null, null, new CustomItem(HeadTexture.PIGLIN_HEAD.getAsItemStack(), "&aPiglins"), null, null, null, null})
.register(plugin);
new RuneOfUnemployment(categories.magicalResources, SlimefunItems.UNEMPLOYMENT_RUNE, RecipeType.ANCIENT_ALTAR,
new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, SlimefunItems.FLASK_OF_KNOWLEDGE, SlimefunItems.ENDER_LUMP_3, SlimefunItems.ORGANIC_NETHER_GOO, new ItemStack(Material.CRYING_OBSIDIAN), SlimefunItems.ORGANIC_NETHER_GOO, SlimefunItems.MAGICAL_GLASS, SlimefunItems.FLASK_OF_KNOWLEDGE, SlimefunItems.MAGICAL_GLASS})
.register(plugin);
}
}
private static void registerArmorSet(Category category, ItemStack baseComponent, ItemStack[] items, String idSyntax, boolean vanilla, PotionEffect[][] effects, SlimefunAddon addon) {

View File

@ -101,9 +101,9 @@ public enum HeadTexture {
CARGO_ARROW_LEFT("f2599bd986659b8ce2c4988525c94e19ddd39fad08a38284a197f1b70675acc"),
CARGO_ARROW_RIGHT("c2f910c47da042e4aa28af6cc81cf48ac6caf37dab35f88db993accb9dfe516"),
ADD_NEW_LANGUAGE("3edd20be93520949e6ce789dc4f43efaeb28c717ee6bfcbbe02780142f716"),
IRON_GOLEM("89091d79ea0f59ef7ef94d7bba6e5f17f2f7d4572c44f90f76c4819a714");
IRON_GOLEM("89091d79ea0f59ef7ef94d7bba6e5f17f2f7d4572c44f90f76c4819a714"),
PIGLIN_HEAD("2882af1294a74023e6919a31d1a027310f2e142afb4667d230d155e7f21dbb41");
private final String texture;
HeadTexture(String texture) {

View File

@ -270,78 +270,42 @@ public final class SlimefunUtils {
private static boolean equalsItemMeta(ItemMeta itemMeta, ImmutableItemMeta meta, boolean checkLore) {
Optional<String> displayName = meta.getDisplayName();
if (itemMeta.hasDisplayName() && displayName.isPresent()) {
if (itemMeta.getDisplayName().equals(displayName.get())) {
Optional<List<String>> itemLore = meta.getLore();
if (checkLore) {
if (itemMeta.hasLore() && itemLore.isPresent()) {
return equalsLore(itemMeta.getLore(), itemLore.get());
}
else {
return !itemMeta.hasLore() && !itemLore.isPresent();
}
}
else {
return true;
}
}
else {
return false;
}
if (itemMeta.hasDisplayName() != displayName.isPresent()) {
return false;
}
else if (!itemMeta.hasDisplayName() && !displayName.isPresent()) {
else if (itemMeta.hasDisplayName() && displayName.isPresent() && !itemMeta.getDisplayName().equals(displayName.get())) {
return false;
}
else if (!checkLore) {
return true;
}
else {
Optional<List<String>> itemLore = meta.getLore();
if (checkLore) {
if (itemMeta.hasLore() && itemLore.isPresent()) {
return equalsLore(itemMeta.getLore(), itemLore.get());
}
else {
return !itemMeta.hasLore() && !itemLore.isPresent();
}
if (itemMeta.hasLore() && itemLore.isPresent()) {
return equalsLore(itemMeta.getLore(), itemLore.get());
}
else {
return true;
return !itemMeta.hasLore() && !itemLore.isPresent();
}
}
else return false;
}
private static boolean equalsItemMeta(ItemMeta itemMeta, ItemMeta sfitemMeta, boolean checkLore) {
if (itemMeta.hasDisplayName() && sfitemMeta.hasDisplayName()) {
if (itemMeta.getDisplayName().equals(sfitemMeta.getDisplayName())) {
if (checkLore) {
if (itemMeta.hasLore() && sfitemMeta.hasLore()) {
return equalsLore(itemMeta.getLore(), sfitemMeta.getLore());
}
else {
return !itemMeta.hasLore() && !sfitemMeta.hasLore();
}
}
else {
return true;
}
}
else {
return false;
}
if (itemMeta.hasDisplayName() != sfitemMeta.hasDisplayName()) {
return false;
}
else if (!itemMeta.hasDisplayName() && !sfitemMeta.hasDisplayName()) {
if (checkLore) {
if (itemMeta.hasLore() && sfitemMeta.hasLore()) {
return equalsLore(itemMeta.getLore(), sfitemMeta.getLore());
}
else {
return !itemMeta.hasLore() && !sfitemMeta.hasLore();
}
}
else {
return true;
}
else if (itemMeta.hasDisplayName() && sfitemMeta.hasDisplayName() && !itemMeta.getDisplayName().equals(sfitemMeta.getDisplayName())) {
return false;
}
else if (!checkLore) {
return true;
}
else if (itemMeta.hasLore() && sfitemMeta.hasLore()) {
return equalsLore(itemMeta.getLore(), sfitemMeta.getLore());
}
else {
return false;
return !itemMeta.hasLore() && !sfitemMeta.hasLore();
}
}

View File

@ -155,10 +155,10 @@ public final class SlimefunItems {
public static final SlimefunItemStack GILDED_IRON_CHESTPLATE = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GILDED_IRON_CHESTPLATE;
public static final SlimefunItemStack GILDED_IRON_LEGGINGS = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GILDED_IRON_LEGGINGS;
public static final SlimefunItemStack GILDED_IRON_BOOTS = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GILDED_IRON_BOOTS;
public static final SlimefunItemStack GOLD_HELMET = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GOLD_HELMET;
public static final SlimefunItemStack GOLD_CHESTPLATE = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GOLD_CHESTPLATE;
public static final SlimefunItemStack GOLD_LEGGINGS = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GOLD_LEGGINGS;
public static final SlimefunItemStack GOLD_BOOTS = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GOLD_BOOTS;
public static final SlimefunItemStack GOLD_HELMET = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GOLDEN_HELMET_12K;
public static final SlimefunItemStack GOLD_CHESTPLATE = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GOLDEN_CHESTPLATE_12K;
public static final SlimefunItemStack GOLD_LEGGINGS = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GOLDEN_LEGGINGS_12K;
public static final SlimefunItemStack GOLD_BOOTS = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.GOLDEN_BOOTS_12K;
public static final SlimefunItemStack SLIME_HELMET_STEEL = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.SLIME_HELMET_STEEL;
public static final SlimefunItemStack SLIME_CHESTPLATE_STEEL = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.SLIME_CHESTPLATE_STEEL;
public static final SlimefunItemStack SLIME_LEGGINGS_STEEL = io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems.SLIME_LEGGINGS_STEEL;

View File

@ -41,6 +41,12 @@ guide:
select: Klicke hier um diese Sprache auszuwählen
select-default: Klicke hier um die Standardsprache auszuwählen
selected-language: 'Aktuell ausgewählt:'
change: Klicke um die Sprache zu ändern
description:
- "&7Hier kannst du deine Spracheinstellungen"
- "&7verwalten. Derzeit umfasst dies"
- "&7jedoch nur bestimmte Nachrichten,"
- "&7Items können noch nicht übersetzt werden."
title:
main: Slimefun-Handbuch
settings: Einstellungen & Infos
@ -80,6 +86,7 @@ guide:
- Um diese Kategorie freizuschalten,
- müssen zuerst sämtliche Items der
- folgenden Kategorien freigeschaltet werden
work-in-progress: Dieses Feature befindet sich noch in der Testphase!
messages:
not-researched: "&4Du hast diesen Gegenstand noch nicht freigeschaltet!"
not-enough-xp: "&4Du hast nicht genügend Erfahrungspunkte, um dies freizuschalten"
@ -96,7 +103,6 @@ messages:
not-valid-research: "&4%research% &cist kein gültiger Erfahrungsgrad!"
give-research: '&bDu hast %player% den Erfahrungsgrad &7"%research%&7" vergeben'
hungry: "&cDu bist zu hungrig, um dies zu tun!"
mode-change: "&bDer Modus von deinem %device% wurde geändert zu: &9%mode%"
disabled-in-world: "&4&lDieses Item wurde in dieser Welt deaktiviert!"
disabled-item: "&4&lDieses Item wurde von einem Server-Administrator deaktiviert!"
no-tome-yourself: "&cDu kannst dieses Item nicht an dir selbst anwenden..."
@ -164,6 +170,10 @@ messages:
wrong-world: "&cDein Ankerpunkt scheint sich in einer anderen Dimension zu befinden!"
distance: "&7Messung erfolgreich. &eDistanz: %distance%"
anchor-set: "&aErfolgreich den Ankerpunkt gesetzt:&e %anchor%"
multi-tool:
mode-change: "&bDer Modus von deinem Multi-Tool wurde geändert zu: &9%mode%"
not-shears: "&cEinMulti Tool kann nicht als Schere verwendet werden!"
mode-change: "&bDer Modus von deinem %device% wurde geändert zu: &9%mode%"
machines:
pattern-not-found: "&eEs tut mir leid, aber ich konnte kein passendes Rezept finden."
unknown-material: "&eEs tut mir leid, aber ich erkenne das Item in meinem Werfer
@ -234,6 +244,7 @@ gps:
werden unterstützt!)"
added: "&aEin neuer Wegpunkt wurde hinzugefügt"
max: "&4Du hast die maximale Anzahl an Wegpunkten erreicht"
duplicate: "&4Es existiert bereits ein Wegpunkt mit folgendem Namen: &f%waypoint%"
insufficient-complexity:
- "&4Unzureichende Komplexität deines GPS-Netzwerkes! Folgende Komplexität wird
benötigt: &c%complexity%"
@ -306,6 +317,7 @@ languages:
zh-CN: Chinesisch (China)
el: Griechisch
he: Hebräisch
pt-BR: Portugiesisch (Brasilien)
ar: Arabisch
af: Afrikaans
da: Dänisch
@ -318,7 +330,6 @@ languages:
th: Thailändisch
ro: Rumänisch
pt: Portugiesisch (Portugal)
pt-BR: Portugiesisch (Brasilien)
bg: Bulgarisch
ko: Koreanisch
tr: Türkisch
@ -327,5 +338,9 @@ languages:
sr: Serbisch
be: Belarusisch
tl: Tagalog
brewing_stand:
not-working: "&4Items von Slimefun können nicht zum Brauen verwendet werden!"
villagers:
no-trading: "&4Items von Slimefun können nicht zum Handeln verwendet werden!"
miner:
no-ores: "&eIch konnte leider keine Erze in der Nähe finden!"

View File

@ -24,6 +24,7 @@ commands:
guide:
locked: 'LOCKED'
work-in-progress: 'This feature is not fully finished yet!'
locked-category:
- 'To unlock this category you will'
@ -64,6 +65,13 @@ guide:
selected-language: 'Currently selected:'
select: 'Click to select this language'
select-default: 'Click to select the default language'
change: 'Click to select a new language'
description:
- '&7You now have the option to change'
- '&7the language in which Slimefun'
- '&7will be presented to you. Items'
- '&7cannot be translated for now.'
translations:
name: '&aIs something missing?'
@ -83,6 +91,7 @@ guide:
commit: 'Commit'
commits: 'Commits'
profile-link: 'Click to visit their profile on GitHub'
roles:
developer: '&6Developer'
wiki: '&3Wiki Editor'
@ -105,13 +114,16 @@ messages:
not-valid-research: '&4%research% &cis not a valid Research!'
give-research: '&bYou have given %player% the Research &7"%research%&7"'
hungry: '&cYou are too hungry to do that!'
mode-change: '&b%device% mode changed to: &9%mode%'
disabled-in-world: '&4&lThis Item has been disabled in this world'
disabled-item: '&4&lThis Item has been disabled! How did you even get that?'
no-tome-yourself: '&cYou cannot use the &4Tome of Knowledge &con yourself...'
multimeter: '&bStored Energy: &3%stored% &b/ &3%capacity%'
piglin-barter: '&4You cannot barter with piglins using Slimefun items'
multi-tool:
mode-change: '&b%device% mode changed to: &9%mode%'
not-shears: '&cA Multi Tool cannot be used as shears!'
talisman:
anvil: '&a&oYour Talisman saved your tool from breaking'
miner: '&a&oYour Talisman just doubled your drops'
@ -232,6 +244,12 @@ machines:
anvil:
not-working: '&4You cannot use Slimefun Items in an anvil!'
brewing_stand:
not-working: '&4You cannot use Slimefun Items in a brewing stand!'
villagers:
no-trading: '&4You cannot trade Slimefun Items with Villagers!'
backpack:
already-open: '&cSorry, this Backpack is open somewhere else!'
no-stack: '&cYou cannot stack Backpacks'
@ -245,6 +263,7 @@ gps:
new: '&ePlease type in a name for your new waypoint in the chat. &7(Color Codes supported!)'
added: '&aSuccessfully added a new waypoint'
max: '&4You have reached the maximum amount of waypoints'
duplicate: '&4You have already created a waypoint named: &f%waypoint%'
insufficient-complexity:
- '&4Insufficient GPS Network Complexity: &c%complexity%'

View File

@ -39,6 +39,12 @@ guide:
select: Clic para seleccionar este idioma.
select-default: Clic para seleccionar el idioma predeterminado.
selected-language: 'Actualmente seleccionado:'
change: Click para seleccionar un nuevo lenguaje
description:
- "&7Ahora tienes la opción de cambiar"
- "&7el idioma en el que Slimefun"
- "&7se le presentará. Items"
- "&7no puede ser traducido por ahora."
title:
main: Guía de Slimefun.
settings: Configuración e Información.
@ -78,6 +84,7 @@ guide:
- Para desbloquear esta categoría deberás
- desbloquear todos los objetos de las
- siguientes categorías
work-in-progress: Esta característica no esta completamente terminada todavia!!
messages:
not-researched: "&4No tienes conocimiento suficiente para entender esto."
not-enough-xp: "&4No tienes suficiente XP para desbloquear esto."
@ -95,7 +102,6 @@ messages:
not-valid-research: "&c¡&4%research% &cno es un conocimiento válido!"
give-research: '&bLe has dado a %player% la investigación &7"%research%&7"'
hungry: "&c¡Tienes demasiada hambre para hacer eso!"
mode-change: 'El modo de &b%device% ha cambiado a: &9%mode%'
disabled-in-world: "&4&lEste item ha sido desactivado en el mundo."
disabled-item: "&4&l¡Este item ha sido desactivado! ¿Cómo es que lo tienes?"
no-tome-yourself: "&cNo puedes usar el &4Tome of Knowledge &cen ti mismo..."
@ -150,6 +156,20 @@ messages:
- "&7¡Siempre mira el lado bueno de la vida!"
- "&7Esta era un bizcocho y no una galleta"
- "&7¡Los signos de neón son lo MEJOR!"
piglin-barter: "&4No puedes tradear con piglins usando items de Slimefun"
enchantment-rune:
fail: "&cNo puedes encantar este item."
no-enchantment: "&cNo se pudo encontrar un encantamiento aplicable a este item."
success: "&aHas aplicado con éxito un encantamiento aleatorio a este item."
tape-measure:
no-anchor: "&cNecesitas establecer un ancla antes de comenzar a medir!"
wrong-world: "&cParece ser que tu ancla se encuentra en un mundo diferente!"
distance: "&7Medida tomada. &eDistancia: %distance%"
anchor-set: "&aAncla establecida con éxito:&e %anchor%"
multi-tool:
mode-change: "&b%device% modo cambiado a: &9%mode%"
not-shears: "&cUna Multi Tool no puede ser usada como tijeras!"
mode-change: 'El modo de &b%device% ha cambiado a: &9%mode%'
machines:
pattern-not-found: "&eLo siento, no puedo reconocer esta receta. Por favor coloca
el objeto en el patrón correcto dentro del dispensador."
@ -218,6 +238,7 @@ gps:
códigos de color!)"
added: "&aNuevo waypoint agregado exitosamente."
max: "&4Has alcanzado el máximo número de waypoints permitidos."
duplicate: "&4Ya has creado un waypoint llamado: &f%waypoint%"
insufficient-complexity:
- "&4Complejidad de red GPS insuficiente: &c%complexity%"
- "&4a) No tienes una red GPS armada aún."
@ -291,8 +312,6 @@ languages:
zh-CN: Chino (China)
el: Griego
he: Hebreo
pt: Portugués (Portugal)
pt-BR: Portugués (Brasil)
ar: Árabe
af: Africano
da: Danés
@ -304,6 +323,8 @@ languages:
fa: Persa
th: Tailandés
ro: Rumano
pt: Portugués (Portugal)
pt-BR: Portugués (Brasil)
bg: Búlgaro
ko: Coreano
tr: Turco
@ -312,5 +333,9 @@ languages:
sr: Serbio
be: Bielorruso
tl: Tagalog
brewing_stand:
not-working: "&4¡No puedes usar objetos de Slimefun en un soporte para pociones!"
villagers:
no-trading: "&4No puedes tradear Slimefun items con los aldeanos!"
miner:
no-ores: "&ePerdón, ¡No encuentro ningún mineral cerca!"

View File

@ -121,7 +121,7 @@ messages:
meghalsz."
research:
start: "&7Az Ősi Lelkek titokzatos szavakat súgnak a füledbe!"
progress: "&7Elkezdel kíváncsiskodni a kutatásról, neve: &b%research% &e(%progress%)"
progress: "&7Elkezdtél kíváncsiskodni a következő kutatásról: &b%research% &e(%progress%)"
fire-extinguish: "&7Eloltottad magad!"
cannot-place: "&cNem teheted ezt a blokkot oda!"
no-pvp: "&cA pvp itt nem engedélyezett!"
@ -300,8 +300,6 @@ languages:
zh-CN: Kínai (Kína)
el: Görög
he: Héber
pt: Portugál (Portugália)
pt-BR: Portugál (Brazília)
ar: Arab
af: Afrikánsz
da: Dán
@ -313,6 +311,8 @@ languages:
fa: Perzsa
th: Thai
ro: Román
pt: Portugál (Portugália)
pt-BR: Portugál (Brazília)
bg: Bolgár
ko: Koreai
tr: Török
@ -321,5 +321,7 @@ languages:
sr: Szerb
be: Belorusz
tl: Tagalog
brewing_stand:
not-working: "&4Nem használhatsz Slimefun tárgyakat a Főzőállványban!"
miner:
no-ores: "&eSajnálom, nem találtam semmilyen Ércet a közelben!"

View File

@ -284,6 +284,8 @@ languages:
zh-CN: 中国語(中国)
el: ギリシャ語
he: ヘブライ語
pt: ポルトガル語(ポルトガル)
pt-BR: ポルトガル語(ブラジル)
ar: アラビア語
af: アフリカーンス語
da: デンマーク語
@ -295,8 +297,6 @@ languages:
fa: ペルシア語
th: タイ語
ro: ルーマニア語
pt: ポルトガル語(ポルトガル)
pt-BR: ポルトガル語(ブラジル)
bg: ブルガリア語
ko: 韓国語
tr: トルコ語
@ -305,5 +305,7 @@ languages:
sr: セルビア語
be: ベラルーシ語
tl: タガログ語
brewing_stand:
not-working: "&4Slimefunのアイテムは醸造台で使えません"
miner:
no-ores: "&e周辺には鉱石が見つかりませんでした"

View File

@ -334,3 +334,5 @@ languages:
sr: Serbian
be: Belarusian
tl: Tagalog/Filipino
brewing_stand:
not-working: "&4Hindi ka maaaring gumamit ng mga Item ng Slimefun sa Brewing Stand!"

View File

@ -41,6 +41,12 @@ guide:
select: Bu dili seçmek için tıklayın
select-default: Varsayılan dili seçmek için tıklayın
selected-language: 'Şuan seçili:'
change: Yeni bir dil seçmek için tıklayın
description:
- "&7Artık Slimefun içerisinde size"
- "&7sunulacak olan dilinizi"
- "&7değiştirebilirsiniz. Henüz eşyalar"
- "&7çevrilememektedir."
title:
main: Slimefun Rehberi
settings: Ayarlar & Bilgi
@ -80,6 +86,7 @@ guide:
- Bu kategoriyi açmak için
- aşağıdaki kategorilerde bulunan
- bütün eşyalarıın
work-in-progress: Bu özellik henüz tamamlanmadı!
messages:
not-researched: "&4Bunu anlayacak kadar bilgin yok"
not-enough-xp: "&4Bunun kilidini açmak için yeterli XP niz yok"
@ -96,7 +103,6 @@ messages:
not-valid-research: "&4%research% &cgeçerli bir araştırma değil!"
give-research: '&b%player% adlı oyuncu için bir araştırmayı açtın: &7"%research%&7"'
hungry: "&cBunu yapmak için çok açsın!"
mode-change: "&b%device% modu değişti: &9%mode%"
disabled-in-world: "&4&lBu eşya bu dünyada devre dışı bırakıldı."
disabled-item: "&4&lBu eşya devre dışı bırakıldı! Bunu nasıl aldın?"
no-tome-yourself: "&4Tome of Knowledge &cı kendin için kullanamazsın..."
@ -159,6 +165,10 @@ messages:
wrong-world: "&cSeçtiğiniz nokta başka bir dünyada gözüküyor!"
distance: "&7Ölçüm yapıldı. &eUzaklık: %distance%"
anchor-set: "&aBaşarılı bir şekilde bir nokta seçildi:&e %anchor%"
multi-tool:
mode-change: "&b%device% modül değiştirildi: &9%mode%"
not-shears: "&cBir Multi Tool makas olarak kullanılamaz!"
mode-change: "&b%device% modu değişti: &9%mode%"
machines:
pattern-not-found: "&eÜzgünüm, bu tarifi tanıyamadım. Lütfen Eşyaları Dağıtıcıya
doğru şekilde yerleştirin."
@ -225,6 +235,7 @@ gps:
new: "&eLütfen sohbette yeni yer noktanız için bir ad yazın. &7(Renk Kodları destekleniyor!)"
added: "&aYeni bir yer noktası başarıyla eklendi"
max: "&4Maksimum yer noktası sayısına ulaştınız"
duplicate: "&4Bu adla zaten bir yer noktası yarattınız: &f%waypoint%"
insufficient-complexity:
- "&4Yetersiz GPS Ağ Gücü: &c%complexity%"
- "&4a) Henüz bir GPS Ağı kurulumunuz yok"
@ -318,5 +329,9 @@ languages:
sr: Sırpça
be: Belarusça
tl: Tagalog
brewing_stand:
not-working: "&4Slimefun eşyalarını simya standında kullanamazsın!"
villagers:
no-trading: "&4Köylülerle Slimefun eşyalarını kullanarak ticaret yapamazsın!"
miner:
no-ores: "&eÜzgünüm, yakınlarda herhangi bir cevher bulamadım!"

View File

@ -213,6 +213,7 @@ gps:
new: "&e给你的路径点起个名字吧 &7(支持彩色代码!)"
added: "&a成功添加了新的传送点"
max: "&4你已到达设置传送点个数的最大上限"
duplicate: "&4你已经创建了一个相同名字的传送点了: &f%waypoint%"
insufficient-complexity:
- "&4GPS网络复杂度不足: &c%complexity%"
- "&4a) 你还没有设置一个 GPS 网络"
@ -284,6 +285,7 @@ languages:
zh-CN: 简体中文 (中国)
el: 希腊语
he: 希伯来语
pt: 葡萄牙语 (葡萄牙)
ar: 阿拉伯语
af: 南非语
da: 丹麦语
@ -295,7 +297,6 @@ languages:
fa: 波斯语
th: 泰语
ro: 罗马尼亚语
pt: 葡萄牙语 (葡萄牙)
pt-BR: 葡萄牙语 (巴西)
bg: 保加利亚语
ko: 韩语
@ -305,5 +306,9 @@ languages:
sr: 塞尔维亚语
be: 白俄罗斯语
tl: 他加禄语
brewing_stand:
not-working: "&4你不能在酿造台中使用 Slimefun 物品!"
villagers:
no-trading: "&4你不能用 Slimefun 的物品和村民交易!"
miner:
no-ores: "&e抱歉, 周围找不到矿石了!"

View File

@ -118,6 +118,11 @@ slimefun:
lore:
- Haz este objeto tal como se muestra
- usando una Refinery
barter_drop:
name: Piglin Bartering Drop
lore:
- Troca con Piglins usando
- Lingotes de Oro para obtener este objeto
minecraft:
shaped:
name: Receta de Crafteo con forma

View File

@ -32,7 +32,7 @@ slimefun:
- Készítsd el ezt a Tárgyat az ábra alapján
- egy Ore Crusher segítségével
mob_drop:
name: Mob Drop
name: Élőlény Dobja
lore:
- Öld meg ezt az Élőlényt,
- hogy megszerezd ezt a tárgyat
@ -118,6 +118,11 @@ slimefun:
lore:
- Készítsd el ezt a Tárgyat az ábra alapján
- egy Refinery segítségével
barter_drop:
name: Piglinek Dobják Cserélésnél
lore:
- Cseréld el a Piglenekkel Aranyrudakat,
- hogy megszerezd ezt a tárgyat
minecraft:
shaped:
name: Barkácsrecept Forma

View File

@ -118,6 +118,11 @@ slimefun:
lore:
- 如合成表所示
- 用炼油机合成
barter_drop:
name: 猪灵交易掉落
lore:
- 使用金锭与猪灵交易
- 可以获得此物品
minecraft:
shaped:
name: 有序合成

View File

@ -236,3 +236,7 @@ slimefun:
advanced_industrial_miner: Minería Mejorada
magical_zombie_pills: De-Zombificación
auto_brewer: Alquimia Industrial
enchantment_rune: Encantamiento Antiguo
lead_clothing: Ropa de Plomo
tape_measure: Cinta Métrica
iron_golem_assembler: Iron Golems Automáticos

View File

@ -7,7 +7,6 @@ import org.bukkit.potion.PotionEffectType;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import be.seeseemelk.mockbukkit.MockBukkit;
@ -45,7 +44,6 @@ public class TestDietCookie implements SlimefunItemTest<DietCookie> {
}
@Test
@Disabled("Potion Effects are currently not fully implemented in MockBukkit")
public void testConsumptionBehaviour() {
PlayerMock player = server.addPlayer();
DietCookie cookie = registerSlimefunItem(plugin, "TEST_DIET_COOKIE");

View File

@ -6,7 +6,6 @@ import org.bukkit.potion.PotionEffectType;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import be.seeseemelk.mockbukkit.MockBukkit;
@ -44,7 +43,6 @@ public class TestMonsterJerky implements SlimefunItemTest<MonsterJerky> {
}
@Test
@Disabled("Potion Effects are currently not fully implemented in MockBukkit")
public void testConsumptionBehaviour() {
PlayerMock player = server.addPlayer();
player.addPotionEffect(PotionEffectType.HUNGER.createEffect(20, 2));

View File

@ -0,0 +1,137 @@
package io.github.thebusybiscuit.slimefun4.testing.tests.listeners;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
import org.bukkit.Material;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.event.inventory.InventoryPickupItemEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import be.seeseemelk.mockbukkit.MockBukkit;
import be.seeseemelk.mockbukkit.ServerMock;
import be.seeseemelk.mockbukkit.entity.ItemEntityMock;
import be.seeseemelk.mockbukkit.inventory.ChestInventoryMock;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.AncientAltarListener;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.ItemPickupListener;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.CSCoreLibPlugin.cscorelib2.item.CustomItem;
class TestItemPickupListener {
private static SlimefunPlugin plugin;
private static ItemPickupListener listener;
private static ServerMock server;
@BeforeAll
public static void load() {
server = MockBukkit.mock();
plugin = MockBukkit.load(SlimefunPlugin.class);
listener = new ItemPickupListener(plugin);
}
@AfterAll
public static void unload() {
MockBukkit.unmock();
}
@ParameterizedTest
@ValueSource(booleans = { true, false })
void testNoPickupFlagForEntities(boolean flag) {
Player player = server.addPlayer();
Item item = new ItemEntityMock(server, UUID.randomUUID(), new ItemStack(Material.COMPASS));
if (flag) {
SlimefunUtils.markAsNoPickup(item, "Unit Test");
}
EntityPickupItemEvent event = new EntityPickupItemEvent(player, item, 1);
listener.onEntityPickup(event);
Assertions.assertEquals(flag, event.isCancelled());
}
@ParameterizedTest
@ValueSource(booleans = { true, false })
void testNoPickupFlagForInventories(boolean flag) {
Inventory inventory = new ChestInventoryMock(null, 5);
Item item = new ItemEntityMock(server, UUID.randomUUID(), new ItemStack(Material.COMPASS));
if (flag) {
SlimefunUtils.markAsNoPickup(item, "Unit Test");
}
InventoryPickupItemEvent event = new InventoryPickupItemEvent(inventory, item);
listener.onHopperPickup(event);
Assertions.assertEquals(flag, event.isCancelled());
}
@ParameterizedTest
@ValueSource(booleans = { true, false })
void testAltarProbeForEntities(boolean flag) {
Player player = server.addPlayer();
ItemStack stack;
if (flag) {
stack = new CustomItem(Material.DIAMOND, AncientAltarListener.ITEM_PREFIX + System.nanoTime());
}
else {
stack = new CustomItem(Material.DIAMOND, "&5Just a normal named diamond");
}
AtomicBoolean removed = new AtomicBoolean(false);
Item item = new ItemEntityMock(server, UUID.randomUUID(), stack) {
@Override
public void remove() {
removed.set(true);
}
};
EntityPickupItemEvent event = new EntityPickupItemEvent(player, item, 1);
listener.onEntityPickup(event);
Assertions.assertEquals(flag, event.isCancelled());
Assertions.assertEquals(flag, removed.get());
}
@ParameterizedTest
@ValueSource(booleans = { true, false })
void testAltarProbeForInventories(boolean flag) {
Inventory inventory = new ChestInventoryMock(null, 5);
ItemStack stack;
if (flag) {
stack = new CustomItem(Material.DIAMOND, AncientAltarListener.ITEM_PREFIX + System.nanoTime());
}
else {
stack = new CustomItem(Material.DIAMOND, "&5Just a normal named diamond");
}
AtomicBoolean removed = new AtomicBoolean(false);
Item item = new ItemEntityMock(server, UUID.randomUUID(), stack) {
@Override
public void remove() {
removed.set(true);
}
};
InventoryPickupItemEvent event = new InventoryPickupItemEvent(inventory, item);
listener.onHopperPickup(event);
Assertions.assertEquals(flag, event.isCancelled());
Assertions.assertEquals(flag, removed.get());
}
}

View File

@ -0,0 +1,111 @@
package io.github.thebusybiscuit.slimefun4.testing.tests.listeners;
import java.util.UUID;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Item;
import org.bukkit.entity.Piglin;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import org.mockito.Mockito;
import be.seeseemelk.mockbukkit.MockBukkit;
import be.seeseemelk.mockbukkit.ServerMock;
import be.seeseemelk.mockbukkit.entity.ItemEntityMock;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.PiglinListener;
import io.github.thebusybiscuit.slimefun4.testing.TestUtilities;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
class TestPiglinListener {
private static SlimefunPlugin plugin;
private static PiglinListener listener;
private static ServerMock server;
@BeforeAll
public static void load() {
server = MockBukkit.mock();
plugin = MockBukkit.load(SlimefunPlugin.class);
listener = new PiglinListener(plugin);
}
@AfterAll
public static void unload() {
MockBukkit.unmock();
}
private EntityPickupItemEvent createPickupEvent(ItemStack item) {
Piglin piglin = Mockito.mock(Piglin.class);
Mockito.when(piglin.getType()).thenReturn(EntityType.PIGLIN);
Item itemEntity = new ItemEntityMock(server, UUID.randomUUID(), item);
return new EntityPickupItemEvent(piglin, itemEntity, 1);
}
private PlayerInteractEntityEvent createInteractEvent(EquipmentSlot hand, ItemStack item) {
Player player = server.addPlayer();
Piglin piglin = Mockito.mock(Piglin.class);
Mockito.when(piglin.getType()).thenReturn(EntityType.PIGLIN);
Mockito.when(piglin.isValid()).thenReturn(true);
if (hand == EquipmentSlot.OFF_HAND) {
player.getInventory().setItemInOffHand(item);
}
else {
player.getInventory().setItemInMainHand(item);
}
return new PlayerInteractEntityEvent(player, piglin, hand);
}
@Test
void testPiglinPickup() {
EntityPickupItemEvent event = createPickupEvent(new ItemStack(Material.GOLD_INGOT));
listener.onPickup(event);
Assertions.assertFalse(event.isCancelled());
}
@Test
void testPiglinPickupWithSlimefunItem() {
SlimefunItem item = TestUtilities.mockSlimefunItem(plugin, "PIGLIN_PICKUP_MOCK", new CustomItem(Material.GOLD_INGOT, "&6Piglin Bait"));
item.register(plugin);
EntityPickupItemEvent event = createPickupEvent(item.getItem());
listener.onPickup(event);
Assertions.assertTrue(event.isCancelled());
}
@ParameterizedTest
@EnumSource(value = EquipmentSlot.class, names = { "HAND", "OFF_HAND" })
void testPiglinInteract(EquipmentSlot hand) {
PlayerInteractEntityEvent event = createInteractEvent(hand, new ItemStack(Material.GOLD_INGOT));
listener.onInteract(event);
Assertions.assertFalse(event.isCancelled());
}
@ParameterizedTest
@EnumSource(value = EquipmentSlot.class, names = { "HAND", "OFF_HAND" })
void testPiglinInteractWithSlimefunItem(EquipmentSlot hand) {
SlimefunItem item = TestUtilities.mockSlimefunItem(plugin, "PIGLIN_GIVE_" + hand.name(), new CustomItem(Material.GOLD_INGOT, "&6Piglin Bait"));
item.register(plugin);
PlayerInteractEntityEvent event = createInteractEvent(hand, item.getItem());
listener.onInteract(event);
Assertions.assertTrue(event.isCancelled());
}
}

View File

@ -0,0 +1,71 @@
package io.github.thebusybiscuit.slimefun4.testing.tests.listeners;
import java.util.stream.Stream;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.inventory.ItemStack;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import be.seeseemelk.mockbukkit.MockBukkit;
import be.seeseemelk.mockbukkit.ServerMock;
import be.seeseemelk.mockbukkit.entity.PlayerMock;
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunGuideListener;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
class TestSlimefunGuideListener {
private static SlimefunPlugin plugin;
private static ServerMock server;
@BeforeAll
public static void load() {
server = MockBukkit.mock();
plugin = MockBukkit.load(SlimefunPlugin.class);
}
@AfterAll
public static void unload() {
MockBukkit.unmock();
}
@ParameterizedTest
@MethodSource("cartesianBooleans")
void testFirstJoin(boolean hasPlayedBefore, boolean giveSlimefunGuide) {
SlimefunGuideListener listener = new SlimefunGuideListener(plugin, giveSlimefunGuide);
PlayerMock player = new PlayerMock(server, "CanIHazGuide");
if (hasPlayedBefore) {
player.setLastPlayed(System.currentTimeMillis());
}
PlayerJoinEvent event = new PlayerJoinEvent(player, "CanIHazGuide has joined and wants sum guide");
listener.onJoin(event);
ItemStack guide = SlimefunGuide.getItem(SlimefunGuide.getDefaultLayout());
Assertions.assertEquals(!hasPlayedBefore && giveSlimefunGuide, hasSlimefunGuide(player, guide));
}
private boolean hasSlimefunGuide(Player player, ItemStack guide) {
return SlimefunUtils.isItemSimilar(player.getInventory().getItem(0), guide, true);
}
/**
* This returns an {@link Arguments} {@link Stream} of boolean combinations.
* It performs a certesian product on two boolean sets.
*
* @return a {@link Stream} of {@link Arguments}
*/
private static Stream<Arguments> cartesianBooleans() {
Stream<Boolean> stream = Stream.of(true, false);
return stream.flatMap(a -> Stream.of(true, false).map(b -> Arguments.of(a, b)));
}
}

View File

@ -59,7 +59,8 @@ public class TestSoulboundListener {
player.respawn();
server.getPluginManager().assertEventFired(PlayerRespawnEvent.class, event -> {
return player.getInventory().getItem(6).isSimilar(item) == soulbound;
ItemStack stack = player.getInventory().getItem(6);
return SlimefunUtils.isItemSimilar(stack, item, true) == soulbound;
});
}

View File

@ -0,0 +1,97 @@
package io.github.thebusybiscuit.slimefun4.testing.tests.listeners;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.Event.Result;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.inventory.InventoryType.SlotType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import be.seeseemelk.mockbukkit.MockBukkit;
import be.seeseemelk.mockbukkit.ServerMock;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.VanillaItem;
import io.github.thebusybiscuit.slimefun4.implementation.items.misc.SyntheticEmerald;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.VillagerTradingListener;
import io.github.thebusybiscuit.slimefun4.testing.TestUtilities;
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;
class TestVillagerTradingListener {
private static SlimefunPlugin plugin;
private static VillagerTradingListener listener;
private static ServerMock server;
@BeforeAll
public static void load() {
server = MockBukkit.mock();
plugin = MockBukkit.load(SlimefunPlugin.class);
listener = new VillagerTradingListener(plugin);
}
@AfterAll
public static void unload() {
MockBukkit.unmock();
}
private InventoryClickEvent mockClickEvent(ItemStack item) {
Player player = server.addPlayer();
Inventory inv = TestUtilities.mockInventory(InventoryType.MERCHANT);
Mockito.when(inv.getSize()).thenReturn(8);
InventoryView view = player.openInventory(inv);
view.setCursor(item);
InventoryClickEvent event = new InventoryClickEvent(view, SlotType.CONTAINER, 1, ClickType.LEFT, InventoryAction.PICKUP_ONE);
listener.onPreBrew(event);
return event;
}
@Test
void testTradingWithoutSlimefunItems() {
InventoryClickEvent event = mockClickEvent(new ItemStack(Material.EMERALD));
Assertions.assertEquals(Result.ALLOW, event.getResult());
}
@Test
void testTradingWithSlimefunItem() {
SlimefunItem item = TestUtilities.mockSlimefunItem(plugin, "MOCKED_FAKE_EMERALD", new CustomItem(Material.EMERALD, "&aFake Emerald"));
item.register(plugin);
InventoryClickEvent event = mockClickEvent(item.getItem());
Assertions.assertEquals(Result.DENY, event.getResult());
}
@Test
void testTradingWithVanillaItem() {
VanillaItem item = TestUtilities.mockVanillaItem(plugin, Material.EMERALD, true);
item.register(plugin);
InventoryClickEvent event = mockClickEvent(item.getItem());
Assertions.assertEquals(Result.ALLOW, event.getResult());
}
@Test
void testTradingWithSyntheticEmerald() {
Category category = TestUtilities.getCategory(plugin, "shiny_emeralds");
SlimefunItemStack stack = new SlimefunItemStack("FAKE_EMERALD", Material.EMERALD, "&aTrade me");
SyntheticEmerald item = new SyntheticEmerald(category, stack, RecipeType.ENHANCED_CRAFTING_TABLE, new ItemStack[9]);
item.register(plugin);
InventoryClickEvent event = mockClickEvent(item.getItem());
Assertions.assertEquals(Result.ALLOW, event.getResult());
}
}