mirror of
https://github.com/StarWishsama/Slimefun4.git
synced 2024-09-19 19:25:48 +00:00
Merge branch 'master' of https://github.com/Slimefun/Slimefun4.git into api/machine-operations
This commit is contained in:
commit
a249ca7848
6
.github/workflows/auto-approve.yml
vendored
6
.github/workflows/auto-approve.yml
vendored
@ -1,7 +1,6 @@
|
||||
name: Auto approve
|
||||
|
||||
on:
|
||||
pull_request
|
||||
on: pull_request
|
||||
|
||||
jobs:
|
||||
auto-approve:
|
||||
@ -9,6 +8,9 @@ jobs:
|
||||
name: Auto approve Pull Request
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
## Only run this on the main repo
|
||||
if: github.event.pull_request.head.repo.full_name == 'Slimefun/Slimefun4'
|
||||
|
||||
steps:
|
||||
- name: Approve via actions
|
||||
uses: hmarr/auto-approve-action@v2.1.0
|
||||
|
15
.github/workflows/auto-squash.yml
vendored
15
.github/workflows/auto-squash.yml
vendored
@ -17,12 +17,17 @@ jobs:
|
||||
name: Auto squash
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
## Only run this on the main repo
|
||||
if: github.event.pull_request.head.repo.full_name == 'Slimefun/Slimefun4'
|
||||
|
||||
steps:
|
||||
- name: Auto squash
|
||||
uses: pascalgn/automerge-action@v0.13.1
|
||||
uses: pascalgn/automerge-action@v0.14.1
|
||||
env:
|
||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
MERGE_METHOD: "squash"
|
||||
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
|
||||
UPDATE_RETRIES: 0
|
||||
MERGE_METHOD: squash
|
||||
MERGE_FORKS: false
|
||||
MERGE_LABELS: "📄 Translations Update"
|
||||
MERGE_COMMIT_MESSAGE: "[CI skip] New locale updates from Crowdin"
|
||||
MERGE_DELETE_BRANCH: true
|
||||
MERGE_LABELS: '📄 Translations Update'
|
||||
MERGE_COMMIT_MESSAGE: '[CI skip] New locale updates from Crowdin'
|
||||
|
4
.github/workflows/discord-webhook.yml
vendored
4
.github/workflows/discord-webhook.yml
vendored
@ -12,13 +12,15 @@ jobs:
|
||||
|
||||
name: Discord Webhook
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
## Only run this on the main repo
|
||||
if: github.repository == 'Slimefun/Slimefun4'
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2.3.4
|
||||
- name: Set up Java JDK 11
|
||||
uses: actions/setup-java@v2.0.0
|
||||
uses: actions/setup-java@v2.1.0
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '11'
|
||||
|
2
.github/workflows/maven-compiler.yml
vendored
2
.github/workflows/maven-compiler.yml
vendored
@ -24,7 +24,7 @@ jobs:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v2.0.0
|
||||
uses: actions/setup-java@v2.1.0
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '8'
|
||||
|
28
CHANGELOG.md
28
CHANGELOG.md
@ -1,5 +1,6 @@
|
||||
# Table of contents
|
||||
- [Release Candidate 23 (TBD)](#release-candidate-23-tbd)
|
||||
- [Release Candidate 24 (TBD)](#release-candidate-24-tbd)
|
||||
- [Release Candidate 23 (19 May 2021)](#release-candidate-23-19-may-2021)
|
||||
- [Release Candidate 22 (18 Apr 2021)](#release-candidate-22-18-apr-2021)
|
||||
- [Release Candidate 21 (14 Mar 2021)](#release-candidate-21-14-mar-2021)
|
||||
- [Release Candidate 20 (30 Jan 2021)](#release-candidate-20-30-jan-2021)
|
||||
@ -23,7 +24,21 @@
|
||||
- [Release Candidate 2 (29 Sep 2019)](#release-candidate-2-29-sep-2019)
|
||||
- [Release Candidate 1 (26 Sep 2019)](#release-candidate-1-26-sep-2019)
|
||||
|
||||
## Release Candidate 23 (TBD)
|
||||
## Release Candidate 24 (TBD)
|
||||
|
||||
#### Additions
|
||||
* The speed of the Ancient Altar can now be configured in the `Items.yml` file
|
||||
|
||||
#### Changes
|
||||
|
||||
#### Fixes
|
||||
* Fixed #3064
|
||||
* Fixed #2964
|
||||
* Fixed #2979
|
||||
* Fixed a permissions issue with `/sf charge`
|
||||
|
||||
## Release Candidate 23 (19 May 2021)
|
||||
https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#23
|
||||
|
||||
#### Additions
|
||||
* Added "Quartz Block -> 4 Quartz" recipe to Grind Stone
|
||||
@ -35,8 +50,12 @@
|
||||
* Added "Ender Lump Tier 3 -> 4 Ender Lump Tier 2" recipe to Grind Stone
|
||||
* Added Tier 2 Auto-Enchanter
|
||||
* Added Tier 2 Auto-Disenchanter
|
||||
* (API) Added AsyncAutoEnchanterProcessEvent
|
||||
* (API) Added Category#setTier() to modify a category's position in the guide
|
||||
* Added the ability to disable auto (dis)enchanting with a lore - `use-ignored-lores` & `ignored-lores` in Items.yml
|
||||
* Added an option to turn off the "researching animation" in the `config.yml`
|
||||
* Added the option to turn off the "researching animation" within your Slimefun Guide
|
||||
* Added Portable Teleporter
|
||||
|
||||
#### Changes
|
||||
* Renamed "Solar Panel" to "Photovoltaic Cell" to avoid confusions with solar generators
|
||||
@ -47,6 +66,7 @@
|
||||
* (API) Removed deprecated "SlimefunBlockHandler"
|
||||
* (API) Refactored "Machine Process" API
|
||||
* Removed Automated Crafting Chamber
|
||||
* Memory and performance improvements for Cargo and Energy networks
|
||||
|
||||
#### Fixes
|
||||
* Fixed #2987
|
||||
@ -58,9 +78,13 @@
|
||||
* Fixed #2927
|
||||
* Fixed #3007
|
||||
* Fixed #3012
|
||||
* Fixed #3013
|
||||
* Fixed #3027
|
||||
* Fixed #2978
|
||||
* Fixed #3041
|
||||
* Fixed #3036
|
||||
* Possibly fixed #2927
|
||||
* Fixed #3060
|
||||
|
||||
## Release Candidate 22 (18 Apr 2021)
|
||||
https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#22
|
||||
|
12
pom.xml
12
pom.xml
@ -230,7 +230,7 @@
|
||||
<!-- Javadocs -->
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0</version>
|
||||
|
||||
<configuration>
|
||||
<reportOutputDirectory>${project.basedir}</reportOutputDirectory>
|
||||
@ -343,19 +343,19 @@
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>5.7.1</version>
|
||||
<version>5.7.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>3.9.0</version>
|
||||
<version>3.10.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.seeseemelk</groupId>
|
||||
<artifactId>MockBukkit-v1.16</artifactId>
|
||||
<version>0.34.2</version>
|
||||
<version>1.0.1</version>
|
||||
<scope>test</scope>
|
||||
|
||||
<exclusions>
|
||||
@ -370,7 +370,7 @@
|
||||
|
||||
<!-- Shaded packages -->
|
||||
<dependency>
|
||||
<groupId>com.github.TheBusyBiscuit</groupId>
|
||||
<groupId>com.github.thebusybiscuit</groupId>
|
||||
<artifactId>CS-CoreLib2</artifactId>
|
||||
<version>0.31.0</version>
|
||||
<scope>compile</scope>
|
||||
@ -470,7 +470,7 @@
|
||||
<dependency>
|
||||
<groupId>com.github.LoneDev6</groupId>
|
||||
<artifactId>itemsadder-api</artifactId>
|
||||
<version>2.3.3</version>
|
||||
<version>2.3.8</version>
|
||||
<scope>provided</scope>
|
||||
|
||||
<exclusions>
|
||||
|
@ -0,0 +1,92 @@
|
||||
package io.github.thebusybiscuit.slimefun4.api.events;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.enchanting.AutoEnchanter;
|
||||
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* An {@link Event} that is called whenever an {@link AutoEnchanter} is
|
||||
* enchanting an {@link ItemStack}.
|
||||
*
|
||||
* @author StarWishsama
|
||||
*/
|
||||
public class AsyncAutoEnchanterProcessEvent extends Event implements Cancellable {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
private final ItemStack item;
|
||||
private final ItemStack enchantedBook;
|
||||
private final BlockMenu menu;
|
||||
|
||||
private boolean cancelled;
|
||||
|
||||
public AsyncAutoEnchanterProcessEvent(@Nonnull ItemStack item, @Nonnull ItemStack enchantedBook, @Nonnull BlockMenu menu) {
|
||||
super(true);
|
||||
|
||||
Validate.notNull(item, "The item to enchant cannot be null!");
|
||||
Validate.notNull(enchantedBook, "The enchanted book to enchant cannot be null!");
|
||||
Validate.notNull(menu, "The menu of auto-enchanter cannot be null!");
|
||||
|
||||
this.item = item;
|
||||
this.enchantedBook = enchantedBook;
|
||||
this.menu = menu;
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the {@link ItemStack} that is being enchanted.
|
||||
*
|
||||
* @return The {@link ItemStack} that is being enchanted
|
||||
*/
|
||||
@Nonnull
|
||||
public ItemStack getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the {@link ItemStack} that is being used enchanted book
|
||||
*
|
||||
* @return The {@link ItemStack} that is being used enchanted book
|
||||
*/
|
||||
@Nonnull
|
||||
public ItemStack getEnchantedBook() {
|
||||
return enchantedBook;
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the {@link AutoEnchanter}'s {@link BlockMenu}
|
||||
*
|
||||
* @return The {@link BlockMenu} of {@link AutoEnchanter} that is enchanting item
|
||||
*/
|
||||
@Nonnull
|
||||
public BlockMenu getMenu() {
|
||||
return menu;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return getHandlerList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancelled = cancel;
|
||||
}
|
||||
}
|
@ -51,12 +51,24 @@ public final class TeleportationManager {
|
||||
*/
|
||||
private final Set<UUID> teleporterUsers = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Opens the GUI of the teleporter and calculates the network complexity of the {@link Player}
|
||||
*
|
||||
* @param p {@link Player} to be teleported
|
||||
* @param ownerUUID {@link UUID} of the {@link Player} who owns the teleporter device
|
||||
* @param b {@link Block} from where the {@link Player} is being teleported
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
public void openTeleporterGUI(Player p, UUID uuid, Block b, int complexity) {
|
||||
public void openTeleporterGUI(Player p, UUID ownerUUID, Block b) {
|
||||
openTeleporterGUI(p, ownerUUID, b, SlimefunPlugin.getGPSNetwork().getNetworkComplexity(ownerUUID));
|
||||
}
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
public void openTeleporterGUI(Player p, UUID ownerUUID, Block b, int complexity) {
|
||||
if (teleporterUsers.add(p.getUniqueId())) {
|
||||
p.playSound(p.getLocation(), Sound.UI_BUTTON_CLICK, 1F, 1F);
|
||||
|
||||
PlayerProfile.fromUUID(uuid, profile -> {
|
||||
PlayerProfile.fromUUID(ownerUUID, profile -> {
|
||||
ChestMenu menu = new ChestMenu("&3Teleporter");
|
||||
menu.addMenuCloseHandler(pl -> teleporterUsers.remove(pl.getUniqueId()));
|
||||
|
||||
|
@ -4,14 +4,18 @@ import java.util.ArrayDeque;
|
||||
import java.util.HashSet;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.World;
|
||||
|
||||
import io.github.thebusybiscuit.cscorelib2.blocks.BlockPosition;
|
||||
import io.github.thebusybiscuit.slimefun4.core.networks.NetworkManager;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.listeners.NetworkListener;
|
||||
@ -20,6 +24,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.NetworkListen
|
||||
* An abstract Network class to manage networks in a stateful way
|
||||
*
|
||||
* @author meiamsome
|
||||
* @author TheBusyBiscuit
|
||||
*
|
||||
* @see NetworkListener
|
||||
* @see NetworkManager
|
||||
@ -37,8 +42,19 @@ public abstract class Network {
|
||||
*/
|
||||
protected Location regulator;
|
||||
|
||||
/**
|
||||
* The {@link UUID} of the {@link World} this {@link Network} exists within.
|
||||
*/
|
||||
private final UUID worldId;
|
||||
|
||||
/**
|
||||
* This {@link Set} holds all {@link Network} positions that are part of this {@link Network}.
|
||||
* The {@link World} should be equal for all positions, therefore we can save memory by simply
|
||||
* storing {@link BlockPosition#getAsLong(int, int, int)}.
|
||||
*/
|
||||
private final Set<Long> positions = new HashSet<>();
|
||||
|
||||
private final Queue<Location> nodeQueue = new ArrayDeque<>();
|
||||
protected final Set<Location> connectedLocations = new HashSet<>();
|
||||
protected final Set<Location> regulatorNodes = new HashSet<>();
|
||||
protected final Set<Location> connectorNodes = new HashSet<>();
|
||||
protected final Set<Location> terminusNodes = new HashSet<>();
|
||||
@ -57,8 +73,9 @@ public abstract class Network {
|
||||
|
||||
this.manager = manager;
|
||||
this.regulator = regulator;
|
||||
this.worldId = regulator.getWorld().getUID();
|
||||
|
||||
connectedLocations.add(regulator);
|
||||
positions.add(BlockPosition.getAsLong(regulator));
|
||||
nodeQueue.add(regulator.clone());
|
||||
}
|
||||
|
||||
@ -115,7 +132,10 @@ public abstract class Network {
|
||||
* The {@link Location} to add
|
||||
*/
|
||||
protected void addLocationToNetwork(@Nonnull Location l) {
|
||||
if (connectedLocations.add(l.clone())) {
|
||||
Validate.notNull(l, "You cannot add a Location to a Network which is null!");
|
||||
Validate.isTrue(l.getWorld().getUID().equals(worldId), "Networks cannot exist in multiple worlds!");
|
||||
|
||||
if (positions.add(BlockPosition.getAsLong(l))) {
|
||||
markDirty(l);
|
||||
}
|
||||
}
|
||||
@ -144,10 +164,14 @@ public abstract class Network {
|
||||
* @return Whether the given {@link Location} is part of this {@link Network}
|
||||
*/
|
||||
public boolean connectsTo(@Nonnull Location l) {
|
||||
if (regulator.equals(l)) {
|
||||
Validate.notNull(l, "The Location cannot be null.");
|
||||
|
||||
if (this.regulator.equals(l)) {
|
||||
return true;
|
||||
} else if (!l.getWorld().getUID().equals(this.worldId)) {
|
||||
return false;
|
||||
} else {
|
||||
return connectedLocations.contains(l);
|
||||
return positions.contains(BlockPosition.getAsLong(l));
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,7 +249,8 @@ public abstract class Network {
|
||||
*/
|
||||
public void display() {
|
||||
if (manager.isVisualizerEnabled()) {
|
||||
SlimefunPlugin.runSync(new NetworkVisualizer(this));
|
||||
// TODO: Make Color configurable / network-dependent
|
||||
SlimefunPlugin.runSync(new NetworkVisualizer(this, Color.BLUE));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package io.github.thebusybiscuit.slimefun4.api.network;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Particle;
|
||||
@ -18,7 +19,7 @@ class NetworkVisualizer implements Runnable {
|
||||
/**
|
||||
* The {@link DustOptions} define the {@link Color} and size of our particles.
|
||||
*/
|
||||
private final DustOptions options = new DustOptions(Color.BLUE, 3.5F);
|
||||
private final DustOptions particleOptions;
|
||||
|
||||
/**
|
||||
* This is our {@link Network} instance.
|
||||
@ -31,8 +32,12 @@ class NetworkVisualizer implements Runnable {
|
||||
* @param network
|
||||
* The {@link Network} to visualize
|
||||
*/
|
||||
NetworkVisualizer(@Nonnull Network network) {
|
||||
NetworkVisualizer(@Nonnull Network network, @Nonnull Color color) {
|
||||
Validate.notNull(network, "The network should not be null.");
|
||||
Validate.notNull(color, "The color cannot be null.");
|
||||
|
||||
this.network = network;
|
||||
this.particleOptions = new DustOptions(color, 3F);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -53,7 +58,7 @@ class NetworkVisualizer implements Runnable {
|
||||
* The {@link Location} of our node
|
||||
*/
|
||||
private void spawnParticles(@Nonnull Location l) {
|
||||
l.getWorld().spawnParticle(Particle.REDSTONE, l.getX() + 0.5, l.getY() + 0.5, l.getZ() + 0.5, 1, 0, 0, 0, 1, options);
|
||||
l.getWorld().spawnParticle(Particle.REDSTONE, l.getX() + 0.5, l.getY() + 0.5, l.getZ() + 0.5, 1, 0, 0, 0, 1, particleOptions);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -69,6 +69,7 @@ public final class SlimefunRegistry {
|
||||
private boolean enableResearches;
|
||||
private boolean freeCreativeResearches;
|
||||
private boolean researchFireworks;
|
||||
private boolean disableLearningAnimation;
|
||||
private boolean logDuplicateBlockEntries;
|
||||
private boolean talismanActionBarMessages;
|
||||
|
||||
@ -109,6 +110,7 @@ public final class SlimefunRegistry {
|
||||
backwardsCompatibility = cfg.getBoolean("options.backwards-compatibility");
|
||||
freeCreativeResearches = cfg.getBoolean("researches.free-in-creative-mode");
|
||||
researchFireworks = cfg.getBoolean("researches.enable-fireworks");
|
||||
disableLearningAnimation = cfg.getBoolean("researches.disable-learning-animation");
|
||||
logDuplicateBlockEntries = cfg.getBoolean("options.log-duplicate-block-entries");
|
||||
talismanActionBarMessages = cfg.getBoolean("talismans.use-actionbar");
|
||||
}
|
||||
@ -238,6 +240,15 @@ public final class SlimefunRegistry {
|
||||
return researchFireworks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the research learning animations is disabled
|
||||
*
|
||||
* @return Whether the research learning animations is disabled
|
||||
*/
|
||||
public boolean isLearningAnimationDisabled() {
|
||||
return disableLearningAnimation;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a {@link List} of every enabled {@link MultiBlock}.
|
||||
*
|
||||
|
@ -1,5 +1,7 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.commands.subcommands;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@ -11,10 +13,22 @@ import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
|
||||
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.RestoredBackpack;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
|
||||
|
||||
/**
|
||||
* This command that allows for backpack retrieval in the event they are lost.
|
||||
* The command accepts a name and id, if those match up it spawns a Medium Backpack
|
||||
* with the correct lore set in the sender's inventory.
|
||||
*
|
||||
* @author Sfiguz7
|
||||
*
|
||||
* @see RestoredBackpack
|
||||
*
|
||||
*/
|
||||
class BackpackCommand extends SubCommand {
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
BackpackCommand(SlimefunPlugin plugin, SlimefunCommand cmd) {
|
||||
super(plugin, cmd, "backpack", false);
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.commands.subcommands;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -19,6 +21,7 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||
*/
|
||||
class ChargeCommand extends SubCommand {
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
ChargeCommand(SlimefunPlugin plugin, SlimefunCommand cmd) {
|
||||
super(plugin, cmd, "charge", false);
|
||||
}
|
||||
@ -31,10 +34,11 @@ class ChargeCommand extends SubCommand {
|
||||
@Override
|
||||
public void onExecute(CommandSender sender, String[] args) {
|
||||
if (sender instanceof Player) {
|
||||
if (sender.hasPermission("slimefun.charge.command")) {
|
||||
if (sender.hasPermission("slimefun.command.charge")) {
|
||||
Player p = (Player) sender;
|
||||
ItemStack item = p.getInventory().getItemInMainHand();
|
||||
SlimefunItem slimefunItem = SlimefunItem.getByItem(item);
|
||||
|
||||
if (slimefunItem instanceof Rechargeable) {
|
||||
Rechargeable rechargeableItem = (Rechargeable) slimefunItem;
|
||||
rechargeableItem.setItemCharge(item, rechargeableItem.getMaxItemCharge(item));
|
||||
|
@ -1,5 +1,7 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.commands.subcommands;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@ -10,6 +12,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
|
||||
class CheatCommand extends SubCommand {
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
CheatCommand(SlimefunPlugin plugin, SlimefunCommand cmd) {
|
||||
super(plugin, cmd, "cheat", false);
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.commands.subcommands;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@ -10,6 +12,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
|
||||
class DebugFishCommand extends SubCommand {
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
DebugFishCommand(SlimefunPlugin plugin, SlimefunCommand cmd) {
|
||||
super(plugin, cmd, "debug_fish", true);
|
||||
}
|
||||
|
@ -16,12 +16,15 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
class GiveCommand extends SubCommand {
|
||||
|
||||
private static final String PLACEHOLDER_PLAYER = "%player%";
|
||||
private static final String PLACEHOLDER_ITEM = "%item%";
|
||||
private static final String PLACEHOLDER_AMOUNT = "%amount%";
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
GiveCommand(SlimefunPlugin plugin, SlimefunCommand cmd) {
|
||||
super(plugin, cmd, "give", false);
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.commands.subcommands;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@ -11,6 +13,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
|
||||
class GuideCommand extends SubCommand {
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
GuideCommand(SlimefunPlugin plugin, SlimefunCommand cmd) {
|
||||
super(plugin, cmd, "guide", false);
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.commands.subcommands;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
|
||||
@ -8,6 +10,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
|
||||
class HelpCommand extends SubCommand {
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
HelpCommand(SlimefunPlugin plugin, SlimefunCommand cmd) {
|
||||
super(plugin, cmd, "help", false);
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
|
||||
class OpenGuideCommand extends SubCommand {
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
OpenGuideCommand(SlimefunPlugin plugin, SlimefunCommand cmd) {
|
||||
super(plugin, cmd, "open_guide", false);
|
||||
}
|
||||
|
@ -3,6 +3,9 @@ package io.github.thebusybiscuit.slimefun4.core.commands.subcommands;
|
||||
import java.util.Optional;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@ -18,6 +21,7 @@ class ResearchCommand extends SubCommand {
|
||||
private static final String PLACEHOLDER_PLAYER = "%player%";
|
||||
private static final String PLACEHOLDER_RESEARCH = "%research%";
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
ResearchCommand(SlimefunPlugin plugin, SlimefunCommand cmd) {
|
||||
super(plugin, cmd, "research", false);
|
||||
}
|
||||
@ -57,6 +61,7 @@ class ResearchCommand extends SubCommand {
|
||||
}
|
||||
}
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
private void giveResearch(CommandSender sender, Player p, String input) {
|
||||
Optional<Research> research = getResearchFromString(input);
|
||||
|
||||
@ -70,6 +75,7 @@ class ResearchCommand extends SubCommand {
|
||||
}
|
||||
}
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
private void researchAll(CommandSender sender, PlayerProfile profile, Player p) {
|
||||
for (Research res : SlimefunPlugin.getRegistry().getResearches()) {
|
||||
if (!profile.hasUnlocked(res)) {
|
||||
@ -80,6 +86,7 @@ class ResearchCommand extends SubCommand {
|
||||
}
|
||||
}
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
private void reset(PlayerProfile profile, Player p) {
|
||||
for (Research research : SlimefunPlugin.getRegistry().getResearches()) {
|
||||
profile.setResearched(research, false);
|
||||
@ -88,7 +95,8 @@ class ResearchCommand extends SubCommand {
|
||||
SlimefunPlugin.getLocalization().sendMessage(p, "commands.research.reset", true, msg -> msg.replace(PLACEHOLDER_PLAYER, p.getName()));
|
||||
}
|
||||
|
||||
private Optional<Research> getResearchFromString(String input) {
|
||||
@Nonnull
|
||||
private Optional<Research> getResearchFromString(@Nonnull String input) {
|
||||
if (!input.contains(":")) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package io.github.thebusybiscuit.slimefun4.core.commands.subcommands;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@ -14,6 +16,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
|
||||
class SearchCommand extends SubCommand {
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
SearchCommand(SlimefunPlugin plugin, SlimefunCommand cmd) {
|
||||
super(plugin, cmd, "search", false);
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand;
|
||||
import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
@ -20,7 +22,8 @@ public final class SlimefunSubCommands {
|
||||
|
||||
private SlimefunSubCommands() {}
|
||||
|
||||
public static Collection<SubCommand> getAllCommands(SlimefunCommand cmd) {
|
||||
@Nonnull
|
||||
public static Collection<SubCommand> getAllCommands(@Nonnull SlimefunCommand cmd) {
|
||||
SlimefunPlugin plugin = cmd.getPlugin();
|
||||
List<SubCommand> commands = new LinkedList<>();
|
||||
|
||||
|
@ -2,6 +2,8 @@ package io.github.thebusybiscuit.slimefun4.core.commands.subcommands;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -14,6 +16,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
|
||||
class StatsCommand extends SubCommand {
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
StatsCommand(SlimefunPlugin plugin, SlimefunCommand cmd) {
|
||||
super(plugin, cmd, "stats", false);
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.commands.subcommands;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.block.BlockFace;
|
||||
@ -12,6 +14,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
|
||||
class TeleporterCommand extends SubCommand {
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
TeleporterCommand(SlimefunPlugin plugin, SlimefunCommand cmd) {
|
||||
super(plugin, cmd, "teleporter", false);
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ class TimingsCommand extends SubCommand {
|
||||
private static final String FLAG_PREFIX = "--";
|
||||
private final Set<String> flags = new HashSet<>(Arrays.asList("verbose"));
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
TimingsCommand(SlimefunPlugin plugin, SlimefunCommand cmd) {
|
||||
super(plugin, cmd, "timings", false);
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package io.github.thebusybiscuit.slimefun4.core.commands.subcommands;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@ -29,6 +30,7 @@ import net.md_5.bungee.api.chat.hover.content.Text;
|
||||
*/
|
||||
class VersionsCommand extends SubCommand {
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
VersionsCommand(SlimefunPlugin plugin, SlimefunCommand cmd) {
|
||||
super(plugin, cmd, "versions", false);
|
||||
}
|
||||
|
@ -3,12 +3,14 @@ package io.github.thebusybiscuit.slimefun4.core.guide;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
|
||||
import io.github.thebusybiscuit.slimefun4.core.guide.options.SlimefunGuideSettings;
|
||||
import io.github.thebusybiscuit.slimefun4.core.researching.Research;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.guide.SurvivalSlimefunGuide;
|
||||
@ -18,7 +20,7 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||
/**
|
||||
* This interface is used for the different implementations that add behaviour
|
||||
* to the {@link SlimefunGuide}.
|
||||
*
|
||||
*
|
||||
* @author TheBusyBiscuit
|
||||
*
|
||||
* @see SlimefunGuideMode
|
||||
@ -30,7 +32,7 @@ public interface SlimefunGuideImplementation {
|
||||
/**
|
||||
* Every {@link SlimefunGuideImplementation} can be associated with a
|
||||
* {@link SlimefunGuideMode}.
|
||||
*
|
||||
*
|
||||
* @return The mode this {@link SlimefunGuideImplementation} represents
|
||||
*/
|
||||
@Nonnull
|
||||
@ -40,22 +42,28 @@ public interface SlimefunGuideImplementation {
|
||||
* Returns the {@link ItemStack} representation for this {@link SlimefunGuideImplementation}.
|
||||
* In other words: The {@link ItemStack} you hold in your hand and that you use to
|
||||
* open your {@link SlimefunGuide}
|
||||
*
|
||||
*
|
||||
* @return The {@link ItemStack} representation for this {@link SlimefunGuideImplementation}
|
||||
*/
|
||||
@Nonnull
|
||||
ItemStack getItem();
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
void openMainMenu(PlayerProfile profile, int page);
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
void openCategory(PlayerProfile profile, Category category, int page);
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
void openSearch(PlayerProfile profile, String input, boolean addToHistory);
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
void displayItem(PlayerProfile profile, ItemStack item, int index, boolean addToHistory);
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
void displayItem(PlayerProfile profile, SlimefunItem item, boolean addToHistory);
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
default void unlockItem(Player p, SlimefunItem sfitem, Consumer<Player> callback) {
|
||||
Research research = sfitem.getResearch();
|
||||
|
||||
@ -63,7 +71,9 @@ public interface SlimefunGuideImplementation {
|
||||
research.unlock(p, true, callback);
|
||||
} else {
|
||||
p.setLevel(p.getLevel() - research.getCost());
|
||||
research.unlock(p, false, callback);
|
||||
|
||||
boolean skipLearningAnimation = SlimefunPlugin.getRegistry().isLearningAnimationDisabled() || !SlimefunGuideSettings.hasLearningAnimationEnabled(p);
|
||||
research.unlock(p, skipLearningAnimation, callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,74 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.guide.options;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import io.github.thebusybiscuit.cscorelib2.data.PersistentDataAPI;
|
||||
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
|
||||
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
|
||||
/**
|
||||
* {@link LearningAnimationOption} represents a setting in the Slimefun guide book.
|
||||
* It allows users to disable/enable the "learning animation",
|
||||
* the information in chat when doing a Slimefun research.
|
||||
*
|
||||
* @author martinbrom
|
||||
*/
|
||||
class LearningAnimationOption implements SlimefunGuideOption<Boolean> {
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public SlimefunAddon getAddon() {
|
||||
return SlimefunPlugin.instance();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public NamespacedKey getKey() {
|
||||
return new NamespacedKey(SlimefunPlugin.instance(), "research_learning_animation");
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Optional<ItemStack> getDisplayItem(@Nonnull Player p, @Nonnull ItemStack guide) {
|
||||
if (SlimefunPlugin.getRegistry().isLearningAnimationDisabled()) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
boolean enabled = getSelectedOption(p, guide).orElse(true);
|
||||
String optionState = enabled ? "enabled" : "disabled";
|
||||
List<String> lore = SlimefunPlugin.getLocalization().getMessages(p, "guide.options.learning-animation." + optionState + ".text");
|
||||
lore.add("");
|
||||
lore.add("&7\u21E8 " + SlimefunPlugin.getLocalization().getMessage(p, "guide.options.learning-animation." + optionState + ".click"));
|
||||
|
||||
ItemStack item = new CustomItem(enabled ? Material.MAP : Material.PAPER, lore);
|
||||
return Optional.of(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(@Nonnull Player p, @Nonnull ItemStack guide) {
|
||||
setSelectedOption(p, guide, !getSelectedOption(p, guide).orElse(true));
|
||||
SlimefunGuideSettings.openSettings(p, guide);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Boolean> getSelectedOption(@Nonnull Player p, @Nonnull ItemStack guide) {
|
||||
NamespacedKey key = getKey();
|
||||
boolean value = !PersistentDataAPI.hasByte(p, key) || PersistentDataAPI.getByte(p, key) == (byte) 1;
|
||||
return Optional.of(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelectedOption(@Nonnull Player p, @Nonnull ItemStack guide, @Nonnull Boolean value) {
|
||||
PersistentDataAPI.setByte(p, getKey(), (byte) (value.booleanValue() ? 1 : 0));
|
||||
}
|
||||
|
||||
}
|
@ -47,6 +47,7 @@ public final class SlimefunGuideSettings {
|
||||
static {
|
||||
options.add(new GuideModeOption());
|
||||
options.add(new FireworksOption());
|
||||
options.add(new LearningAnimationOption());
|
||||
options.add(new PlayerLanguageOption());
|
||||
}
|
||||
|
||||
@ -238,15 +239,51 @@ public final class SlimefunGuideSettings {
|
||||
* @return Whether this {@link Player} wants to see fireworks when unlocking a {@link Research}
|
||||
*/
|
||||
public static boolean hasFireworksEnabled(@Nonnull Player p) {
|
||||
return getOptionValue(p, FireworksOption.class, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks if the given {@link Player} has enabled the {@link LearningAnimationOption}
|
||||
* in their {@link SlimefunGuide}.
|
||||
* If they enabled this setting, they will see messages in chat about the progress of their {@link Research}.
|
||||
*
|
||||
* @param p
|
||||
* The {@link Player}
|
||||
*
|
||||
* @return Whether this {@link Player} wants to info messages in chat when unlocking a {@link Research}
|
||||
*/
|
||||
public static boolean hasLearningAnimationEnabled(@Nonnull Player p) {
|
||||
return getOptionValue(p, LearningAnimationOption.class, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to get the value of a {@link SlimefunGuideOption} that the {@link Player}
|
||||
* has set in their {@link SlimefunGuide}
|
||||
*
|
||||
* @param p
|
||||
* The {@link Player}
|
||||
* @param optionsClass
|
||||
* Class of the {@link SlimefunGuideOption} to get the value of
|
||||
* @param defaultValue
|
||||
* Default value to return in case the option is not found at all or has no value set
|
||||
* @param <T>
|
||||
* Type of the {@link SlimefunGuideOption}
|
||||
* @param <V>
|
||||
* Type of the {@link SlimefunGuideOption} value
|
||||
*
|
||||
* @return The value of given {@link SlimefunGuideOption}
|
||||
*/
|
||||
@Nonnull
|
||||
private static <T extends SlimefunGuideOption<V>, V> V getOptionValue(@Nonnull Player p, @Nonnull Class<T> optionsClass, @Nonnull V defaultValue) {
|
||||
for (SlimefunGuideOption<?> option : options) {
|
||||
if (option instanceof FireworksOption) {
|
||||
FireworksOption fireworks = (FireworksOption) option;
|
||||
if (optionsClass.isInstance(option)) {
|
||||
T o = optionsClass.cast(option);
|
||||
ItemStack guide = SlimefunGuide.getItem(SlimefunGuideMode.SURVIVAL_MODE);
|
||||
return fireworks.getSelectedOption(p, guide).orElse(true);
|
||||
return o.getSelectedOption(p, guide).orElse(defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.networks;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
@ -12,16 +14,21 @@ import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import io.github.thebusybiscuit.cscorelib2.blocks.BlockPosition;
|
||||
import io.github.thebusybiscuit.cscorelib2.config.Config;
|
||||
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
|
||||
import io.github.thebusybiscuit.slimefun4.api.network.Network;
|
||||
import io.github.thebusybiscuit.slimefun4.core.networks.cargo.CargoNet;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.listeners.NetworkListener;
|
||||
import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
||||
|
||||
/**
|
||||
* The {@link NetworkManager} is responsible for holding all instances of {@link Network}
|
||||
* and providing some utility methods that would have probably been static otherwise.
|
||||
*
|
||||
* @author TheBusyBiscuit
|
||||
* @author meiamsome
|
||||
*
|
||||
* @see Network
|
||||
* @see NetworkListener
|
||||
@ -32,7 +39,16 @@ public class NetworkManager {
|
||||
private final int maxNodes;
|
||||
private final boolean enableVisualizer;
|
||||
private final boolean deleteExcessItems;
|
||||
private final List<Network> networks = new LinkedList<>();
|
||||
|
||||
/**
|
||||
* Fixes #3041
|
||||
*
|
||||
* We use a {@link CopyOnWriteArrayList} here to ensure thread-safety.
|
||||
* This {@link List} is also much more frequently read than being written to.
|
||||
* Therefore a {@link CopyOnWriteArrayList} should be perfect for this, even
|
||||
* if insertions come at a slight cost.
|
||||
*/
|
||||
private final List<Network> networks = new CopyOnWriteArrayList<>();
|
||||
|
||||
/**
|
||||
* This creates a new {@link NetworkManager} with the given capacity.
|
||||
@ -93,12 +109,13 @@ public class NetworkManager {
|
||||
|
||||
/**
|
||||
* This returns a {@link List} of every {@link Network} on the {@link Server}.
|
||||
* The returned {@link List} is not modifiable.
|
||||
*
|
||||
* @return A {@link List} containing every {@link Network} on the {@link Server}
|
||||
*/
|
||||
@Nonnull
|
||||
public List<Network> getNetworkList() {
|
||||
return networks;
|
||||
return Collections.unmodifiableList(networks);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@ -169,11 +186,30 @@ public class NetworkManager {
|
||||
public void updateAllNetworks(@Nonnull Location l) {
|
||||
Validate.notNull(l, "The Location cannot be null");
|
||||
|
||||
// No need to create a sublist and loop through it if there are no Networks
|
||||
if (!networks.isEmpty()) {
|
||||
try {
|
||||
/*
|
||||
* No need to create a sublist and loop through it if
|
||||
* there aren't even any networks on the server.
|
||||
*/
|
||||
if (networks.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Only a Slimefun block can be part of a Network.
|
||||
* This check helps to speed up performance.
|
||||
*
|
||||
* (Skip for Unit Tests as they don't support block info yet)
|
||||
*/
|
||||
if (!BlockStorage.hasBlockInfo(l) && SlimefunPlugin.getMinecraftVersion() != MinecraftVersion.UNIT_TEST) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Network network : getNetworksFromLocation(l, Network.class)) {
|
||||
network.markDirty(l);
|
||||
}
|
||||
} catch (Exception x) {
|
||||
SlimefunPlugin.logger().log(Level.SEVERE, x, () -> "An Exception was thrown while causing a networks update @ " + new BlockPosition(l));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,6 +74,7 @@ class ContributionsConnector extends GitHubConnector {
|
||||
aliases.put("bverhoeven", "soczol");
|
||||
aliases.put("ramdon-person", "ramdon_person");
|
||||
aliases.put("NCBPFluffyBear", "FluffyBear_");
|
||||
aliases.put("martinbrom", "OneTime97");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -745,6 +745,7 @@ public final class SlimefunItems {
|
||||
public static final SlimefunItemStack GPS_TELEPORTATION_MATRIX = new SlimefunItemStack("GPS_TELEPORTATION_MATRIX", Material.IRON_BLOCK, "&bGPS Teleporter Matrix", "", "&fThis is your Teleporter's Main Component", "&fThis Matrix allows Players to choose from all", "&fWaypoints made by the Player who has placed", "&fthis Device.");
|
||||
public static final SlimefunItemStack GPS_ACTIVATION_DEVICE_SHARED = new SlimefunItemStack("GPS_ACTIVATION_DEVICE_SHARED", Material.STONE_PRESSURE_PLATE, "&fGPS Activation Device &3(Shared)", "", "&fPlace this onto a Teleportation Matrix", "&fand step onto this Plate to activate", "&fthe Teleportation Process");
|
||||
public static final SlimefunItemStack GPS_ACTIVATION_DEVICE_PERSONAL = new SlimefunItemStack("GPS_ACTIVATION_DEVICE_PERSONAL", Material.STONE_PRESSURE_PLATE, "&fGPS Activation Device &a(Personal)", "", "&fPlace this onto a Teleportation Matrix", "&fand step onto this Plate to activate", "&fthe Teleportation Process", "", "&fThis Version only allows the Person who", "&fplaced this Device to use it");
|
||||
public static final SlimefunItemStack PORTABLE_TELEPORTER = new SlimefunItemStack("PORTABLE_TELEPORTER", Material.COMPASS, "&bPortable Teleporter", "", "&fThis device allows you to teleport", "&fto your waypoints from anywhere", "", LoreBuilder.powerCharged(0, 50), "", "&eRight Click&7 to use");
|
||||
|
||||
public static final SlimefunItemStack ELEVATOR_PLATE = new SlimefunItemStack("ELEVATOR_PLATE", Material.STONE_PRESSURE_PLATE, "&bElevator Plate", "", "&fPlace an Elevator Plate on every floor", "&fand you will be able to teleport between them.", "", "&eRight Click this Block &7to name it");
|
||||
public static final SlimefunItemStack INFUSED_HOPPER = new SlimefunItemStack("INFUSED_HOPPER", Material.HOPPER, "&5Infused Hopper", "", "&fAutomatically picks up nearby Items in a 7x7x7", "&fRadius when placed.");
|
||||
|
@ -3,9 +3,14 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.altar;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.api.events.AncientAltarCraftEvent;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.settings.IntRangeSetting;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.listeners.AncientAltarListener;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.AncientAltarTask;
|
||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||
@ -17,41 +22,47 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||
* The {@link AncientAltar} is a multiblock structure.
|
||||
* The altar itself stands in the center, surrounded by {@link AncientPedestal Pedestals}, it is used
|
||||
* to craft various magical items.
|
||||
*
|
||||
*
|
||||
* @author TheBusyBiscuit
|
||||
*
|
||||
* @author martinbrom
|
||||
*
|
||||
* @see AncientAltarListener
|
||||
* @see AncientAltarTask
|
||||
* @see AncientAltarCraftEvent
|
||||
* @see AncientPedestal
|
||||
*
|
||||
*/
|
||||
public class AncientAltar extends SlimefunItem {
|
||||
|
||||
private final int speed;
|
||||
/**
|
||||
* This number represents a delay in ticks between two ritual steps.
|
||||
* The whole ritual process consists of 36 steps, an item is consumed every 4 steps (8 times)
|
||||
* and the output is spawned after the 36th step completes.
|
||||
*/
|
||||
private static final int DEFAULT_STEP_DELAY = 8;
|
||||
|
||||
private final List<AltarRecipe> recipes = new ArrayList<>();
|
||||
|
||||
public AncientAltar(Category category, int speed, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||
private final ItemSetting<Integer> stepDelay = new IntRangeSetting(this, "step-delay", 0, DEFAULT_STEP_DELAY, Integer.MAX_VALUE);
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
public AncientAltar(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||
super(category, item, recipeType, recipe);
|
||||
|
||||
if (speed < 1) {
|
||||
throw new IllegalArgumentException("The speed must be at least 1.");
|
||||
}
|
||||
|
||||
this.speed = speed;
|
||||
addItemSetting(stepDelay);
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the speed of this {@link AncientAltar}.
|
||||
* This number determines how much ticks happen inbetween a step in the ritual animation.
|
||||
* The default is 8 ticks.
|
||||
*
|
||||
* @return The speed of this {@link AncientAltar}
|
||||
* This returns the delay of this {@link AncientAltar}.
|
||||
* This number determines how many ticks happen in between a step in the ritual animation.
|
||||
* The default is {@value #DEFAULT_STEP_DELAY} ticks.
|
||||
*
|
||||
* @return The delay between two ritual steps of this {@link AncientAltar}
|
||||
*/
|
||||
public int getSpeed() {
|
||||
return speed;
|
||||
public int getStepDelay() {
|
||||
return stepDelay.getValue();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public List<AltarRecipe> getRecipes() {
|
||||
return recipes;
|
||||
}
|
||||
|
@ -684,7 +684,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
|
||||
|
||||
if ("false".equals(data.getString("paused"))) {
|
||||
BlockMenu menu = BlockStorage.getInventory(b);
|
||||
|
||||
|
||||
String fuelData = data.getString("fuel");
|
||||
float fuel = fuelData == null ? 0 : Float.parseFloat(fuelData);
|
||||
|
||||
|
@ -67,15 +67,16 @@ public class WoodcutterAndroid extends ProgrammableAndroid {
|
||||
private void breakLog(Block log, Block android, BlockMenu menu, BlockFace face) {
|
||||
ItemStack drop = new ItemStack(log.getType());
|
||||
|
||||
if (menu.fits(drop, getOutputSlots())) {
|
||||
menu.pushItem(drop, getOutputSlots());
|
||||
log.getWorld().playEffect(log.getLocation(), Effect.STEP_SOUND, log.getType());
|
||||
// We try to push the log into the android's inventory, but nothing happens if it does not fit
|
||||
menu.pushItem(drop, getOutputSlots());
|
||||
|
||||
if (log.getY() == android.getRelative(face).getY()) {
|
||||
replant(log);
|
||||
} else {
|
||||
log.setType(Material.AIR);
|
||||
}
|
||||
log.getWorld().playEffect(log.getLocation(), Effect.STEP_SOUND, log.getType());
|
||||
|
||||
// If the android just chopped the bottom log, we replant the appropriate sapling
|
||||
if (log.getY() == android.getRelative(face).getY()) {
|
||||
replant(log);
|
||||
} else {
|
||||
log.setType(Material.AIR);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,7 @@
|
||||
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.enchanting;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
|
||||
|
||||
import io.github.thebusybiscuit.cscorelib2.inventory.InvUtils;
|
||||
import io.github.thebusybiscuit.slimefun4.api.events.AsyncAutoEnchanterProcessEvent;
|
||||
import io.github.thebusybiscuit.slimefun4.api.events.AutoEnchantEvent;
|
||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||
@ -20,6 +9,16 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe;
|
||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The {@link AutoEnchanter}, in contrast to the {@link AutoDisenchanter}, adds
|
||||
@ -65,10 +64,10 @@ public class AutoEnchanter extends AbstractEnchantmentMachine {
|
||||
return null;
|
||||
}
|
||||
|
||||
ItemStack secondItem = menu.getItemInSlot(slot);
|
||||
ItemStack enchantedBook = menu.getItemInSlot(slot);
|
||||
|
||||
if (secondItem != null && secondItem.getType() == Material.ENCHANTED_BOOK) {
|
||||
return enchant(menu, item, secondItem);
|
||||
if (enchantedBook != null && enchantedBook.getType() == Material.ENCHANTED_BOOK) {
|
||||
return enchant(menu, item, enchantedBook);
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,6 +77,14 @@ public class AutoEnchanter extends AbstractEnchantmentMachine {
|
||||
@Nullable
|
||||
@ParametersAreNonnullByDefault
|
||||
protected MachineRecipe enchant(BlockMenu menu, ItemStack target, ItemStack enchantedBook) {
|
||||
// Call an event so other Plugins can modify it.
|
||||
AsyncAutoEnchanterProcessEvent event = new AsyncAutoEnchanterProcessEvent(target, enchantedBook, menu);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
|
||||
if (event.isCancelled()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
EnchantmentStorageMeta meta = (EnchantmentStorageMeta) enchantedBook.getItemMeta();
|
||||
Map<Enchantment, Integer> enchantments = new HashMap<>();
|
||||
|
||||
|
@ -0,0 +1,61 @@
|
||||
package io.github.thebusybiscuit.slimefun4.implementation.items.teleporter;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
|
||||
import io.github.thebusybiscuit.slimefun4.api.items.settings.IntRangeSetting;
|
||||
import io.github.thebusybiscuit.slimefun4.core.attributes.Rechargeable;
|
||||
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
|
||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||
|
||||
/**
|
||||
* This item allows a {@link Player} to access and teleport to his waypoints
|
||||
* from anywhere.
|
||||
*
|
||||
* @author martinbrom
|
||||
*
|
||||
* @see Teleporter
|
||||
*/
|
||||
public class PortableTeleporter extends SimpleSlimefunItem<ItemUseHandler> implements Rechargeable {
|
||||
|
||||
private static final int CAPACITY = 50;
|
||||
private static final int DEFAULT_COST = 10;
|
||||
|
||||
private final ItemSetting<Integer> cost = new IntRangeSetting(this, "teleportation-cost", 0, DEFAULT_COST, CAPACITY);
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
public PortableTeleporter(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||
super(category, item, recipeType, recipe);
|
||||
|
||||
addItemSetting(cost);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemUseHandler getItemHandler() {
|
||||
return e -> {
|
||||
ItemStack item = e.getItem();
|
||||
e.cancel();
|
||||
|
||||
if (removeItemCharge(item, cost.getValue())) {
|
||||
Player p = e.getPlayer();
|
||||
SlimefunPlugin.getGPSNetwork().getTeleportationManager().openTeleporterGUI(
|
||||
p, p.getUniqueId(), p.getLocation().getBlock().getRelative(BlockFace.DOWN));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getMaxItemCharge(ItemStack item) {
|
||||
return CAPACITY;
|
||||
}
|
||||
}
|
@ -156,7 +156,14 @@ public class ExplosiveTool extends SimpleSlimefunItem<ToolUseHandler> implements
|
||||
*/
|
||||
BlockBreakEvent dummyEvent = new BlockBreakEvent(b, e.getPlayer());
|
||||
|
||||
if (!sfItem.callItemHandler(BlockBreakHandler.class, handler -> handler.onPlayerBreak(dummyEvent, item, drops)) && !dummyEvent.isCancelled()) {
|
||||
/*
|
||||
* Fixes #3036 and handling in general.
|
||||
* Call the BlockBreakHandler if the block has one to allow for proper handling.
|
||||
*/
|
||||
sfItem.callItemHandler(BlockBreakHandler.class, handler -> handler.onPlayerBreak(dummyEvent, item, drops));
|
||||
|
||||
// Make sure the event wasn't cancelled by the BlockBreakHandler.
|
||||
if (!dummyEvent.isCancelled()) {
|
||||
drops.addAll(sfItem.getDrops(p));
|
||||
b.setType(Material.AIR);
|
||||
BlockStorage.clearBlockInfo(b);
|
||||
|
@ -94,7 +94,9 @@ public class GoldPan extends SimpleSlimefunItem<ItemUseHandler> implements Recip
|
||||
randomizer.clear();
|
||||
|
||||
for (GoldPanDrop setting : drops) {
|
||||
randomizer.add(setting.getOutput(), setting.getValue());
|
||||
if (setting.getValue() > 0) {
|
||||
randomizer.add(setting.getOutput(), setting.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,11 +114,13 @@ public class GoldPan extends SimpleSlimefunItem<ItemUseHandler> implements Recip
|
||||
return item != null ? item : new ItemStack(Material.AIR);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getLabelLocalPath() {
|
||||
return "guide.tooltips.recipes.gold-pan";
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemUseHandler getItemHandler() {
|
||||
return e -> {
|
||||
@ -158,6 +162,7 @@ public class GoldPan extends SimpleSlimefunItem<ItemUseHandler> implements Recip
|
||||
};
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<ItemStack> getDisplayRecipes() {
|
||||
List<ItemStack> recipes = new LinkedList<>();
|
||||
|
@ -44,6 +44,7 @@ public class ExplosiveBow extends SlimefunBow {
|
||||
addItemSetting(range);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public BowShootHandler onShoot() {
|
||||
return (e, target) -> {
|
||||
|
@ -1,10 +1,12 @@
|
||||
package io.github.thebusybiscuit.slimefun4.implementation.items.weapons;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
@ -16,8 +18,9 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||
/**
|
||||
* The {@link IcyBow} is a special kind of bow which slows down any
|
||||
* {@link LivingEntity} it hits.
|
||||
*
|
||||
*
|
||||
* @author TheBusyBiscuit
|
||||
* @author martinbrom
|
||||
*
|
||||
*/
|
||||
public class IcyBow extends SlimefunBow {
|
||||
@ -27,9 +30,19 @@ public class IcyBow extends SlimefunBow {
|
||||
super(category, item, recipe);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public BowShootHandler onShoot() {
|
||||
return (e, n) -> {
|
||||
if (n instanceof Player) {
|
||||
Player p = (Player) n;
|
||||
|
||||
// Fixes #3060 - Don't apply effects if the arrow was successfully blocked.
|
||||
if (p.isBlocking() && e.getFinalDamage() <= 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
n.getWorld().playEffect(n.getLocation(), Effect.STEP_SOUND, Material.ICE);
|
||||
n.getWorld().playEffect(n.getEyeLocation(), Effect.STEP_SOUND, Material.ICE);
|
||||
n.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 20 * 2, 10));
|
||||
|
@ -225,7 +225,7 @@ public class AncientAltarListener implements Listener {
|
||||
|
||||
b.getWorld().playSound(b.getLocation(), Sound.ENTITY_ILLUSIONER_PREPARE_MIRROR, 1, 1);
|
||||
|
||||
AncientAltarTask task = new AncientAltarTask(this, b, altarItem.getSpeed(), result.get(), pedestals, consumed, p);
|
||||
AncientAltarTask task = new AncientAltarTask(this, b, altarItem.getStepDelay(), result.get(), pedestals, consumed, p);
|
||||
SlimefunPlugin.runSync(task, 10L);
|
||||
} else {
|
||||
altars.remove(b);
|
||||
|
@ -2,12 +2,14 @@ package io.github.thebusybiscuit.slimefun4.implementation.listeners;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
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.BlockPlaceEvent;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.api.events.ExplosiveToolBreakBlocksEvent;
|
||||
import io.github.thebusybiscuit.slimefun4.api.network.Network;
|
||||
import io.github.thebusybiscuit.slimefun4.core.networks.NetworkManager;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
@ -16,6 +18,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
* This {@link Listener} is responsible for all updates to a {@link Network}.
|
||||
*
|
||||
* @author meiamsome
|
||||
* @author TheBusyBiscuit
|
||||
*
|
||||
* @see Network
|
||||
* @see NetworkManager
|
||||
@ -23,6 +26,9 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
*/
|
||||
public class NetworkListener implements Listener {
|
||||
|
||||
/**
|
||||
* Our {@link NetworkManager} instance.
|
||||
*/
|
||||
private final NetworkManager manager;
|
||||
|
||||
public NetworkListener(@Nonnull SlimefunPlugin plugin, @Nonnull NetworkManager manager) {
|
||||
@ -39,4 +45,12 @@ public class NetworkListener implements Listener {
|
||||
public void onBlockPlace(BlockPlaceEvent e) {
|
||||
manager.updateAllNetworks(e.getBlock().getLocation());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onExplosiveToolUse(ExplosiveToolBreakBlocksEvent e) {
|
||||
// Fixes #3013 - Also update networks when using an explosive tool
|
||||
for (Block b : e.getAdditionalBlocks()) {
|
||||
manager.updateAllNetworks(b.getLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ public class TeleporterListener implements Listener {
|
||||
if (teleporter instanceof Teleporter && checkForPylons(b.getRelative(BlockFace.DOWN))) {
|
||||
Block block = b.getRelative(BlockFace.DOWN);
|
||||
UUID owner = UUID.fromString(BlockStorage.getLocationInfo(block.getLocation(), "owner"));
|
||||
SlimefunPlugin.getGPSNetwork().getTeleportationManager().openTeleporterGUI(p, owner, block, SlimefunPlugin.getGPSNetwork().getNetworkComplexity(owner));
|
||||
SlimefunPlugin.getGPSNetwork().getTeleportationManager().openTeleporterGUI(p, owner, block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -287,6 +287,7 @@ public final class ResearchSetup {
|
||||
register("improved_generators", 275, "Improved Generators", 24, SlimefunItems.COAL_GENERATOR_2, SlimefunItems.LAVA_GENERATOR_2);
|
||||
register("ingredients_and_cheese", 276, "Slimefun Cuisine", 5, SlimefunItems.SALT, SlimefunItems.WHEAT_FLOUR, SlimefunItems.HEAVY_CREAM, SlimefunItems.CHEESE, SlimefunItems.BUTTER);
|
||||
register("medium_tier_auto_enchanting", 277, "Fast Automatic Enchanting and Disenchanting", 48, SlimefunItems.AUTO_ENCHANTER_2, SlimefunItems.AUTO_DISENCHANTER_2);
|
||||
register("portable_teleporter", 278, "Teleportation from Anywhere", 42, SlimefunItems.PORTABLE_TELEPORTER);
|
||||
}
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
|
@ -182,6 +182,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.miner
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.seasonal.ChristmasPresent;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.seasonal.EasterEgg;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.teleporter.PersonalActivationPlate;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.teleporter.PortableTeleporter;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.teleporter.SharedActivationPlate;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.teleporter.Teleporter;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.teleporter.TeleporterPylon;
|
||||
@ -1492,7 +1493,7 @@ public final class SlimefunItemSetup {
|
||||
new SlimefunItemStack(SlimefunItems.ANCIENT_PEDESTAL, 4))
|
||||
.register(plugin);
|
||||
|
||||
new AncientAltar(categories.magicalGadgets, 8, SlimefunItems.ANCIENT_ALTAR, RecipeType.MAGIC_WORKBENCH,
|
||||
new AncientAltar(categories.magicalGadgets, SlimefunItems.ANCIENT_ALTAR, RecipeType.MAGIC_WORKBENCH,
|
||||
new ItemStack[] {null, new ItemStack(Material.ENCHANTING_TABLE), null, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.GOLD_8K, SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.OBSIDIAN), SlimefunItems.GOLD_8K, new ItemStack(Material.OBSIDIAN)})
|
||||
.register(plugin);
|
||||
|
||||
@ -2221,6 +2222,10 @@ public final class SlimefunItemSetup {
|
||||
new ItemStack[] {SlimefunItems.GPS_TELEPORTER_PYLON, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.GPS_TELEPORTER_PYLON, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.GPS_CONTROL_PANEL, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.GPS_TELEPORTER_PYLON, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.GPS_TELEPORTER_PYLON})
|
||||
.register(plugin);
|
||||
|
||||
new PortableTeleporter(categories.gps, SlimefunItems.PORTABLE_TELEPORTER, RecipeType.ENHANCED_CRAFTING_TABLE,
|
||||
new ItemStack[] {SlimefunItems.ELECTRO_MAGNET, SlimefunItems.GPS_TRANSMITTER_3, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.REINFORCED_PLATE, SlimefunItems.GPS_TELEPORTATION_MATRIX, SlimefunItems.REINFORCED_PLATE, SlimefunItems.BLISTERING_INGOT_3, SlimefunItems.MEDIUM_CAPACITOR, SlimefunItems.BLISTERING_INGOT_3})
|
||||
.register(plugin);
|
||||
|
||||
new SharedActivationPlate(categories.gps, SlimefunItems.GPS_ACTIVATION_DEVICE_SHARED, RecipeType.ENHANCED_CRAFTING_TABLE,
|
||||
new ItemStack[] {null, new ItemStack(Material.STONE_PRESSURE_PLATE), null, new ItemStack(Material.REDSTONE), SlimefunItems.GPS_TRANSMITTER, new ItemStack(Material.REDSTONE), SlimefunItems.BILLON_INGOT, SlimefunItems.BILLON_INGOT, SlimefunItems.BILLON_INGOT})
|
||||
.register(plugin);
|
||||
|
@ -46,7 +46,7 @@ public class AncientAltarTask implements Runnable {
|
||||
private final AncientPedestal pedestalItem = (AncientPedestal) SlimefunItems.ANCIENT_PEDESTAL.getItem();
|
||||
|
||||
private final Block altar;
|
||||
private final int speed;
|
||||
private final int stepDelay;
|
||||
private final Location dropLocation;
|
||||
private final ItemStack output;
|
||||
private final List<Block> pedestals;
|
||||
@ -60,10 +60,10 @@ public class AncientAltarTask implements Runnable {
|
||||
private final Player player;
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
public AncientAltarTask(AncientAltarListener listener, Block altar, int speed, ItemStack output, List<Block> pedestals, List<ItemStack> items, Player player) {
|
||||
public AncientAltarTask(AncientAltarListener listener, Block altar, int stepDelay, ItemStack output, List<Block> pedestals, List<ItemStack> items, Player player) {
|
||||
this.listener = listener;
|
||||
this.dropLocation = altar.getLocation().add(0.5, 1.3, 0.5);
|
||||
this.speed = speed;
|
||||
this.stepDelay = stepDelay;
|
||||
this.altar = altar;
|
||||
this.output = output;
|
||||
this.pedestals = pedestals;
|
||||
@ -102,7 +102,7 @@ public class AncientAltarTask implements Runnable {
|
||||
}
|
||||
|
||||
this.stage += 1;
|
||||
SlimefunPlugin.runSync(this, speed);
|
||||
SlimefunPlugin.runSync(this, stepDelay);
|
||||
}
|
||||
|
||||
private boolean checkLockedItems() {
|
||||
|
@ -59,6 +59,8 @@ public class BlockStorage {
|
||||
private final Map<String, Config> blocksCache = new ConcurrentHashMap<>();
|
||||
|
||||
private static int chunkChanges = 0;
|
||||
private static boolean chunksLoaded = false;
|
||||
private static boolean universalInventoriesLoaded = false;
|
||||
|
||||
private int changes = 0;
|
||||
private AtomicBoolean isMarkedForRemoval = new AtomicBoolean(false);
|
||||
@ -214,6 +216,12 @@ public class BlockStorage {
|
||||
}
|
||||
|
||||
private void loadChunks() {
|
||||
if (chunksLoaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
chunksLoaded = true;
|
||||
|
||||
File chunks = new File(PATH_CHUNKS + "chunks.sfc");
|
||||
|
||||
if (chunks.exists()) {
|
||||
@ -237,6 +245,12 @@ public class BlockStorage {
|
||||
if (file.getName().startsWith(world.getName()) && file.getName().endsWith(".sfi")) {
|
||||
try {
|
||||
Location l = deserializeLocation(file.getName().replace(".sfi", ""));
|
||||
|
||||
// We only want to only load this world's menus
|
||||
if (world != l.getWorld()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
io.github.thebusybiscuit.cscorelib2.config.Config cfg = new io.github.thebusybiscuit.cscorelib2.config.Config(file);
|
||||
BlockMenuPreset preset = BlockMenuPreset.getPreset(cfg.getString("preset"));
|
||||
|
||||
@ -253,6 +267,12 @@ public class BlockStorage {
|
||||
}
|
||||
}
|
||||
|
||||
if (universalInventoriesLoaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
universalInventoriesLoaded = true;
|
||||
|
||||
for (File file : new File("data-storage/Slimefun/universal-inventories").listFiles()) {
|
||||
if (file.getName().endsWith(".sfi")) {
|
||||
try {
|
||||
|
@ -1,84 +0,0 @@
|
||||
package me.mrCookieSlime.Slimefun.api;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||
|
||||
/**
|
||||
* Provides a few static convenience methods.
|
||||
*
|
||||
* @deprecated This class is slowly getting stripped away in favour of a more object-oriented approach.
|
||||
*
|
||||
* @author TheBusyBiscuit
|
||||
* @author Walshy
|
||||
* @author Poslovitch
|
||||
*/
|
||||
@Deprecated
|
||||
public final class Slimefun {
|
||||
|
||||
private Slimefun() {}
|
||||
|
||||
/**
|
||||
* Checks if this player has the permission to use this item.
|
||||
*
|
||||
* @param p
|
||||
* the player to check, not null
|
||||
* @param item
|
||||
* the item to check, null returns <code>true</code>
|
||||
* @param message
|
||||
* whether a message should be sent to the player or not
|
||||
*
|
||||
* @deprecated This method will soon be removed.
|
||||
*
|
||||
* @return <code>true</code> if the item is not null and if the player has the permission to use it,
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean hasPermission(Player p, SlimefunItem item, boolean message) {
|
||||
if (item == null) {
|
||||
return true;
|
||||
} else if (SlimefunPlugin.getPermissionsService().hasPermission(p, item)) {
|
||||
return true;
|
||||
} else {
|
||||
if (message) {
|
||||
SlimefunPlugin.getLocalization().sendMessage(p, "messages.no-permission", true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this item is enabled in the world this player is in.
|
||||
*
|
||||
* @param p
|
||||
* the player to get the world he is in, not null
|
||||
* @param sfItem
|
||||
* the item to check, not null
|
||||
* @param message
|
||||
* whether a message should be sent to the player or not
|
||||
*
|
||||
* @deprecated Please use {@link SlimefunItem#isDisabledIn(org.bukkit.World)} instead.
|
||||
*
|
||||
* @return <code>true</code> if the item is enabled in the world the player is in,
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isEnabled(Player p, SlimefunItem sfItem, boolean message) {
|
||||
if (sfItem.isDisabled()) {
|
||||
if (message) {
|
||||
SlimefunPlugin.getLocalization().sendMessage(p, "messages.disabled-item", true);
|
||||
}
|
||||
|
||||
return false;
|
||||
} else if (!SlimefunPlugin.getWorldSettingsService().isEnabled(p.getWorld(), sfItem)) {
|
||||
if (message) {
|
||||
SlimefunPlugin.getLocalization().sendMessage(p, "messages.disabled-in-world", true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -86,6 +86,17 @@ public class DirtyChestMenu extends ChestMenu {
|
||||
return InvUtils.fits(toInventory(), new ItemStackWrapper(item), slots);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds given {@link ItemStack} to any of the given inventory slots.
|
||||
* Items will be added to the inventory slots based on their order in the function argument.
|
||||
* Items will be added either to any empty inventory slots or any partially filled slots, in which case
|
||||
* as many items as can fit will be added to that specific spot.
|
||||
*
|
||||
* @param item {@link ItemStack} to be added to the inventory
|
||||
* @param slots Numbers of slots to add the {@link ItemStack} to
|
||||
* @return {@link ItemStack} with any items that did not fit into the inventory
|
||||
* or null when everything had fit
|
||||
*/
|
||||
@Nullable
|
||||
public ItemStack pushItem(ItemStack item, int... slots) {
|
||||
if (item == null || item.getType() == Material.AIR) {
|
||||
|
@ -26,6 +26,7 @@ guide:
|
||||
researches:
|
||||
free-in-creative-mode: true
|
||||
enable-fireworks: true
|
||||
disable-learning-animation: false
|
||||
|
||||
URID:
|
||||
info-delay: 3000
|
||||
|
@ -75,6 +75,24 @@ guide:
|
||||
translations:
|
||||
name: '&aFehlt etwas?'
|
||||
lore: 'Klicke um eine Übersetzung hinzuzufügen'
|
||||
options:
|
||||
learning-animation:
|
||||
enabled:
|
||||
text:
|
||||
- '&bLern-Animation: &aAn'
|
||||
- ''
|
||||
- '&7Du kannst nun entscheiden, ob'
|
||||
- '&7du eine Animation beim Freischalten von'
|
||||
- '&7Items sehen wirst.'
|
||||
click: '&eKlicke um die Lern-Animation zu deaktivieren'
|
||||
disabled:
|
||||
text:
|
||||
- '&bLern-Animation: &4Aus'
|
||||
- ''
|
||||
- '&7Du kannst nun entscheiden, ob'
|
||||
- '&7du eine Animation beim Freischalten von'
|
||||
- '&7Items sehen wirst.'
|
||||
click: '&eKlicke um die Lern-Animation zu aktivieren'
|
||||
title:
|
||||
main: 'Slimefun-Handbuch'
|
||||
settings: 'Einstellungen & Infos'
|
||||
@ -139,6 +157,11 @@ messages:
|
||||
- ''
|
||||
- '&eLeft Click &7to temporarily disable the recipe'
|
||||
- '&eRight Click &7to remove this recipe'
|
||||
disabled:
|
||||
- '&cDieses Rezept ist momentan deaktiviert'
|
||||
- ''
|
||||
- '&eLeft Click &7to re-enable this recipe'
|
||||
- '&eRight Click &7to remove this recipe'
|
||||
talisman:
|
||||
anvil: '&a&oDein Talisman hat dein Werkzeug vor dem Zerfall gerettet'
|
||||
miner: '&a&oDein Talisman hat soeben die Drops verdoppelt'
|
||||
@ -197,6 +220,8 @@ messages:
|
||||
- '&7Always look on the bright side of life!'
|
||||
- '&7Ist das jetzt ein Keks, Cookie oder ein Biscuit?'
|
||||
- '&7Jetzt auch zuckerfrei!'
|
||||
pickaxe-of-the-seeker:
|
||||
no-ores: '&cEs konnten keine Erze in deiner Nähe gefunden werden!'
|
||||
machines:
|
||||
pattern-not-found: '&eEs tut mir leid, aber ich konnte kein passendes Rezept finden.'
|
||||
unknown-material: '&eEs tut mir leid, aber ich erkenne das Item in meinem Werfer nicht, probier ein anderes Item aus.'
|
||||
|
@ -91,6 +91,25 @@ guide:
|
||||
name: '&aIs something missing?'
|
||||
lore: 'Click to add your own translation'
|
||||
|
||||
options:
|
||||
learning-animation:
|
||||
enabled:
|
||||
text:
|
||||
- '&bLearning Animation: &aYes'
|
||||
- ''
|
||||
- '&7You can now toggle whether you'
|
||||
- '&7will see information about your pondering in chat'
|
||||
- '&7upon researching an item.'
|
||||
click: '&eClick to disable your learning animation'
|
||||
disabled:
|
||||
text:
|
||||
- '&bLearning Animation: &4No'
|
||||
- ''
|
||||
- '&7You can now toggle whether you'
|
||||
- '&7will see information about your pondering in chat'
|
||||
- '&7upon researching an item.'
|
||||
click: '&eClick to enable your learning animation'
|
||||
|
||||
title:
|
||||
main: 'Slimefun Guide'
|
||||
settings: 'Settings & Info'
|
||||
|
@ -255,3 +255,4 @@ slimefun:
|
||||
improved_generators: Improved Generators
|
||||
ingredients_and_cheese: Slimefun Cuisine
|
||||
medium_tier_auto_enchanting: Fast Automatic Enchanting and Disenchanting
|
||||
portable_teleporter: Teleportation from Anywhere
|
||||
|
@ -35,7 +35,7 @@ guide:
|
||||
languages: 'Izvēlies savu vēlamo valodu,'
|
||||
credits: 'Slimefun4 Ieguldītāji'
|
||||
credits:
|
||||
commit: "Ieguldījums"
|
||||
commit: 'Ieguldījums'
|
||||
commits: 'Ieguldījumi'
|
||||
profile-link: 'Spied, lai apmeklētu GitHub profilu'
|
||||
roles:
|
||||
|
Loading…
Reference in New Issue
Block a user