mirror of
https://github.com/StarWishsama/Slimefun4.git
synced 2024-09-20 11:45:51 +00:00
commit
bd461a6f88
11
.github/configs/yaml-linter.yml
vendored
11
.github/configs/yaml-linter.yml
vendored
@ -6,10 +6,13 @@ yaml-files:
|
|||||||
|
|
||||||
rules:
|
rules:
|
||||||
|
|
||||||
## A warning is sufficient here
|
## Don't warn for line lengths
|
||||||
line-length:
|
line-length: disable
|
||||||
max: 180
|
|
||||||
level: warning
|
truthy:
|
||||||
|
allowed-values: ['true', 'false']
|
||||||
|
## We don't want it to trigger for the 'on' in our workflows
|
||||||
|
check-keys: false
|
||||||
|
|
||||||
## We don't need indentation warnings
|
## We don't need indentation warnings
|
||||||
indentation: disable
|
indentation: disable
|
||||||
|
2
.github/workflows/discord-webhook.yml
vendored
2
.github/workflows/discord-webhook.yml
vendored
@ -16,7 +16,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v2.3.3
|
uses: actions/checkout@v2.3.4
|
||||||
- name: Set up Java JDK 11
|
- name: Set up Java JDK 11
|
||||||
uses: actions/setup-java@v1.4.3
|
uses: actions/setup-java@v1.4.3
|
||||||
with:
|
with:
|
||||||
|
2
.github/workflows/maven-compiler.yml
vendored
2
.github/workflows/maven-compiler.yml
vendored
@ -22,7 +22,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v1
|
uses: actions/checkout@v2
|
||||||
- name: Set up JDK 1.8
|
- name: Set up JDK 1.8
|
||||||
uses: actions/setup-java@master
|
uses: actions/setup-java@master
|
||||||
with:
|
with:
|
||||||
|
2
.github/workflows/update-changelog.yml
vendored
2
.github/workflows/update-changelog.yml
vendored
@ -16,7 +16,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: TOC Generator
|
- name: TOC Generator
|
||||||
uses: technote-space/toc-generator@v2.4.0
|
uses: technote-space/toc-generator@v2.6.1
|
||||||
with:
|
with:
|
||||||
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
|
||||||
TARGET_PATHS: 'CHANGELOG.md'
|
TARGET_PATHS: 'CHANGELOG.md'
|
||||||
|
4
.github/workflows/url-checker.yml
vendored
4
.github/workflows/url-checker.yml
vendored
@ -6,7 +6,7 @@ on:
|
|||||||
- master
|
- master
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
check:
|
||||||
|
|
||||||
name: URL Checker
|
name: URL Checker
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@ -17,7 +17,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
git_path: https://github.com/Slimefun/Slimefun4
|
git_path: https://github.com/Slimefun/Slimefun4
|
||||||
file_types: .md,.java,.yml
|
file_types: .md,.java,.yml
|
||||||
print_all: False
|
print_all: false
|
||||||
retry_count: 2
|
retry_count: 2
|
||||||
## These URLs will always be correct, even if their services may be offline right now
|
## 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,https://gitlocalize.com/repo/3841
|
white_listed_patterns: http://textures.minecraft.net/texture/,https://pastebin.com/,https://www.spigotmc.org/threads/spigot-bungeecord-1-16-1.447405/#post-3852349,https://gitlocalize.com/repo/3841
|
||||||
|
4
.github/workflows/yaml-linter.yml
vendored
4
.github/workflows/yaml-linter.yml
vendored
@ -16,8 +16,8 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v1
|
uses: actions/checkout@v2
|
||||||
- name: YAML Linter
|
- name: YAML Linter
|
||||||
uses: ibiqlik/action-yamllint@v1.0.0
|
uses: ibiqlik/action-yamllint@v3.0.0
|
||||||
with:
|
with:
|
||||||
config_file: '.github/configs/yaml-linter.yml'
|
config_file: '.github/configs/yaml-linter.yml'
|
||||||
|
25
CHANGELOG.md
25
CHANGELOG.md
@ -26,14 +26,39 @@
|
|||||||
## Release Candidate 18 (TBD)
|
## Release Candidate 18 (TBD)
|
||||||
|
|
||||||
#### Additions
|
#### Additions
|
||||||
|
* The Smelters Pick now also works on Ancient Debris
|
||||||
|
* (API) Added PlayerPreResearchEvent
|
||||||
|
* Added a config option to disable network visualizations
|
||||||
|
* (API) Added CoolerFeedPlayerEvent
|
||||||
|
|
||||||
#### Changes
|
#### Changes
|
||||||
* Removed 1.13 support
|
* Removed 1.13 support
|
||||||
|
* Cooling Units can no longer be placed down
|
||||||
|
* Heating Coils can no longer be placed down
|
||||||
|
* Electric Motors can no longer be placed down
|
||||||
|
* Cargo Motors can no longer be placed down
|
||||||
|
* Magnets can no longer be placed down
|
||||||
|
* Electromagnets can no longer be placed down
|
||||||
|
* Performance improvements to Cargo network visualizations
|
||||||
|
|
||||||
#### Fixes
|
#### Fixes
|
||||||
* Fixed #2448
|
* Fixed #2448
|
||||||
* Fixed #2470
|
* Fixed #2470
|
||||||
* Fixed #2478
|
* Fixed #2478
|
||||||
|
* Fixed #2493
|
||||||
|
* Fixed a missing slot in the contributors menu
|
||||||
|
* Fixed color codes in script downloading screen
|
||||||
|
* Fixed #2505
|
||||||
|
* Fixed contributors not showing correctly
|
||||||
|
* Fixed #2469
|
||||||
|
* Fixed #2509
|
||||||
|
* Fixed #2499
|
||||||
|
* Fixed #2527
|
||||||
|
* Fixed #2519
|
||||||
|
* Fixed #2517
|
||||||
|
* Fixed Magician Talisman sometimes drawing invalid enchantments
|
||||||
|
* Fixed id conflicts for external Enchantment sources (e.g. plugins) for the Magician Talisman settings
|
||||||
|
* Fixed network visualizers spawning particles for other player heads
|
||||||
|
|
||||||
## Release Candidate 17 (17 Oct 2020)
|
## Release Candidate 17 (17 Oct 2020)
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ Well, we asked some users on our [Discord server](#discord) to send us some scre
|
|||||||
| *Screenshot provided by GalaxyKat11#3816* | *Screenshot provided by TamThan#7987* | *Screenshot provided by Kilaruna#4981* |
|
| *Screenshot provided by GalaxyKat11#3816* | *Screenshot provided by TamThan#7987* | *Screenshot provided by Kilaruna#4981* |
|
||||||
|
|
||||||
## Discord
|
## Discord
|
||||||
You can find Slimefun's community on Discord and connect with **over 2500** users of this plugin from all over the world.<br>
|
You can find Slimefun's community on Discord and connect with **over 3000** users of this plugin from all over the world.<br>
|
||||||
Click the badge down below to join the server for suggestions/questions or other discussions about this plugin.<br>
|
Click the badge down below to join the server for suggestions/questions or other discussions about this plugin.<br>
|
||||||
We are also hosting a community event every so often, join us to find out more.<br>
|
We are also hosting a community event every so often, join us to find out more.<br>
|
||||||
**Important**: We do **not** accept bug reports on discord, please use our [Issue Tracker](https://github.com/Slimefun/Slimefun4/issues) to submit bug reports!
|
**Important**: We do **not** accept bug reports on discord, please use our [Issue Tracker](https://github.com/Slimefun/Slimefun4/issues) to submit bug reports!
|
||||||
|
12
pom.xml
12
pom.xml
@ -22,7 +22,7 @@
|
|||||||
<maven.compiler.target>1.8</maven.compiler.target>
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
|
||||||
<!-- Spigot properties -->
|
<!-- Spigot properties -->
|
||||||
<spigot.version>1.16.3</spigot.version>
|
<spigot.version>1.16.4</spigot.version>
|
||||||
<spigot.javadocs>https://hub.spigotmc.org/javadocs/spigot/</spigot.javadocs>
|
<spigot.javadocs>https://hub.spigotmc.org/javadocs/spigot/</spigot.javadocs>
|
||||||
|
|
||||||
<!-- Default settings for sonarcloud.io -->
|
<!-- Default settings for sonarcloud.io -->
|
||||||
@ -315,7 +315,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.seeseemelk</groupId>
|
<groupId>com.github.seeseemelk</groupId>
|
||||||
<artifactId>MockBukkit-v1.16</artifactId>
|
<artifactId>MockBukkit-v1.16</artifactId>
|
||||||
<version>0.13.0</version>
|
<version>0.15.0</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
@ -329,7 +329,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mockito</groupId>
|
<groupId>org.mockito</groupId>
|
||||||
<artifactId>mockito-core</artifactId>
|
<artifactId>mockito-core</artifactId>
|
||||||
<version>3.5.13</version>
|
<version>3.6.0</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@ -349,7 +349,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.konghq</groupId>
|
<groupId>com.konghq</groupId>
|
||||||
<artifactId>unirest-java</artifactId>
|
<artifactId>unirest-java</artifactId>
|
||||||
<version>3.11.02</version>
|
<version>3.11.05</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
@ -363,7 +363,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.sk89q.worldedit</groupId>
|
<groupId>com.sk89q.worldedit</groupId>
|
||||||
<artifactId>worldedit-bukkit</artifactId>
|
<artifactId>worldedit-bukkit</artifactId>
|
||||||
<version>7.2.0-SNAPSHOT</version>
|
<version>7.2.0</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
@ -381,7 +381,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.gmail.nossr50.mcMMO</groupId>
|
<groupId>com.gmail.nossr50.mcMMO</groupId>
|
||||||
<artifactId>mcMMO</artifactId>
|
<artifactId>mcMMO</artifactId>
|
||||||
<version>2.1.149</version>
|
<version>2.1.157</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
|
@ -0,0 +1,113 @@
|
|||||||
|
package io.github.thebusybiscuit.slimefun4.api.events;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.Cancellable;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.event.player.PlayerEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.PotionMeta;
|
||||||
|
import org.bukkit.potion.PotionEffect;
|
||||||
|
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This {@link Event} is called whenever a {@link Player} is
|
||||||
|
* fed through a {@link Cooler}.
|
||||||
|
*
|
||||||
|
* @author TheBusyBiscuit
|
||||||
|
*
|
||||||
|
* @see Cooler
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CoolerFeedPlayerEvent extends PlayerEvent implements Cancellable {
|
||||||
|
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
|
||||||
|
private final Cooler cooler;
|
||||||
|
private final ItemStack coolerItem;
|
||||||
|
|
||||||
|
private ItemStack consumedItem;
|
||||||
|
private boolean cancelled;
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public CoolerFeedPlayerEvent(Player player, Cooler cooler, ItemStack coolerItem, ItemStack consumedItem) {
|
||||||
|
super(player);
|
||||||
|
|
||||||
|
this.cooler = cooler;
|
||||||
|
this.coolerItem = coolerItem;
|
||||||
|
this.consumedItem = consumedItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns the {@link Cooler} that was used.
|
||||||
|
*
|
||||||
|
* @return The {@link Cooler} that was used
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
public Cooler getCooler() {
|
||||||
|
return cooler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns the {@link Cooler} that was used (as an {@link ItemStack})
|
||||||
|
*
|
||||||
|
* @return The {@link Cooler} that was used
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
public ItemStack getCoolerItem() {
|
||||||
|
return coolerItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns the {@link ItemStack} that was consumed.
|
||||||
|
* The returned {@link ItemStack} is immutable.
|
||||||
|
*
|
||||||
|
* @return The {@link ItemStack} that was consumed
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
public ItemStack getConsumedItem() {
|
||||||
|
return consumedItem.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This sets the {@link ItemStack} that should be "consumed".
|
||||||
|
* The {@link ItemStack} must be a potion.
|
||||||
|
* The {@link Player} will receive the {@link PotionEffect PotionEffects} of the
|
||||||
|
* provided potion upon consumption.
|
||||||
|
*
|
||||||
|
* @param item
|
||||||
|
* The new {@link ItemStack}
|
||||||
|
*/
|
||||||
|
public void setConsumedItem(@Nonnull ItemStack item) {
|
||||||
|
Validate.notNull(item, "The consumed Item cannot be null!");
|
||||||
|
Validate.isTrue(item.getItemMeta() instanceof PotionMeta, "The item must be a potion!");
|
||||||
|
|
||||||
|
this.consumedItem = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCancelled(boolean cancel) {
|
||||||
|
this.cancelled = cancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public static HandlerList getHandlerList() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public HandlerList getHandlers() {
|
||||||
|
return getHandlerList();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
package io.github.thebusybiscuit.slimefun4.api.events;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.Cancellable;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.core.researching.Research;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.guide.BookSlimefunGuide;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.guide.ChestSlimefunGuide;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.guide.CheatSheetSlimefunGuide;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This {@link Event} is called whenever a {@link Player} clicks to unlock a {@link Research}.
|
||||||
|
* This is called before {@link Research#canUnlock(Player)}.
|
||||||
|
* The {@link Event} is not called for {@link CheatSheetSlimefunGuide}.
|
||||||
|
*
|
||||||
|
* @author uiytt
|
||||||
|
*
|
||||||
|
* @see ChestSlimefunGuide
|
||||||
|
* @see BookSlimefunGuide
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class PlayerPreResearchEvent extends Event implements Cancellable {
|
||||||
|
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
|
||||||
|
private final Player player;
|
||||||
|
private final Research research;
|
||||||
|
private final SlimefunItem slimefunItem;
|
||||||
|
private boolean cancelled;
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public PlayerPreResearchEvent(Player p, Research research, SlimefunItem slimefunItem) {
|
||||||
|
Validate.notNull(p, "The Player cannot be null");
|
||||||
|
Validate.notNull(research, "Research cannot be null");
|
||||||
|
Validate.notNull(slimefunItem, "SlimefunItem cannot be null");
|
||||||
|
|
||||||
|
this.player = p;
|
||||||
|
this.research = research;
|
||||||
|
this.slimefunItem = slimefunItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public Player getPlayer() {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public Research getResearch() {
|
||||||
|
return research;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public SlimefunItem getSlimefunItem() {
|
||||||
|
return slimefunItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 cancelled) {
|
||||||
|
this.cancelled = cancelled;
|
||||||
|
}
|
||||||
|
}
|
@ -9,11 +9,8 @@ import javax.annotation.Nonnull;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.Color;
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.Particle;
|
import org.bukkit.Particle;
|
||||||
import org.bukkit.Particle.DustOptions;
|
|
||||||
|
|
||||||
import io.github.thebusybiscuit.slimefun4.core.networks.NetworkManager;
|
import io.github.thebusybiscuit.slimefun4.core.networks.NetworkManager;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
@ -103,13 +100,16 @@ public abstract class Network {
|
|||||||
return regulatorNodes.size() + connectorNodes.size() + terminusNodes.size();
|
return regulatorNodes.size() + connectorNodes.size() + terminusNodes.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method adds the given {@link Location} to this {@link Network}.
|
||||||
|
*
|
||||||
|
* @param l
|
||||||
|
* The {@link Location} to add
|
||||||
|
*/
|
||||||
protected void addLocationToNetwork(@Nonnull Location l) {
|
protected void addLocationToNetwork(@Nonnull Location l) {
|
||||||
if (connectedLocations.contains(l)) {
|
if (connectedLocations.add(l.clone())) {
|
||||||
return;
|
markDirty(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedLocations.add(l.clone());
|
|
||||||
markDirty(l);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -211,17 +211,9 @@ public abstract class Network {
|
|||||||
* every {@link Location} that this {@link Network} is connected to.
|
* every {@link Location} that this {@link Network} is connected to.
|
||||||
*/
|
*/
|
||||||
public void display() {
|
public void display() {
|
||||||
SlimefunPlugin.runSync(() -> {
|
if (manager.isVisualizerEnabled()) {
|
||||||
DustOptions options = new DustOptions(Color.BLUE, 3F);
|
SlimefunPlugin.runSync(new NetworkVisualizer(this));
|
||||||
|
}
|
||||||
for (Location l : connectedLocations) {
|
|
||||||
Material type = l.getBlock().getType();
|
|
||||||
|
|
||||||
if (type == Material.PLAYER_HEAD || type == Material.PLAYER_WALL_HEAD) {
|
|
||||||
l.getWorld().spawnParticle(Particle.REDSTONE, l.getX() + 0.5, l.getY() + 0.5, l.getZ() + 0.5, 1, 0, 0, 0, 1, options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
package io.github.thebusybiscuit.slimefun4.api.network;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
import org.bukkit.Color;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Particle;
|
||||||
|
import org.bukkit.Particle.DustOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents the visualizer task of a given {@link Network}.
|
||||||
|
*
|
||||||
|
* @author TheBusyBiscuit
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is our {@link Network} instance.
|
||||||
|
*/
|
||||||
|
private final Network network;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This creates a new {@link NetworkVisualizer} for the given {@link Network}.
|
||||||
|
*
|
||||||
|
* @param network
|
||||||
|
* The {@link Network} to visualize
|
||||||
|
*/
|
||||||
|
NetworkVisualizer(@Nonnull Network network) {
|
||||||
|
this.network = network;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
for (Location l : network.connectorNodes) {
|
||||||
|
spawnParticles(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Location l : network.terminusNodes) {
|
||||||
|
spawnParticles(l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will spawn the actual particles.
|
||||||
|
*
|
||||||
|
* @param l
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -40,7 +40,7 @@ class GiveCommand extends SubCommand {
|
|||||||
if (sfItem != null) {
|
if (sfItem != null) {
|
||||||
giveItem(sender, p, sfItem, args);
|
giveItem(sender, p, sfItem, args);
|
||||||
} else {
|
} else {
|
||||||
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.not-valid-item", true, msg -> msg.replace(PLACEHOLDER_ITEM, args[2]));
|
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.invalid-item", true, msg -> msg.replace(PLACEHOLDER_ITEM, args[2]));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.not-online", true, msg -> msg.replace(PLACEHOLDER_PLAYER, args[1]));
|
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.not-online", true, msg -> msg.replace(PLACEHOLDER_PLAYER, args[1]));
|
||||||
@ -70,7 +70,7 @@ class GiveCommand extends SubCommand {
|
|||||||
|
|
||||||
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.give-item", true, msg -> msg.replace(PLACEHOLDER_PLAYER, args[1]).replace(PLACEHOLDER_ITEM, sfItem.getItemName()).replace(PLACEHOLDER_AMOUNT, String.valueOf(amount)));
|
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.give-item", true, msg -> msg.replace(PLACEHOLDER_PLAYER, args[1]).replace(PLACEHOLDER_ITEM, sfItem.getItemName()).replace(PLACEHOLDER_AMOUNT, String.valueOf(amount)));
|
||||||
} else {
|
} else {
|
||||||
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.not-valid-amount", true, msg -> msg.replace(PLACEHOLDER_AMOUNT, args[3]));
|
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.invalid-amount", true, msg -> msg.replace(PLACEHOLDER_AMOUNT, args[3]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ class ResearchCommand extends SubCommand {
|
|||||||
SlimefunPlugin.getLocalization().sendMessage(player, "messages.give-research", true, variables);
|
SlimefunPlugin.getLocalization().sendMessage(player, "messages.give-research", true, variables);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.not-valid-research", true, msg -> msg.replace(PLACEHOLDER_RESEARCH, input));
|
SlimefunPlugin.getLocalization().sendMessage(sender, "messages.invalid-research", true, msg -> msg.replace(PLACEHOLDER_RESEARCH, input));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ final class ContributorsMenu {
|
|||||||
menu.setEmptySlotsClickable(false);
|
menu.setEmptySlotsClickable(false);
|
||||||
menu.addMenuOpeningHandler(pl -> pl.playSound(pl.getLocation(), Sound.BLOCK_NOTE_BLOCK_HARP, 0.7F, 0.7F));
|
menu.addMenuOpeningHandler(pl -> pl.playSound(pl.getLocation(), Sound.BLOCK_NOTE_BLOCK_HARP, 0.7F, 0.7F));
|
||||||
|
|
||||||
ChestMenuUtils.drawBackground(menu, 0, 2, 3, 4, 5, 6, 7, 8, 45, 47, 48, 49, 50, 51, 52);
|
ChestMenuUtils.drawBackground(menu, 0, 2, 3, 4, 5, 6, 7, 8, 45, 47, 48, 49, 50, 51, 53);
|
||||||
|
|
||||||
menu.addItem(1, new CustomItem(ChestMenuUtils.getBackButton(p, "", "&7" + SlimefunPlugin.getLocalization().getMessage(p, "guide.back.settings"))));
|
menu.addItem(1, new CustomItem(ChestMenuUtils.getBackButton(p, "", "&7" + SlimefunPlugin.getLocalization().getMessage(p, "guide.back.settings"))));
|
||||||
menu.addMenuClickHandler(1, (pl, slot, item, action) -> {
|
menu.addMenuClickHandler(1, (pl, slot, item, action) -> {
|
||||||
|
@ -16,6 +16,7 @@ import io.github.thebusybiscuit.cscorelib2.collections.LoopIterator;
|
|||||||
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
|
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.RainbowBlock;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.RainbowBlock;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.utils.ColoredMaterial;
|
||||||
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
|
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
|
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
|
||||||
@ -48,10 +49,14 @@ public class RainbowTickHandler extends BlockTicker {
|
|||||||
material = iterator.next();
|
material = iterator.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
public RainbowTickHandler(Material... materials) {
|
public RainbowTickHandler(@Nonnull Material... materials) {
|
||||||
this(Arrays.asList(materials));
|
this(Arrays.asList(materials));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RainbowTickHandler(@Nonnull ColoredMaterial material) {
|
||||||
|
this(material.asList());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method checks whether a given {@link Material} array contains any {@link Material}
|
* This method checks whether a given {@link Material} array contains any {@link Material}
|
||||||
* that would result in a {@link GlassPane} {@link BlockData}.
|
* that would result in a {@link GlassPane} {@link BlockData}.
|
||||||
|
@ -29,6 +29,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.NetworkListen
|
|||||||
public class NetworkManager {
|
public class NetworkManager {
|
||||||
|
|
||||||
private final int maxNodes;
|
private final int maxNodes;
|
||||||
|
private final boolean enableVisualizer;
|
||||||
private final List<Network> networks = new LinkedList<>();
|
private final List<Network> networks = new LinkedList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,8 +38,10 @@ public class NetworkManager {
|
|||||||
* @param maxStepSize
|
* @param maxStepSize
|
||||||
* The maximum amount of nodes a {@link Network} can have
|
* The maximum amount of nodes a {@link Network} can have
|
||||||
*/
|
*/
|
||||||
public NetworkManager(int maxStepSize) {
|
public NetworkManager(int maxStepSize, boolean enableVisualizer) {
|
||||||
Validate.isTrue(maxStepSize > 0, "The maximal Network size must be above zero!");
|
Validate.isTrue(maxStepSize > 0, "The maximal Network size must be above zero!");
|
||||||
|
|
||||||
|
this.enableVisualizer = enableVisualizer;
|
||||||
maxNodes = maxStepSize;
|
maxNodes = maxStepSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +55,15 @@ public class NetworkManager {
|
|||||||
return maxNodes;
|
return maxNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns whether the {@link Network} visualizer is enabled.
|
||||||
|
*
|
||||||
|
* @return Whether the {@link Network} visualizer is enabled
|
||||||
|
*/
|
||||||
|
public boolean isVisualizerEnabled() {
|
||||||
|
return enableVisualizer;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This returns a {@link List} of every {@link Network} on the {@link Server}.
|
* This returns a {@link List} of every {@link Network} on the {@link Server}.
|
||||||
*
|
*
|
||||||
|
@ -8,6 +8,7 @@ import java.util.function.Consumer;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@ -25,6 +26,9 @@ import io.github.thebusybiscuit.slimefun4.core.services.localization.Language;
|
|||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.setup.ResearchSetup;
|
import io.github.thebusybiscuit.slimefun4.implementation.setup.ResearchSetup;
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.FireworkUtils;
|
import io.github.thebusybiscuit.slimefun4.utils.FireworkUtils;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.api.events.PlayerPreResearchEvent;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideImplementation;
|
||||||
|
import me.mrCookieSlime.Slimefun.Objects.Category;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -189,6 +193,38 @@ public class Research implements Keyed {
|
|||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle what to do when a {@link Player} clicks on an un-researched item in
|
||||||
|
* a {@link SlimefunGuideImplementation}.
|
||||||
|
*
|
||||||
|
* @param guide The {@link SlimefunGuideImplementation} used.
|
||||||
|
* @param player The {@link Player} who clicked on the item.
|
||||||
|
* @param profile The {@link PlayerProfile} of that {@link Player}.
|
||||||
|
* @param sfItem The {@link SlimefunItem} on which the {@link Player} clicked.
|
||||||
|
* @param category The {@link Category} where the {@link Player} was.
|
||||||
|
* @param page The page number of where the {@link Player} was in the {@link Category};
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public void unlockFromGuide(SlimefunGuideImplementation guide, Player player, PlayerProfile profile, SlimefunItem sfItem, Category category, int page) {
|
||||||
|
if (!SlimefunPlugin.getRegistry().getCurrentlyResearchingPlayers().contains(player.getUniqueId())) {
|
||||||
|
if (profile.hasUnlocked(this)) {
|
||||||
|
guide.openCategory(profile, category, page);
|
||||||
|
} else {
|
||||||
|
PlayerPreResearchEvent event = new PlayerPreResearchEvent(player, this, sfItem);
|
||||||
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
|
|
||||||
|
if (!event.isCancelled()) {
|
||||||
|
if (this.canUnlock(player)) {
|
||||||
|
guide.unlockItem(player, sfItem, pl -> guide.openCategory(profile, category, page));
|
||||||
|
} else {
|
||||||
|
SlimefunPlugin.getLocalization().sendMessage(player, "messages.not-enough-xp", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the {@link Player} can unlock this {@link Research}.
|
* Checks if the {@link Player} can unlock this {@link Research}.
|
||||||
*
|
*
|
||||||
|
@ -1,16 +1,31 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.core.services;
|
package io.github.thebusybiscuit.slimefun4.core.services;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Keyed;
|
import org.bukkit.Keyed;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockState;
|
import org.bukkit.block.BlockState;
|
||||||
import org.bukkit.block.TileState;
|
import org.bukkit.block.TileState;
|
||||||
|
import org.bukkit.persistence.PersistentDataContainer;
|
||||||
import org.bukkit.persistence.PersistentDataHolder;
|
import org.bukkit.persistence.PersistentDataHolder;
|
||||||
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
|
import io.papermc.lib.PaperLib;
|
||||||
|
import io.papermc.lib.features.blockstatesnapshot.BlockStateSnapshotResult;
|
||||||
|
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link BlockDataService} is similar to the {@link CustomItemDataService},
|
* The {@link BlockDataService} is similar to the {@link CustomItemDataService},
|
||||||
* it is responsible for storing NBT data inside a {@link TileState}.
|
* it is responsible for storing NBT data inside a {@link TileState}.
|
||||||
@ -20,11 +35,21 @@ import org.bukkit.plugin.Plugin;
|
|||||||
* @author TheBusyBiscuit
|
* @author TheBusyBiscuit
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class BlockDataService implements PersistentDataService, Keyed {
|
public class BlockDataService implements Keyed {
|
||||||
|
|
||||||
private final NamespacedKey namespacedKey;
|
private final NamespacedKey namespacedKey;
|
||||||
|
|
||||||
public BlockDataService(Plugin plugin, String key) {
|
/**
|
||||||
|
* This creates a new {@link BlockDataService} for the given {@link Plugin}.
|
||||||
|
* The {@link Plugin} and key will together form a {@link NamespacedKey} used to store
|
||||||
|
* data on a {@link TileState}.
|
||||||
|
*
|
||||||
|
* @param plugin
|
||||||
|
* The {@link Plugin} responsible for this service
|
||||||
|
* @param key
|
||||||
|
* The key under which to store data
|
||||||
|
*/
|
||||||
|
public BlockDataService(@Nonnull Plugin plugin, @Nonnull String key) {
|
||||||
namespacedKey = new NamespacedKey(plugin, key);
|
namespacedKey = new NamespacedKey(plugin, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,12 +66,32 @@ public class BlockDataService implements PersistentDataService, Keyed {
|
|||||||
* @param value
|
* @param value
|
||||||
* The value to store
|
* The value to store
|
||||||
*/
|
*/
|
||||||
public void setBlockData(Block b, String value) {
|
public void setBlockData(@Nonnull Block b, @Nonnull String value) {
|
||||||
BlockState state = b.getState();
|
Validate.notNull(b, "The block cannot be null!");
|
||||||
|
Validate.notNull(value, "The value cannot be null!");
|
||||||
|
|
||||||
|
// Due to a bug on older versions, Persistent Data is nullable for non-snapshots
|
||||||
|
boolean useSnapshot = SlimefunPlugin.getMinecraftVersion().isBefore(MinecraftVersion.MINECRAFT_1_16);
|
||||||
|
|
||||||
|
BlockStateSnapshotResult result = PaperLib.getBlockState(b, useSnapshot);
|
||||||
|
BlockState state = result.getState();
|
||||||
|
|
||||||
if (state instanceof TileState) {
|
if (state instanceof TileState) {
|
||||||
setString((TileState) state, namespacedKey, value);
|
try {
|
||||||
state.update();
|
PersistentDataContainer container = ((TileState) state).getPersistentDataContainer();
|
||||||
|
container.set(namespacedKey, PersistentDataType.STRING, value);
|
||||||
|
|
||||||
|
if (result.isSnapshot()) {
|
||||||
|
state.update();
|
||||||
|
}
|
||||||
|
} catch (Exception x) {
|
||||||
|
Slimefun.getLogger().log(Level.SEVERE, "Please check if your Server Software is up to date!");
|
||||||
|
|
||||||
|
String serverSoftware = PaperLib.isSpigot() && !PaperLib.isPaper() ? "Spigot" : Bukkit.getName();
|
||||||
|
Slimefun.getLogger().log(Level.SEVERE, () -> serverSoftware + " | " + Bukkit.getVersion() + " | " + Bukkit.getBukkitVersion());
|
||||||
|
|
||||||
|
Slimefun.getLogger().log(Level.SEVERE, "An Exception was thrown while trying to set Persistent Data for a Block", x);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,11 +102,14 @@ public class BlockDataService implements PersistentDataService, Keyed {
|
|||||||
* The {@link Block} to retrieve data from
|
* The {@link Block} to retrieve data from
|
||||||
* @return The stored value
|
* @return The stored value
|
||||||
*/
|
*/
|
||||||
public Optional<String> getBlockData(Block b) {
|
public Optional<String> getBlockData(@Nonnull Block b) {
|
||||||
BlockState state = b.getState();
|
Validate.notNull(b, "The block cannot be null!");
|
||||||
|
|
||||||
|
BlockState state = PaperLib.getBlockState(b, false).getState();
|
||||||
|
|
||||||
if (state instanceof TileState) {
|
if (state instanceof TileState) {
|
||||||
return getString((TileState) state, namespacedKey);
|
PersistentDataContainer container = ((TileState) state).getPersistentDataContainer();
|
||||||
|
return Optional.ofNullable(container.get(namespacedKey, PersistentDataType.STRING));
|
||||||
} else {
|
} else {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
@ -77,9 +125,10 @@ public class BlockDataService implements PersistentDataService, Keyed {
|
|||||||
*
|
*
|
||||||
* @param type
|
* @param type
|
||||||
* The {@link Material} to check for
|
* The {@link Material} to check for
|
||||||
|
*
|
||||||
* @return Whether the given {@link Material} is considered a Tile Entity
|
* @return Whether the given {@link Material} is considered a Tile Entity
|
||||||
*/
|
*/
|
||||||
public boolean isTileEntity(Material type) {
|
public boolean isTileEntity(@Nullable Material type) {
|
||||||
if (type == null || type.isAir()) {
|
if (type == null || type.isAir()) {
|
||||||
// Cannot store data on air
|
// Cannot store data on air
|
||||||
return false;
|
return false;
|
||||||
@ -104,8 +153,10 @@ public class BlockDataService implements PersistentDataService, Keyed {
|
|||||||
case BARREL:
|
case BARREL:
|
||||||
case SPAWNER:
|
case SPAWNER:
|
||||||
case BEACON:
|
case BEACON:
|
||||||
|
// All of the above Materials are Tile Entities
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
|
// Otherwise we assume they're not Tile Entities
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,17 @@ package io.github.thebusybiscuit.slimefun4.core.services;
|
|||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.Keyed;
|
import org.bukkit.Keyed;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.persistence.PersistentDataContainer;
|
||||||
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
@ -22,7 +28,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
|||||||
* @see SlimefunItemStack
|
* @see SlimefunItemStack
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class CustomItemDataService implements PersistentDataService, Keyed {
|
public class CustomItemDataService implements Keyed {
|
||||||
|
|
||||||
private final NamespacedKey namespacedKey;
|
private final NamespacedKey namespacedKey;
|
||||||
|
|
||||||
@ -35,7 +41,7 @@ public class CustomItemDataService implements PersistentDataService, Keyed {
|
|||||||
* @param key
|
* @param key
|
||||||
* The key under which to store data
|
* The key under which to store data
|
||||||
*/
|
*/
|
||||||
public CustomItemDataService(Plugin plugin, String key) {
|
public CustomItemDataService(@Nonnull Plugin plugin, @Nonnull String key) {
|
||||||
// Null-Validation is performed in the NamespacedKey constructor
|
// Null-Validation is performed in the NamespacedKey constructor
|
||||||
namespacedKey = new NamespacedKey(plugin, key);
|
namespacedKey = new NamespacedKey(plugin, key);
|
||||||
}
|
}
|
||||||
@ -45,14 +51,39 @@ public class CustomItemDataService implements PersistentDataService, Keyed {
|
|||||||
return namespacedKey;
|
return namespacedKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setItemData(ItemStack item, String id) {
|
/**
|
||||||
|
* This method stores the given id on the provided {@link ItemStack} via
|
||||||
|
* persistent data.
|
||||||
|
*
|
||||||
|
* @param item
|
||||||
|
* The {@link ItemStack} to store data on
|
||||||
|
* @param id
|
||||||
|
* The id to store on the {@link ItemStack}
|
||||||
|
*/
|
||||||
|
public void setItemData(@Nonnull ItemStack item, @Nonnull String id) {
|
||||||
|
Validate.notNull(item, "The Item cannot be null!");
|
||||||
|
Validate.notNull(id, "Cannot store null on an Item!");
|
||||||
|
|
||||||
ItemMeta im = item.getItemMeta();
|
ItemMeta im = item.getItemMeta();
|
||||||
setItemData(im, id);
|
setItemData(im, id);
|
||||||
item.setItemMeta(im);
|
item.setItemMeta(im);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setItemData(ItemMeta im, String id) {
|
/**
|
||||||
setString(im, namespacedKey, id);
|
* This method stores the given id on the provided {@link ItemMeta} via
|
||||||
|
* persistent data.
|
||||||
|
*
|
||||||
|
* @param meta
|
||||||
|
* The {@link ItemMeta} to store data on
|
||||||
|
* @param id
|
||||||
|
* The id to store on the {@link ItemMeta}
|
||||||
|
*/
|
||||||
|
public void setItemData(@Nonnull ItemMeta meta, @Nonnull String id) {
|
||||||
|
Validate.notNull(meta, "The ItemMeta cannot be null!");
|
||||||
|
Validate.notNull(id, "Cannot store null on an ItemMeta!");
|
||||||
|
|
||||||
|
PersistentDataContainer container = meta.getPersistentDataContainer();
|
||||||
|
container.set(namespacedKey, PersistentDataType.STRING, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,7 +96,8 @@ public class CustomItemDataService implements PersistentDataService, Keyed {
|
|||||||
*
|
*
|
||||||
* @return An {@link Optional} describing the result
|
* @return An {@link Optional} describing the result
|
||||||
*/
|
*/
|
||||||
public Optional<String> getItemData(ItemStack item) {
|
@Nonnull
|
||||||
|
public Optional<String> getItemData(@Nullable ItemStack item) {
|
||||||
if (item == null || item.getType() == Material.AIR || !item.hasItemMeta()) {
|
if (item == null || item.getType() == Material.AIR || !item.hasItemMeta()) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
@ -82,8 +114,12 @@ public class CustomItemDataService implements PersistentDataService, Keyed {
|
|||||||
*
|
*
|
||||||
* @return An {@link Optional} describing the result
|
* @return An {@link Optional} describing the result
|
||||||
*/
|
*/
|
||||||
public Optional<String> getItemData(ItemMeta meta) {
|
@Nonnull
|
||||||
return getString(meta, namespacedKey);
|
public Optional<String> getItemData(@Nonnull ItemMeta meta) {
|
||||||
|
Validate.notNull(meta, "Cannot read data from null!");
|
||||||
|
|
||||||
|
PersistentDataContainer container = meta.getPersistentDataContainer();
|
||||||
|
return Optional.ofNullable(container.get(namespacedKey, PersistentDataType.STRING));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,12 @@ public class CustomTextureService {
|
|||||||
private String version = null;
|
private String version = null;
|
||||||
private boolean modified = false;
|
private boolean modified = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This creates a new {@link CustomTextureService} for the provided {@link Config}
|
||||||
|
*
|
||||||
|
* @param config
|
||||||
|
* The {@link Config} to read custom model data from
|
||||||
|
*/
|
||||||
public CustomTextureService(@Nonnull Config config) {
|
public CustomTextureService(@Nonnull Config config) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
config.getConfiguration().options().header("This file is used to assign items from Slimefun or any of its addons\n" + "the 'CustomModelData' NBT tag. This can be used in conjunction with a custom resource pack\n" + "to give items custom textures.\n0 means there is no data assigned to that item.\n\n" + "There is no official Slimefun resource pack at the moment.");
|
config.getConfiguration().options().header("This file is used to assign items from Slimefun or any of its addons\n" + "the 'CustomModelData' NBT tag. This can be used in conjunction with a custom resource pack\n" + "to give items custom textures.\n0 means there is no data assigned to that item.\n\n" + "There is no official Slimefun resource pack at the moment.");
|
||||||
@ -49,6 +55,8 @@ public class CustomTextureService {
|
|||||||
config.setDefaultValue("SLIMEFUN_GUIDE", 0);
|
config.setDefaultValue("SLIMEFUN_GUIDE", 0);
|
||||||
|
|
||||||
config.setDefaultValue("_UI_BACKGROUND", 0);
|
config.setDefaultValue("_UI_BACKGROUND", 0);
|
||||||
|
config.setDefaultValue("_UI_NO_PERMISSION", 0);
|
||||||
|
config.setDefaultValue("_UI_NOT_RESEARCHED", 0);
|
||||||
config.setDefaultValue("_UI_INPUT_SLOT", 0);
|
config.setDefaultValue("_UI_INPUT_SLOT", 0);
|
||||||
config.setDefaultValue("_UI_OUTPUT_SLOT", 0);
|
config.setDefaultValue("_UI_OUTPUT_SLOT", 0);
|
||||||
config.setDefaultValue("_UI_BACK", 0);
|
config.setDefaultValue("_UI_BACK", 0);
|
||||||
@ -82,22 +90,60 @@ public class CustomTextureService {
|
|||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns true if any custom model data was configured.
|
||||||
|
* If every item id has no configured custom model data, it will return false.
|
||||||
|
*
|
||||||
|
* @return Whether any custom model data was configured
|
||||||
|
*/
|
||||||
public boolean isActive() {
|
public boolean isActive() {
|
||||||
return modified;
|
return modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns the configured custom model data for a given id.
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* The id to get the data for
|
||||||
|
*
|
||||||
|
* @return The configured custom model data
|
||||||
|
*/
|
||||||
public int getModelData(@Nonnull String id) {
|
public int getModelData(@Nonnull String id) {
|
||||||
Validate.notNull(id, "Cannot get the ModelData for 'null'");
|
Validate.notNull(id, "Cannot get the ModelData for 'null'");
|
||||||
return config.getInt(id);
|
return config.getInt(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the custom model data for this {@link ItemStack}
|
||||||
|
* to the value configured for the provided item id.
|
||||||
|
*
|
||||||
|
* @param item
|
||||||
|
* The {@link ItemStack} to set the custom model data for
|
||||||
|
* @param id
|
||||||
|
* The id for which to get the configured model data
|
||||||
|
*/
|
||||||
public void setTexture(@Nonnull ItemStack item, @Nonnull String id) {
|
public void setTexture(@Nonnull ItemStack item, @Nonnull String id) {
|
||||||
|
Validate.notNull(item, "The Item cannot be null!");
|
||||||
|
Validate.notNull(id, "Cannot store null on an Item!");
|
||||||
|
|
||||||
ItemMeta im = item.getItemMeta();
|
ItemMeta im = item.getItemMeta();
|
||||||
setTexture(im, id);
|
setTexture(im, id);
|
||||||
item.setItemMeta(im);
|
item.setItemMeta(im);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the custom model data for this {@link ItemMeta}
|
||||||
|
* to the value configured for the provided item id.
|
||||||
|
*
|
||||||
|
* @param im
|
||||||
|
* The {@link ItemMeta} to set the custom model data for
|
||||||
|
* @param id
|
||||||
|
* The id for which to get the configured model data
|
||||||
|
*/
|
||||||
public void setTexture(@Nonnull ItemMeta im, @Nonnull String id) {
|
public void setTexture(@Nonnull ItemMeta im, @Nonnull String id) {
|
||||||
|
Validate.notNull(im, "The ItemMeta cannot be null!");
|
||||||
|
Validate.notNull(id, "Cannot store null on an ItemMeta!");
|
||||||
|
|
||||||
int data = getModelData(id);
|
int data = getModelData(id);
|
||||||
im.setCustomModelData(data == 0 ? null : data);
|
im.setCustomModelData(data == 0 ? null : data);
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ import java.util.Collection;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
@ -21,6 +20,8 @@ import org.bukkit.Server;
|
|||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.persistence.PersistentDataContainer;
|
||||||
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
|
|
||||||
import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler;
|
import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.services.localization.Language;
|
import io.github.thebusybiscuit.slimefun4.core.services.localization.Language;
|
||||||
@ -37,7 +38,7 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|||||||
* @see Language
|
* @see Language
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class LocalizationService extends SlimefunLocalization implements PersistentDataService {
|
public class LocalizationService extends SlimefunLocalization {
|
||||||
|
|
||||||
private static final String LANGUAGE_PATH = "language";
|
private static final String LANGUAGE_PATH = "language";
|
||||||
|
|
||||||
@ -151,10 +152,12 @@ public class LocalizationService extends SlimefunLocalization implements Persist
|
|||||||
@Override
|
@Override
|
||||||
public Language getLanguage(@Nonnull Player p) {
|
public Language getLanguage(@Nonnull Player p) {
|
||||||
Validate.notNull("Player cannot be null!");
|
Validate.notNull("Player cannot be null!");
|
||||||
Optional<String> language = getString(p, languageKey);
|
|
||||||
|
|
||||||
if (language.isPresent()) {
|
PersistentDataContainer container = p.getPersistentDataContainer();
|
||||||
Language lang = languages.get(language.get());
|
String language = container.get(languageKey, PersistentDataType.STRING);
|
||||||
|
|
||||||
|
if (language != null) {
|
||||||
|
Language lang = languages.get(language);
|
||||||
|
|
||||||
if (lang != null) {
|
if (lang != null) {
|
||||||
return lang;
|
return lang;
|
||||||
@ -164,7 +167,7 @@ public class LocalizationService extends SlimefunLocalization implements Persist
|
|||||||
return getDefaultLanguage();
|
return getDefaultLanguage();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setLanguage(String language, boolean reset) {
|
private void setLanguage(@Nonnull String language, boolean reset) {
|
||||||
// Clearing out the old Language (if necessary)
|
// Clearing out the old Language (if necessary)
|
||||||
if (reset) {
|
if (reset) {
|
||||||
getConfig().clear();
|
getConfig().clear();
|
||||||
|
@ -34,9 +34,26 @@ import kong.unirest.UnirestException;
|
|||||||
*/
|
*/
|
||||||
public class MetricsService {
|
public class MetricsService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The URL pointing towards the GitHub API.
|
||||||
|
*/
|
||||||
private static final String API_URL = "https://api.github.com/";
|
private static final String API_URL = "https://api.github.com/";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Name of our repository
|
||||||
|
*/
|
||||||
private static final String REPO_NAME = "MetricsModule";
|
private static final String REPO_NAME = "MetricsModule";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The URL pointing towards the /releases/ endpoint of our
|
||||||
|
* Metrics repository
|
||||||
|
*/
|
||||||
private static final String RELEASES_URL = API_URL + "repos/Slimefun/" + REPO_NAME + "/releases/latest";
|
private static final String RELEASES_URL = API_URL + "repos/Slimefun/" + REPO_NAME + "/releases/latest";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The URL pointing towards the download location for a
|
||||||
|
* GitHub release of our Metrics repository
|
||||||
|
*/
|
||||||
private static final String DOWNLOAD_URL = "https://github.com/Slimefun/" + REPO_NAME + "/releases/download";
|
private static final String DOWNLOAD_URL = "https://github.com/Slimefun/" + REPO_NAME + "/releases/download";
|
||||||
|
|
||||||
private final SlimefunPlugin plugin;
|
private final SlimefunPlugin plugin;
|
||||||
@ -48,9 +65,22 @@ public class MetricsService {
|
|||||||
private boolean hasDownloadedUpdate = false;
|
private boolean hasDownloadedUpdate = false;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
Unirest.config().concurrency(2, 1).setDefaultHeader("User-Agent", "MetricsModule Auto-Updater").setDefaultHeader("Accept", "application/vnd.github.v3+json").enableCookieManagement(false).cookieSpec("ignoreCookies");
|
// @formatter:off (We want this to stay this nicely aligned :D )
|
||||||
|
Unirest.config()
|
||||||
|
.concurrency(2, 1)
|
||||||
|
.setDefaultHeader("User-Agent", "MetricsModule Auto-Updater")
|
||||||
|
.setDefaultHeader("Accept", "application/vnd.github.v3+json")
|
||||||
|
.enableCookieManagement(false)
|
||||||
|
.cookieSpec("ignoreCookies");
|
||||||
|
// @formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constructs a new instance of our {@link MetricsService}.
|
||||||
|
*
|
||||||
|
* @param plugin
|
||||||
|
* Our {@link SlimefunPlugin} instance
|
||||||
|
*/
|
||||||
public MetricsService(@Nonnull SlimefunPlugin plugin) {
|
public MetricsService(@Nonnull SlimefunPlugin plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.parentFolder = new File(plugin.getDataFolder(), "cache" + File.separatorChar + "modules");
|
this.parentFolder = new File(plugin.getDataFolder(), "cache" + File.separatorChar + "modules");
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.core.services;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import org.bukkit.NamespacedKey;
|
|
||||||
import org.bukkit.persistence.PersistentDataContainer;
|
|
||||||
import org.bukkit.persistence.PersistentDataHolder;
|
|
||||||
import org.bukkit.persistence.PersistentDataType;
|
|
||||||
|
|
||||||
import io.github.thebusybiscuit.cscorelib2.data.PersistentDataAPI;
|
|
||||||
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This interface is used to defer calls to Persistent Data and make sure they are only called
|
|
||||||
* if the {@link MinecraftVersion} supports it.
|
|
||||||
*
|
|
||||||
* @author TheBusyBiscuit
|
|
||||||
*
|
|
||||||
* @deprecated This is redundant, we can use {@link PersistentDataAPI} instead.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
interface PersistentDataService {
|
|
||||||
|
|
||||||
default void setString(Object obj, NamespacedKey key, String value) {
|
|
||||||
PersistentDataContainer container = ((PersistentDataHolder) obj).getPersistentDataContainer();
|
|
||||||
container.set(key, PersistentDataType.STRING, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
default Optional<String> getString(Object obj, NamespacedKey key) {
|
|
||||||
PersistentDataContainer container = ((PersistentDataHolder) obj).getPersistentDataContainer();
|
|
||||||
return Optional.ofNullable(container.get(key, PersistentDataType.STRING));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -16,11 +16,28 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|||||||
|
|
||||||
class ContributionsConnector extends GitHubConnector {
|
class ContributionsConnector extends GitHubConnector {
|
||||||
|
|
||||||
// GitHub Bots that do not count as Contributors
|
/*
|
||||||
// (includes "invalid-email-address" because it is an invalid contributor)
|
* @formatter:off
|
||||||
private static final List<String> blacklist = Arrays.asList("invalid-email-address", "renovate-bot", "TheBusyBot", "ImgBotApp", "imgbot", "imgbot[bot]", "github-actions[bot]", "gitlocalize-app", "gitlocalize-app[bot]", "mt-gitlocalize");
|
* GitHub Bots that do not count as Contributors
|
||||||
|
* (includes "invalid-email-address" because it is an invalid contributor)
|
||||||
|
*/
|
||||||
|
private static final List<String> blacklist = Arrays.asList(
|
||||||
|
"invalid-email-address",
|
||||||
|
"renovate-bot",
|
||||||
|
"TheBusyBot",
|
||||||
|
"ImgBotApp",
|
||||||
|
"imgbot",
|
||||||
|
"imgbot[bot]",
|
||||||
|
"github-actions[bot]",
|
||||||
|
"gitlocalize-app",
|
||||||
|
"gitlocalize-app[bot]",
|
||||||
|
"mt-gitlocalize"
|
||||||
|
);
|
||||||
|
|
||||||
// Matches a GitHub name with a Minecraft name.
|
/*
|
||||||
|
* @formatter:on
|
||||||
|
* Matches a GitHub name with a Minecraft name.
|
||||||
|
*/
|
||||||
private static final Map<String, String> aliases = new HashMap<>();
|
private static final Map<String, String> aliases = new HashMap<>();
|
||||||
|
|
||||||
// Should probably be switched to UUIDs at some point...
|
// Should probably be switched to UUIDs at some point...
|
||||||
@ -82,8 +99,16 @@ class ContributionsConnector extends GitHubConnector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getURLSuffix() {
|
public String getEndpoint() {
|
||||||
return "/contributors?per_page=100&page=" + page;
|
return "/contributors";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getParameters() {
|
||||||
|
Map<String, Object> parameters = new HashMap<>();
|
||||||
|
parameters.put("per_page", 100);
|
||||||
|
parameters.put("page", page);
|
||||||
|
return parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void computeContributors(@Nonnull JSONArray array) {
|
private void computeContributors(@Nonnull JSONArray array) {
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.core.services.github;
|
package io.github.thebusybiscuit.slimefun4.core.services.github;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
@ -35,8 +37,13 @@ class GitHubActivityConnector extends GitHubConnector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getURLSuffix() {
|
public String getEndpoint() {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getParameters() {
|
||||||
|
return new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,13 @@ import java.io.FileInputStream;
|
|||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.URL;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
||||||
|
|
||||||
import kong.unirest.HttpResponse;
|
import kong.unirest.HttpResponse;
|
||||||
import kong.unirest.JsonNode;
|
import kong.unirest.JsonNode;
|
||||||
@ -31,22 +32,49 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|||||||
abstract class GitHubConnector {
|
abstract class GitHubConnector {
|
||||||
|
|
||||||
private static final String API_URL = "https://api.github.com/";
|
private static final String API_URL = "https://api.github.com/";
|
||||||
|
private static final String USER_AGENT = "Slimefun4 (https://github.com/Slimefun)";
|
||||||
|
|
||||||
protected File file;
|
|
||||||
protected String repository;
|
|
||||||
protected final GitHubService github;
|
protected final GitHubService github;
|
||||||
|
private final String url;
|
||||||
|
private File file;
|
||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
/**
|
||||||
public GitHubConnector(GitHubService github, String repository) {
|
* This creates a new {@link GitHubConnector} for the given repository.
|
||||||
|
*
|
||||||
|
* @param github
|
||||||
|
* Our instance of {@link GitHubService}
|
||||||
|
* @param repository
|
||||||
|
* The repository we want to connect to
|
||||||
|
*/
|
||||||
|
GitHubConnector(@Nonnull GitHubService github, @Nonnull String repository) {
|
||||||
this.github = github;
|
this.github = github;
|
||||||
this.repository = repository;
|
this.url = API_URL + "repos/" + repository + getEndpoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns the name of our cache {@link File}.
|
||||||
|
*
|
||||||
|
* @return The cache {@link File} name
|
||||||
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public abstract String getFileName();
|
public abstract String getFileName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is our {@link URL} endpoint.
|
||||||
|
* It is the suffix of the {@link URL} we want to connect to.
|
||||||
|
*
|
||||||
|
* @return Our endpoint
|
||||||
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public abstract String getURLSuffix();
|
public abstract String getEndpoint();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This {@link Map} contains the query parameters for our {@link URL}.
|
||||||
|
*
|
||||||
|
* @return A {@link Map} with our query parameters
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
public abstract Map<String, Object> getParameters();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called when the connection finished successfully.
|
* This method is called when the connection finished successfully.
|
||||||
@ -63,7 +91,12 @@ abstract class GitHubConnector {
|
|||||||
// Don't do anything by default
|
// Don't do anything by default
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pullFile() {
|
/**
|
||||||
|
* This method will connect to GitHub and store the received data inside a local
|
||||||
|
* cache {@link File}.
|
||||||
|
* Make sure to call this method asynchronously!
|
||||||
|
*/
|
||||||
|
void download() {
|
||||||
file = new File("plugins/Slimefun/cache/github/" + getFileName() + ".json");
|
file = new File("plugins/Slimefun/cache/github/" + getFileName() + ".json");
|
||||||
|
|
||||||
if (github.isLoggingEnabled()) {
|
if (github.isLoggingEnabled()) {
|
||||||
@ -71,16 +104,19 @@ abstract class GitHubConnector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
HttpResponse<JsonNode> resp = Unirest.get(API_URL + "repos/" + repository + getURLSuffix())
|
// @formatter:off
|
||||||
.header("User-Agent", "Slimefun4 (https://github.com/Slimefun)")
|
HttpResponse<JsonNode> response = Unirest.get(url)
|
||||||
|
.queryString(getParameters())
|
||||||
|
.header("User-Agent", USER_AGENT)
|
||||||
.asJson();
|
.asJson();
|
||||||
|
// @formatter:on
|
||||||
|
|
||||||
if (resp.isSuccess()) {
|
if (response.isSuccess()) {
|
||||||
onSuccess(resp.getBody());
|
onSuccess(response.getBody());
|
||||||
writeCacheFile(resp.getBody());
|
writeCacheFile(response.getBody());
|
||||||
} else {
|
} else {
|
||||||
if (github.isLoggingEnabled()) {
|
if (github.isLoggingEnabled()) {
|
||||||
Slimefun.getLogger().log(Level.WARNING, "Failed to fetch {0}: {1} - {2}", new Object[] { repository + getURLSuffix(), resp.getStatus(), resp.getBody() });
|
Slimefun.getLogger().log(Level.WARNING, "Failed to fetch {0}: {1} - {2}", new Object[] { url, response.getStatus(), response.getBody() });
|
||||||
}
|
}
|
||||||
|
|
||||||
// It has the cached file, let's just read that then
|
// It has the cached file, let's just read that then
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.core.services.github;
|
package io.github.thebusybiscuit.slimefun4.core.services.github;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@ -50,8 +52,15 @@ class GitHubIssuesConnector extends GitHubConnector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getURLSuffix() {
|
public String getEndpoint() {
|
||||||
return "/issues?per_page=100";
|
return "/issues";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getParameters() {
|
||||||
|
Map<String, Object> parameters = new HashMap<>();
|
||||||
|
parameters.put("per_page", 100);
|
||||||
|
return parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,8 @@ public class GitHubService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void start(@Nonnull SlimefunPlugin plugin) {
|
public void start(@Nonnull SlimefunPlugin plugin) {
|
||||||
plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, new GitHubTask(this), 80L, 60 * 60 * 20L);
|
GitHubTask task = new GitHubTask(this);
|
||||||
|
plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, task, 80L, 60 * 60 * 20L);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.core.services.github;
|
package io.github.thebusybiscuit.slimefun4.core.services.github;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -38,10 +39,14 @@ class GitHubTask implements Runnable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
gitHubService.getConnectors().forEach(GitHubConnector::pullFile);
|
gitHubService.getConnectors().forEach(GitHubConnector::download);
|
||||||
grabTextures();
|
grabTextures();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will pull the skin textures for every {@link Contributor} and store
|
||||||
|
* the {@link UUID} and received skin inside a local cache {@link File}.
|
||||||
|
*/
|
||||||
private void grabTextures() {
|
private void grabTextures() {
|
||||||
// Store all queried usernames to prevent 429 responses for pinging the
|
// Store all queried usernames to prevent 429 responses for pinging the
|
||||||
// same URL twice in one run.
|
// same URL twice in one run.
|
||||||
|
@ -31,14 +31,14 @@ import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
|||||||
* This is an abstract parent class of {@link LocalizationService}.
|
* This is an abstract parent class of {@link LocalizationService}.
|
||||||
* There is not really much more I can say besides that...
|
* There is not really much more I can say besides that...
|
||||||
*
|
*
|
||||||
* @author TheBusyBiscui
|
* @author TheBusyBiscuit
|
||||||
*
|
*
|
||||||
* @see LocalizationService
|
* @see LocalizationService
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public abstract class SlimefunLocalization extends Localization implements Keyed {
|
public abstract class SlimefunLocalization extends Localization implements Keyed {
|
||||||
|
|
||||||
public SlimefunLocalization(@Nonnull SlimefunPlugin plugin) {
|
protected SlimefunLocalization(@Nonnull SlimefunPlugin plugin) {
|
||||||
super(plugin);
|
super(plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,6 +71,15 @@ public abstract class SlimefunLocalization extends Localization implements Keyed
|
|||||||
*/
|
*/
|
||||||
public abstract Language getDefaultLanguage();
|
public abstract Language getDefaultLanguage();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns whether a {@link Language} with the given id exists within
|
||||||
|
* the project resources.
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* The {@link Language} id
|
||||||
|
*
|
||||||
|
* @return Whether the project contains a {@link Language} with that id
|
||||||
|
*/
|
||||||
protected abstract boolean hasLanguage(@Nonnull String id);
|
protected abstract boolean hasLanguage(@Nonnull String id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,10 +91,23 @@ public abstract class SlimefunLocalization extends Localization implements Keyed
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
public abstract Collection<Language> getLanguages();
|
public abstract Collection<Language> getLanguages();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method adds a new {@link Language} with the given id and texture.
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* The {@link Language} id
|
||||||
|
* @param texture
|
||||||
|
* The texture of how this {@link Language} should be displayed
|
||||||
|
*/
|
||||||
protected abstract void addLanguage(@Nonnull String id, @Nonnull String texture);
|
protected abstract void addLanguage(@Nonnull String id, @Nonnull String texture);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will load every {@link SupportedLanguage} into memory.
|
||||||
|
* To be precise: It performs {@link #addLanguage(String, String)} for every
|
||||||
|
* value of {@link SupportedLanguage}.
|
||||||
|
*/
|
||||||
protected void loadEmbeddedLanguages() {
|
protected void loadEmbeddedLanguages() {
|
||||||
for (SupportedLanguage lang : SupportedLanguage.valuesCache) {
|
for (SupportedLanguage lang : SupportedLanguage.values()) {
|
||||||
if (lang.isReadyForRelease() || SlimefunPlugin.getUpdater().getBranch() != SlimefunBranch.STABLE) {
|
if (lang.isReadyForRelease() || SlimefunPlugin.getUpdater().getBranch() != SlimefunBranch.STABLE) {
|
||||||
addLanguage(lang.getLanguageId(), lang.getTexture());
|
addLanguage(lang.getLanguageId(), lang.getTexture());
|
||||||
}
|
}
|
||||||
|
@ -58,8 +58,6 @@ enum SupportedLanguage {
|
|||||||
MACEDONIAN("mk", false, "a0e0b0b5d87a855466980a101a757bcdb5f77d9f7287889f3efa998ee0472fc0"),
|
MACEDONIAN("mk", false, "a0e0b0b5d87a855466980a101a757bcdb5f77d9f7287889f3efa998ee0472fc0"),
|
||||||
TAGALOG("tl", true, "9306c0c1ce6a9c61bb42a572c49e6d0ed20e0e6b3d122cc64c339cbf78e9e937");
|
TAGALOG("tl", true, "9306c0c1ce6a9c61bb42a572c49e6d0ed20e0e6b3d122cc64c339cbf78e9e937");
|
||||||
|
|
||||||
public static final SupportedLanguage[] valuesCache = values();
|
|
||||||
|
|
||||||
private final String id;
|
private final String id;
|
||||||
private final boolean releaseReady;
|
private final boolean releaseReady;
|
||||||
private final String textureHash;
|
private final String textureHash;
|
||||||
@ -71,11 +69,22 @@ enum SupportedLanguage {
|
|||||||
this.textureHash = textureHash;
|
this.textureHash = textureHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns the id of this {@link Language}.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public String getLanguageId() {
|
public String getLanguageId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns whether this {@link SupportedLanguage} is "release-ready".
|
||||||
|
* A release-ready {@link Language} will be available in RC builds of Slimefun.
|
||||||
|
*
|
||||||
|
* @return Whether this {@link Language} is "release-ready"
|
||||||
|
*/
|
||||||
public boolean isReadyForRelease() {
|
public boolean isReadyForRelease() {
|
||||||
return releaseReady;
|
return releaseReady;
|
||||||
}
|
}
|
||||||
|
@ -120,6 +120,7 @@ public class Translators {
|
|||||||
// Translators - Chinese (Taiwan)
|
// Translators - Chinese (Taiwan)
|
||||||
addTranslator("BrineYT", "HeroBrineKing", SupportedLanguage.CHINESE_TAIWAN, true);
|
addTranslator("BrineYT", "HeroBrineKing", SupportedLanguage.CHINESE_TAIWAN, true);
|
||||||
addTranslator("mio9", SupportedLanguage.CHINESE_TAIWAN, true);
|
addTranslator("mio9", SupportedLanguage.CHINESE_TAIWAN, true);
|
||||||
|
addTranslator("ALiangLiang", SupportedLanguage.CHINESE_TAIWAN, true);
|
||||||
|
|
||||||
// Translators - Arabic
|
// Translators - Arabic
|
||||||
addTranslator("mohkamfer", "AgentBabbie", SupportedLanguage.ARABIC, false);
|
addTranslator("mohkamfer", "AgentBabbie", SupportedLanguage.ARABIC, false);
|
||||||
|
@ -101,9 +101,6 @@ public class ThirdPartyPluginService {
|
|||||||
// mcMMO Integration
|
// mcMMO Integration
|
||||||
if (isPluginInstalled("mcMMO")) {
|
if (isPluginInstalled("mcMMO")) {
|
||||||
try {
|
try {
|
||||||
// This makes sure that the FakeEvent interface is present.
|
|
||||||
// Class.forName("com.gmail.nossr50.events.fake.FakeEvent");
|
|
||||||
|
|
||||||
new McMMOIntegration(plugin);
|
new McMMOIntegration(plugin);
|
||||||
isMcMMOInstalled = true;
|
isMcMMOInstalled = true;
|
||||||
} catch (Exception | LinkageError x) {
|
} catch (Exception | LinkageError x) {
|
||||||
@ -170,7 +167,7 @@ public class ThirdPartyPluginService {
|
|||||||
* @return Whether this is a fake event
|
* @return Whether this is a fake event
|
||||||
*/
|
*/
|
||||||
public boolean isEventFaked(@Nonnull Event event) {
|
public boolean isEventFaked(@Nonnull Event event) {
|
||||||
// TODO: Change this to FakeEvent once the new mcMMO build was released
|
// This can be changed to "FakeEvent" in a later version
|
||||||
return isMcMMOInstalled && event instanceof FakeBlockBreakEvent;
|
return isMcMMOInstalled && event instanceof FakeBlockBreakEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,11 +175,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
|
|||||||
instance = this;
|
instance = this;
|
||||||
|
|
||||||
if (minecraftVersion == MinecraftVersion.UNIT_TEST) {
|
if (minecraftVersion == MinecraftVersion.UNIT_TEST) {
|
||||||
local = new LocalizationService(this, "", null);
|
onUnitTestStart();
|
||||||
gpsNetwork = new GPSNetwork();
|
|
||||||
networkManager = new NetworkManager(200);
|
|
||||||
command.register();
|
|
||||||
registry.load(config);
|
|
||||||
} else if (getServer().getPluginManager().isPluginEnabled("CS-CoreLib")) {
|
} else if (getServer().getPluginManager().isPluginEnabled("CS-CoreLib")) {
|
||||||
getLogger().log(Level.INFO, "CS-CoreLib was detected!");
|
getLogger().log(Level.INFO, "CS-CoreLib was detected!");
|
||||||
long timestamp = System.nanoTime();
|
long timestamp = System.nanoTime();
|
||||||
@ -222,7 +218,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
|
|||||||
networkSize = 1;
|
networkSize = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
networkManager = new NetworkManager(networkSize);
|
networkManager = new NetworkManager(networkSize, config.getBoolean("networks.enable-visualizer"));
|
||||||
|
|
||||||
// Setting up bStats
|
// Setting up bStats
|
||||||
new Thread(metricsService::start, "Slimefun Metrics").start();
|
new Thread(metricsService::start, "Slimefun Metrics").start();
|
||||||
@ -306,6 +302,14 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onUnitTestStart() {
|
||||||
|
local = new LocalizationService(this, "", null);
|
||||||
|
gpsNetwork = new GPSNetwork();
|
||||||
|
networkManager = new NetworkManager(200, true);
|
||||||
|
command.register();
|
||||||
|
registry.load(config);
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private String getStartupTime(long timestamp) {
|
private String getStartupTime(long timestamp) {
|
||||||
long ms = (System.nanoTime() - timestamp) / 1000000;
|
long ms = (System.nanoTime() - timestamp) / 1000000;
|
||||||
|
@ -215,7 +215,11 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation {
|
|||||||
|
|
||||||
ChatComponent component = new ChatComponent(ChatUtils.crop(ChatColor.RED, item.getItemName()) + "\n");
|
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.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 -> research(player, profile, item, research, category, page)));
|
component.setClickEvent(new ClickEvent(key, player ->
|
||||||
|
SlimefunPlugin.runSync(() ->
|
||||||
|
research.unlockFromGuide(this, player, profile, item, category, page)
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
items.add(component);
|
items.add(component);
|
||||||
} else {
|
} else {
|
||||||
@ -234,22 +238,6 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void research(Player p, PlayerProfile profile, SlimefunItem item, Research research, Category category, int page) {
|
|
||||||
SlimefunPlugin.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
|
@Override
|
||||||
public void openSearch(PlayerProfile profile, String input, boolean addToHistory) {
|
public void openSearch(PlayerProfile profile, String input, boolean addToHistory) {
|
||||||
// We need to write a book implementation for this at some point
|
// We need to write a book implementation for this at some point
|
||||||
|
@ -271,23 +271,12 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
|
|||||||
|
|
||||||
if (isSurvivalMode() && !Slimefun.hasPermission(p, sfitem, false)) {
|
if (isSurvivalMode() && !Slimefun.hasPermission(p, sfitem, false)) {
|
||||||
List<String> message = SlimefunPlugin.getPermissionsService().getLore(sfitem);
|
List<String> message = SlimefunPlugin.getPermissionsService().getLore(sfitem);
|
||||||
menu.addItem(index, new CustomItem(Material.BARRIER, sfitem.getItemName(), message.toArray(new String[0])));
|
menu.addItem(index, new CustomItem(ChestMenuUtils.getNoPermissionItem(), sfitem.getItemName(), message.toArray(new String[0])));
|
||||||
menu.addMenuClickHandler(index, ChestMenuUtils.getEmptyClickHandler());
|
menu.addMenuClickHandler(index, ChestMenuUtils.getEmptyClickHandler());
|
||||||
} else if (isSurvivalMode() && research != null && !profile.hasUnlocked(research)) {
|
} else if (isSurvivalMode() && research != null && !profile.hasUnlocked(research)) {
|
||||||
menu.addItem(index, new CustomItem(Material.BARRIER, ChatColor.WHITE + ItemUtils.getItemName(sfitem.getItem()), "&4&l" + SlimefunPlugin.getLocalization().getMessage(p, "guide.locked"), "", "&a> Click to unlock", "", "&7Cost: &b" + research.getCost() + " Level(s)"));
|
menu.addItem(index, new CustomItem(ChestMenuUtils.getNotResearchedItem(), ChatColor.WHITE + ItemUtils.getItemName(sfitem.getItem()), "&4&l" + SlimefunPlugin.getLocalization().getMessage(p, "guide.locked"), "", "&a> Click to unlock", "", "&7Cost: &b" + research.getCost() + " Level(s)"));
|
||||||
menu.addMenuClickHandler(index, (pl, slot, item, action) -> {
|
menu.addMenuClickHandler(index, (pl, slot, item, action) -> {
|
||||||
if (!SlimefunPlugin.getRegistry().getCurrentlyResearchingPlayers().contains(pl.getUniqueId())) {
|
research.unlockFromGuide(this, p, profile, sfitem, category, page);
|
||||||
if (research.canUnlock(pl)) {
|
|
||||||
if (profile.hasUnlocked(research)) {
|
|
||||||
openCategory(profile, category, page);
|
|
||||||
} else {
|
|
||||||
unlockItem(pl, sfitem, player -> openCategory(profile, category, page));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SlimefunPlugin.getLocalization().sendMessage(pl, "messages.not-enough-xp", true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -31,6 +31,9 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
|||||||
*/
|
*/
|
||||||
public class RadioactiveItem extends SlimefunItem implements Radioactive, NotPlaceable {
|
public class RadioactiveItem extends SlimefunItem implements Radioactive, NotPlaceable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the level of {@link Radioactivity} for this {@link SlimefunItem}
|
||||||
|
*/
|
||||||
private final Radioactivity radioactivity;
|
private final Radioactivity radioactivity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.implementation.items.androids;
|
package io.github.thebusybiscuit.slimefun4.implementation.items.androids;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This enum holds all the different types a {@link ProgrammableAndroid} can represent.
|
* This enum holds all the different types a {@link ProgrammableAndroid} can represent.
|
||||||
*
|
*
|
||||||
@ -55,7 +57,7 @@ public enum AndroidType {
|
|||||||
*/
|
*/
|
||||||
NON_FIGHTER;
|
NON_FIGHTER;
|
||||||
|
|
||||||
boolean isType(AndroidType type) {
|
boolean isType(@Nonnull AndroidType type) {
|
||||||
return type == NONE || type == this || (type == NON_FIGHTER && this != FIGHTER);
|
return type == NONE || type == this || (type == NON_FIGHTER && this != FIGHTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ public class FisherAndroid extends ProgrammableAndroid {
|
|||||||
|
|
||||||
if (ThreadLocalRandom.current().nextInt(100) < 10 * getTier()) {
|
if (ThreadLocalRandom.current().nextInt(100) < 10 * getTier()) {
|
||||||
ItemStack drop = fishingLoot.getRandom();
|
ItemStack drop = fishingLoot.getRandom();
|
||||||
menu.pushItem(drop, getOutputSlots());
|
menu.pushItem(drop.clone(), getOutputSlots());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import java.util.Map;
|
|||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.entity.Ageable;
|
import org.bukkit.entity.Ageable;
|
||||||
@ -20,126 +21,223 @@ import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
|
|||||||
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
||||||
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
||||||
|
|
||||||
enum Instruction {
|
/**
|
||||||
|
* This enum holds every {@link Instruction} for the {@link ProgrammableAndroid}
|
||||||
|
* added by Slimefun itself.
|
||||||
|
*
|
||||||
|
* @author TheBusyBiscuit
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public enum Instruction {
|
||||||
|
|
||||||
// Start and End Parts
|
/**
|
||||||
|
* This {@link Instruction} is the starting point of a {@link Script}.
|
||||||
|
*/
|
||||||
START(AndroidType.NONE, HeadTexture.SCRIPT_START),
|
START(AndroidType.NONE, HeadTexture.SCRIPT_START),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This {@link Instruction} is the end token of a {@link Script}.
|
||||||
|
* Once this {@link Instruction} is reached, the {@link Script} will start again.
|
||||||
|
*/
|
||||||
REPEAT(AndroidType.NONE, HeadTexture.SCRIPT_REPEAT),
|
REPEAT(AndroidType.NONE, HeadTexture.SCRIPT_REPEAT),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This {@link Instruction} will make the {@link ProgrammableAndroid} wait
|
||||||
|
* for one Slimefun tick.
|
||||||
|
*/
|
||||||
WAIT(AndroidType.NONE, HeadTexture.SCRIPT_WAIT),
|
WAIT(AndroidType.NONE, HeadTexture.SCRIPT_WAIT),
|
||||||
|
|
||||||
// Movement
|
/**
|
||||||
|
* This will make the {@link ProgrammableAndroid} go forward.
|
||||||
|
*/
|
||||||
GO_FORWARD(AndroidType.NON_FIGHTER, HeadTexture.SCRIPT_FORWARD, (android, b, inv, face) -> {
|
GO_FORWARD(AndroidType.NON_FIGHTER, HeadTexture.SCRIPT_FORWARD, (android, b, inv, face) -> {
|
||||||
Block target = b.getRelative(face);
|
Block target = b.getRelative(face);
|
||||||
android.move(b, face, target);
|
android.move(b, face, target);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will make the {@link ProgrammableAndroid} go up.
|
||||||
|
*/
|
||||||
GO_UP(AndroidType.NON_FIGHTER, HeadTexture.SCRIPT_UP, (android, b, inv, face) -> {
|
GO_UP(AndroidType.NON_FIGHTER, HeadTexture.SCRIPT_UP, (android, b, inv, face) -> {
|
||||||
Block target = b.getRelative(BlockFace.UP);
|
Block target = b.getRelative(BlockFace.UP);
|
||||||
android.move(b, face, target);
|
android.move(b, face, target);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will make the {@link ProgrammableAndroid} go down.
|
||||||
|
*/
|
||||||
GO_DOWN(AndroidType.NON_FIGHTER, HeadTexture.SCRIPT_DOWN, (android, b, inv, face) -> {
|
GO_DOWN(AndroidType.NON_FIGHTER, HeadTexture.SCRIPT_DOWN, (android, b, inv, face) -> {
|
||||||
Block target = b.getRelative(BlockFace.DOWN);
|
Block target = b.getRelative(BlockFace.DOWN);
|
||||||
android.move(b, face, target);
|
android.move(b, face, target);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// Directions
|
/**
|
||||||
|
* This will make the {@link ProgrammableAndroid} rotate to the left side.
|
||||||
|
*/
|
||||||
TURN_LEFT(AndroidType.NONE, HeadTexture.SCRIPT_LEFT, (android, b, inv, face) -> {
|
TURN_LEFT(AndroidType.NONE, HeadTexture.SCRIPT_LEFT, (android, b, inv, face) -> {
|
||||||
int mod = -1;
|
int mod = -1;
|
||||||
android.rotate(b, face, mod);
|
android.rotate(b, face, mod);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will make the {@link ProgrammableAndroid} rotate to the right side.
|
||||||
|
*/
|
||||||
TURN_RIGHT(AndroidType.NONE, HeadTexture.SCRIPT_RIGHT, (android, b, inv, face) -> {
|
TURN_RIGHT(AndroidType.NONE, HeadTexture.SCRIPT_RIGHT, (android, b, inv, face) -> {
|
||||||
int mod = 1;
|
int mod = 1;
|
||||||
android.rotate(b, face, mod);
|
android.rotate(b, face, mod);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// Action - Pickaxe
|
/**
|
||||||
|
* This will make a {@link MinerAndroid} dig the {@link Block} above.
|
||||||
|
*/
|
||||||
DIG_UP(AndroidType.MINER, HeadTexture.SCRIPT_DIG_UP, (android, b, inv, face) -> {
|
DIG_UP(AndroidType.MINER, HeadTexture.SCRIPT_DIG_UP, (android, b, inv, face) -> {
|
||||||
Block target = b.getRelative(BlockFace.UP);
|
Block target = b.getRelative(BlockFace.UP);
|
||||||
android.dig(b, inv, target);
|
android.dig(b, inv, target);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will make a {@link MinerAndroid} dig the {@link Block} ahead.
|
||||||
|
*/
|
||||||
DIG_FORWARD(AndroidType.MINER, HeadTexture.SCRIPT_DIG_FORWARD, (android, b, inv, face) -> {
|
DIG_FORWARD(AndroidType.MINER, HeadTexture.SCRIPT_DIG_FORWARD, (android, b, inv, face) -> {
|
||||||
Block target = b.getRelative(face);
|
Block target = b.getRelative(face);
|
||||||
android.dig(b, inv, target);
|
android.dig(b, inv, target);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will make a {@link MinerAndroid} dig the {@link Block} below.
|
||||||
|
*/
|
||||||
DIG_DOWN(AndroidType.MINER, HeadTexture.SCRIPT_DIG_DOWN, (android, b, inv, face) -> {
|
DIG_DOWN(AndroidType.MINER, HeadTexture.SCRIPT_DIG_DOWN, (android, b, inv, face) -> {
|
||||||
Block target = b.getRelative(BlockFace.DOWN);
|
Block target = b.getRelative(BlockFace.DOWN);
|
||||||
android.dig(b, inv, target);
|
android.dig(b, inv, target);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will make a {@link MinerAndroid} dig the {@link Block} above
|
||||||
|
* and then move itself to that new {@link Location}.
|
||||||
|
*/
|
||||||
MOVE_AND_DIG_UP(AndroidType.MINER, HeadTexture.SCRIPT_DIG_UP, (android, b, inv, face) -> {
|
MOVE_AND_DIG_UP(AndroidType.MINER, HeadTexture.SCRIPT_DIG_UP, (android, b, inv, face) -> {
|
||||||
Block target = b.getRelative(BlockFace.UP);
|
Block target = b.getRelative(BlockFace.UP);
|
||||||
android.moveAndDig(b, inv, face, target);
|
android.moveAndDig(b, inv, face, target);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will make a {@link MinerAndroid} dig the {@link Block} ahead
|
||||||
|
* and then move itself to that new {@link Location}.
|
||||||
|
*/
|
||||||
MOVE_AND_DIG_FORWARD(AndroidType.MINER, HeadTexture.SCRIPT_DIG_FORWARD, (android, b, inv, face) -> {
|
MOVE_AND_DIG_FORWARD(AndroidType.MINER, HeadTexture.SCRIPT_DIG_FORWARD, (android, b, inv, face) -> {
|
||||||
Block target = b.getRelative(face);
|
Block target = b.getRelative(face);
|
||||||
android.moveAndDig(b, inv, face, target);
|
android.moveAndDig(b, inv, face, target);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will make a {@link MinerAndroid} dig the {@link Block} below
|
||||||
|
* and then move itself to that new {@link Location}.
|
||||||
|
*/
|
||||||
MOVE_AND_DIG_DOWN(AndroidType.MINER, HeadTexture.SCRIPT_DIG_DOWN, (android, b, inv, face) -> {
|
MOVE_AND_DIG_DOWN(AndroidType.MINER, HeadTexture.SCRIPT_DIG_DOWN, (android, b, inv, face) -> {
|
||||||
Block target = b.getRelative(BlockFace.DOWN);
|
Block target = b.getRelative(BlockFace.DOWN);
|
||||||
android.moveAndDig(b, inv, face, target);
|
android.moveAndDig(b, inv, face, target);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// Action - Sword
|
/**
|
||||||
|
* This will make a {@link ButcherAndroid} attack any {@link LivingEntity}
|
||||||
|
* ahead of them.
|
||||||
|
*/
|
||||||
ATTACK_MOBS_ANIMALS(AndroidType.FIGHTER, HeadTexture.SCRIPT_ATTACK, (android, b, inv, face) -> {
|
ATTACK_MOBS_ANIMALS(AndroidType.FIGHTER, HeadTexture.SCRIPT_ATTACK, (android, b, inv, face) -> {
|
||||||
Predicate<LivingEntity> predicate = e -> true;
|
Predicate<LivingEntity> predicate = e -> true;
|
||||||
android.attack(b, face, predicate);
|
android.attack(b, face, predicate);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will make a {@link ButcherAndroid} attack any {@link Monster}
|
||||||
|
* ahead of them.
|
||||||
|
*/
|
||||||
ATTACK_MOBS(AndroidType.FIGHTER, HeadTexture.SCRIPT_ATTACK, (android, b, inv, face) -> {
|
ATTACK_MOBS(AndroidType.FIGHTER, HeadTexture.SCRIPT_ATTACK, (android, b, inv, face) -> {
|
||||||
Predicate<LivingEntity> predicate = e -> e instanceof Monster;
|
Predicate<LivingEntity> predicate = e -> e instanceof Monster;
|
||||||
android.attack(b, face, predicate);
|
android.attack(b, face, predicate);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will make a {@link ButcherAndroid} attack any {@link Animals Animal}
|
||||||
|
* ahead of them.
|
||||||
|
*/
|
||||||
ATTACK_ANIMALS(AndroidType.FIGHTER, HeadTexture.SCRIPT_ATTACK, (android, b, inv, face) -> {
|
ATTACK_ANIMALS(AndroidType.FIGHTER, HeadTexture.SCRIPT_ATTACK, (android, b, inv, face) -> {
|
||||||
Predicate<LivingEntity> predicate = e -> e instanceof Animals;
|
Predicate<LivingEntity> predicate = e -> e instanceof Animals;
|
||||||
android.attack(b, face, predicate);
|
android.attack(b, face, predicate);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will make a {@link ButcherAndroid} attack any <strong>adult</strong>
|
||||||
|
* {@link Animals Animal} ahead of them.
|
||||||
|
*/
|
||||||
ATTACK_ANIMALS_ADULT(AndroidType.FIGHTER, HeadTexture.SCRIPT_ATTACK, (android, b, inv, face) -> {
|
ATTACK_ANIMALS_ADULT(AndroidType.FIGHTER, HeadTexture.SCRIPT_ATTACK, (android, b, inv, face) -> {
|
||||||
Predicate<LivingEntity> predicate = e -> e instanceof Animals && e instanceof Ageable && ((Ageable) e).isAdult();
|
Predicate<LivingEntity> predicate = e -> e instanceof Animals && ((Ageable) e).isAdult();
|
||||||
android.attack(b, face, predicate);
|
android.attack(b, face, predicate);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// Action - Axe
|
/**
|
||||||
|
* This will make a {@link WoodcutterAndroid} chop down the tree in front of them.
|
||||||
|
*/
|
||||||
CHOP_TREE(AndroidType.WOODCUTTER, HeadTexture.SCRIPT_CHOP_TREE),
|
CHOP_TREE(AndroidType.WOODCUTTER, HeadTexture.SCRIPT_CHOP_TREE),
|
||||||
|
|
||||||
// Action - Fishing Rod
|
/**
|
||||||
|
* This {@link Instruction} makes a {@link FisherAndroid} try to catch fish from
|
||||||
|
* the water below.
|
||||||
|
*/
|
||||||
CATCH_FISH(AndroidType.FISHERMAN, HeadTexture.SCRIPT_FISH, (android, b, inv, face) -> android.fish(b, inv)),
|
CATCH_FISH(AndroidType.FISHERMAN, HeadTexture.SCRIPT_FISH, (android, b, inv, face) -> android.fish(b, inv)),
|
||||||
|
|
||||||
// Action - Hoe
|
/**
|
||||||
|
* This {@link Instruction} will make a {@link FarmerAndroid} try to harvest
|
||||||
|
* the {@link Block} in front of them.
|
||||||
|
*/
|
||||||
FARM_FORWARD(AndroidType.FARMER, HeadTexture.SCRIPT_FARM_FORWARD, (android, b, inv, face) -> {
|
FARM_FORWARD(AndroidType.FARMER, HeadTexture.SCRIPT_FARM_FORWARD, (android, b, inv, face) -> {
|
||||||
Block target = b.getRelative(face);
|
Block target = b.getRelative(face);
|
||||||
android.farm(inv, target);
|
android.farm(inv, target);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This {@link Instruction} will make a {@link FarmerAndroid} try to harvest
|
||||||
|
* the {@link Block} below.
|
||||||
|
*/
|
||||||
FARM_DOWN(AndroidType.FARMER, HeadTexture.SCRIPT_FARM_DOWN, (android, b, inv, face) -> {
|
FARM_DOWN(AndroidType.FARMER, HeadTexture.SCRIPT_FARM_DOWN, (android, b, inv, face) -> {
|
||||||
Block target = b.getRelative(BlockFace.DOWN);
|
Block target = b.getRelative(BlockFace.DOWN);
|
||||||
android.farm(inv, target);
|
android.farm(inv, target);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// Action - ExoticGarden
|
/**
|
||||||
|
* This {@link Instruction} will make a {@link FarmerAndroid} try to harvest
|
||||||
|
* the {@link Block} in front of them.
|
||||||
|
*
|
||||||
|
* <strong>This includes plants from ExoticGarden.</strong>
|
||||||
|
*/
|
||||||
FARM_EXOTIC_FORWARD(AndroidType.ADVANCED_FARMER, HeadTexture.SCRIPT_FARM_FORWARD, (android, b, inv, face) -> {
|
FARM_EXOTIC_FORWARD(AndroidType.ADVANCED_FARMER, HeadTexture.SCRIPT_FARM_FORWARD, (android, b, inv, face) -> {
|
||||||
Block target = b.getRelative(face);
|
Block target = b.getRelative(face);
|
||||||
android.exoticFarm(inv, target);
|
android.exoticFarm(inv, target);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This {@link Instruction} will make a {@link FarmerAndroid} try to harvest
|
||||||
|
* the {@link Block} below.
|
||||||
|
*
|
||||||
|
* <strong>This includes plants from ExoticGarden.</strong>
|
||||||
|
*/
|
||||||
FARM_EXOTIC_DOWN(AndroidType.ADVANCED_FARMER, HeadTexture.SCRIPT_FARM_DOWN, (android, b, inv, face) -> {
|
FARM_EXOTIC_DOWN(AndroidType.ADVANCED_FARMER, HeadTexture.SCRIPT_FARM_DOWN, (android, b, inv, face) -> {
|
||||||
Block target = b.getRelative(BlockFace.DOWN);
|
Block target = b.getRelative(BlockFace.DOWN);
|
||||||
android.exoticFarm(inv, target);
|
android.exoticFarm(inv, target);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// Action - Interface
|
/**
|
||||||
|
* This {@link Instruction} will force the {@link ProgrammableAndroid} to push their
|
||||||
|
* items into an {@link AndroidInterface} ahead of them.
|
||||||
|
*/
|
||||||
INTERFACE_ITEMS(AndroidType.NONE, HeadTexture.SCRIPT_PUSH_ITEMS, (android, b, inv, face) -> {
|
INTERFACE_ITEMS(AndroidType.NONE, HeadTexture.SCRIPT_PUSH_ITEMS, (android, b, inv, face) -> {
|
||||||
Block target = b.getRelative(face);
|
Block target = b.getRelative(face);
|
||||||
android.depositItems(inv, target);
|
android.depositItems(inv, target);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This {@link Instruction} will force the {@link ProgrammableAndroid} to pull
|
||||||
|
* fuel from an {@link AndroidInterface} ahead of them.
|
||||||
|
*/
|
||||||
INTERFACE_FUEL(AndroidType.NONE, HeadTexture.SCRIPT_PULL_FUEL, (android, b, inv, face) -> {
|
INTERFACE_FUEL(AndroidType.NONE, HeadTexture.SCRIPT_PULL_FUEL, (android, b, inv, face) -> {
|
||||||
Block target = b.getRelative(face);
|
Block target = b.getRelative(face);
|
||||||
android.refuel(inv, target);
|
android.refuel(inv, target);
|
||||||
|
@ -58,6 +58,7 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.interfaces.InventoryBlock;
|
|||||||
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
|
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler;
|
import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler;
|
||||||
import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
||||||
|
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
||||||
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
|
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
|
||||||
@ -69,6 +70,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
|
|||||||
private static final int[] BORDER = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 18, 24, 25, 26, 27, 33, 35, 36, 42, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53 };
|
private static final int[] BORDER = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 18, 24, 25, 26, 27, 33, 35, 36, 42, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53 };
|
||||||
private static final int[] OUTPUT_BORDER = { 10, 11, 12, 13, 14, 19, 23, 28, 32, 37, 38, 39, 40, 41 };
|
private static final int[] OUTPUT_BORDER = { 10, 11, 12, 13, 14, 19, 23, 28, 32, 37, 38, 39, 40, 41 };
|
||||||
private static final String DEFAULT_SCRIPT = "START-TURN_LEFT-REPEAT";
|
private static final String DEFAULT_SCRIPT = "START-TURN_LEFT-REPEAT";
|
||||||
|
private static final int MAX_SCRIPT_LENGTH = 54;
|
||||||
|
|
||||||
protected final List<MachineFuel> fuelTypes = new ArrayList<>();
|
protected final List<MachineFuel> fuelTypes = new ArrayList<>();
|
||||||
protected final String texture;
|
protected final String texture;
|
||||||
@ -407,19 +409,23 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
|
|||||||
} else {
|
} else {
|
||||||
Script script = scripts.get(target);
|
Script script = scripts.get(target);
|
||||||
menu.addItem(index, script.getAsItemStack(this, p), (player, slot, stack, action) -> {
|
menu.addItem(index, script.getAsItemStack(this, p), (player, slot, stack, action) -> {
|
||||||
if (action.isShiftClicked()) {
|
try {
|
||||||
if (script.isAuthor(player)) {
|
if (action.isShiftClicked()) {
|
||||||
SlimefunPlugin.getLocalization().sendMessage(player, "android.scripts.rating.own", true);
|
if (script.isAuthor(player)) {
|
||||||
} else if (script.canRate(player)) {
|
SlimefunPlugin.getLocalization().sendMessage(player, "android.scripts.rating.own", true);
|
||||||
script.rate(player, !action.isRightClicked());
|
} else if (script.canRate(player)) {
|
||||||
openScriptDownloader(player, b, page);
|
script.rate(player, !action.isRightClicked());
|
||||||
} else {
|
openScriptDownloader(player, b, page);
|
||||||
SlimefunPlugin.getLocalization().sendMessage(player, "android.scripts.rating.already", true);
|
} else {
|
||||||
|
SlimefunPlugin.getLocalization().sendMessage(player, "android.scripts.rating.already", true);
|
||||||
|
}
|
||||||
|
} else if (!action.isRightClicked()) {
|
||||||
|
script.download();
|
||||||
|
setScript(b.getLocation(), script.getSourceCode());
|
||||||
|
openScriptEditor(player, b);
|
||||||
}
|
}
|
||||||
} else if (!action.isRightClicked()) {
|
} catch (Exception x) {
|
||||||
script.download();
|
Slimefun.getLogger().log(Level.SEVERE, "An Exception was thrown when a User tried to download a Script!", x);
|
||||||
setScript(b.getLocation(), script.getSourceCode());
|
|
||||||
openScriptEditor(player, b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -534,12 +540,19 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
protected String getScript(@Nonnull Location l) {
|
public String getScript(@Nonnull Location l) {
|
||||||
|
Validate.notNull(l, "Location for android not specified");
|
||||||
String script = BlockStorage.getLocationInfo(l, "script");
|
String script = BlockStorage.getLocationInfo(l, "script");
|
||||||
return script != null ? script : DEFAULT_SCRIPT;
|
return script != null ? script : DEFAULT_SCRIPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setScript(@Nonnull Location l, @Nonnull String script) {
|
public void setScript(@Nonnull Location l, @Nonnull String script) {
|
||||||
|
Validate.notNull(l, "Location for android not specified");
|
||||||
|
Validate.notNull(script, "No script given");
|
||||||
|
Validate.isTrue(script.startsWith(Instruction.START.name() + '-'), "A script must begin with a 'START' token.");
|
||||||
|
Validate.isTrue(script.endsWith('-' + Instruction.REPEAT.name()), "A script must end with a 'REPEAT' token.");
|
||||||
|
Validate.isTrue(PatternUtils.DASH.split(script).length <= MAX_SCRIPT_LENGTH, "Scripts may not have more than " + MAX_SCRIPT_LENGTH + " segments");
|
||||||
|
|
||||||
BlockStorage.addBlockInfo(l, "script", script);
|
BlockStorage.addBlockInfo(l, "script", script);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -794,12 +807,8 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void constructMenu(@Nonnull BlockMenuPreset preset) {
|
private void constructMenu(@Nonnull BlockMenuPreset preset) {
|
||||||
for (int i : BORDER) {
|
preset.drawBackground(BORDER);
|
||||||
preset.addItem(i, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler());
|
preset.drawBackground(ChestMenuUtils.getOutputSlotTexture(), OUTPUT_BORDER);
|
||||||
}
|
|
||||||
for (int i : OUTPUT_BORDER) {
|
|
||||||
preset.addItem(i, ChestMenuUtils.getOutputSlotTexture(), ChestMenuUtils.getEmptyClickHandler());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i : getOutputSlots()) {
|
for (int i : getOutputSlots()) {
|
||||||
preset.addMenuClickHandler(i, new AdvancedMenuClickHandler() {
|
preset.addMenuClickHandler(i, new AdvancedMenuClickHandler() {
|
||||||
@ -828,7 +837,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void move(Block b, BlockFace face, Block block) {
|
protected void move(Block b, BlockFace face, Block block) {
|
||||||
if (block.getY() > 0 && block.getY() < block.getWorld().getMaxHeight() && (block.getType() == Material.AIR || block.getType() == Material.CAVE_AIR)) {
|
if (block.getY() > 0 && block.getY() < block.getWorld().getMaxHeight() && block.isEmpty()) {
|
||||||
BlockData blockData = Material.PLAYER_HEAD.createBlockData(data -> {
|
BlockData blockData = Material.PLAYER_HEAD.createBlockData(data -> {
|
||||||
if (data instanceof Rotatable) {
|
if (data instanceof Rotatable) {
|
||||||
Rotatable rotatable = ((Rotatable) data);
|
Rotatable rotatable = ((Rotatable) data);
|
||||||
|
@ -130,18 +130,19 @@ public final class Script {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
ItemStack getAsItemStack(@Nonnull ProgrammableAndroid android, @Nonnull Player p) {
|
ItemStack getAsItemStack(@Nonnull ProgrammableAndroid android, @Nonnull Player p) {
|
||||||
List<String> lore = new LinkedList<>();
|
List<String> lore = new LinkedList<>();
|
||||||
lore.add("&7by &r" + getAuthor());
|
lore.add("&7by &f" + getAuthor());
|
||||||
lore.add("");
|
lore.add("");
|
||||||
lore.add("&7Downloads: &r" + getDownloads());
|
lore.add("&7Downloads: &f" + getDownloads());
|
||||||
lore.add("&7Rating: " + getScriptRatingPercentage());
|
lore.add("&7Rating: " + getScriptRatingPercentage());
|
||||||
lore.add("&a" + getUpvotes() + " \u263A &7| &4\u2639 " + getDownvotes());
|
lore.add("&a" + getUpvotes() + " \u263A &7| &4\u2639 " + getDownvotes());
|
||||||
lore.add("");
|
lore.add("");
|
||||||
lore.add("&eLeft Click &rto download this Script");
|
lore.add("&eLeft Click &fto download this Script");
|
||||||
lore.add("&4(This will override your current Script)");
|
lore.add("&4(This will override your current Script)");
|
||||||
|
|
||||||
if (canRate(p)) {
|
if (canRate(p)) {
|
||||||
lore.add("&eShift + Left Click &rto leave a positive Rating");
|
lore.add("");
|
||||||
lore.add("&eShift + Right Click &rto leave a negative Rating");
|
lore.add("&eShift + Left Click &fto leave a positive Rating");
|
||||||
|
lore.add("&eShift + Right Click &fto leave a negative Rating");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new CustomItem(android.getItem(), "&b" + getName(), lore.toArray(new String[0]));
|
return new CustomItem(android.getItem(), "&b" + getName(), lore.toArray(new String[0]));
|
||||||
|
@ -11,7 +11,7 @@ import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
|
|||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.ChatUtils;
|
import io.github.thebusybiscuit.slimefun4.utils.ChatUtils;
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
|
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.ColoredMaterials;
|
import io.github.thebusybiscuit.slimefun4.utils.ColoredMaterial;
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
|
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
|
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
|
||||||
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
|
||||||
@ -100,7 +100,7 @@ abstract class AbstractCargoNode extends SlimefunItem {
|
|||||||
menu.replaceExistingItem(slotCurrent, new CustomItem(HeadTexture.CHEST_TERMINAL.getAsItemStack(), "&bChannel ID: &3" + (channel + 1)));
|
menu.replaceExistingItem(slotCurrent, new CustomItem(HeadTexture.CHEST_TERMINAL.getAsItemStack(), "&bChannel ID: &3" + (channel + 1)));
|
||||||
menu.addMenuClickHandler(slotCurrent, ChestMenuUtils.getEmptyClickHandler());
|
menu.addMenuClickHandler(slotCurrent, ChestMenuUtils.getEmptyClickHandler());
|
||||||
} else {
|
} else {
|
||||||
menu.replaceExistingItem(slotCurrent, new CustomItem(ColoredMaterials.WOOL.get(channel), "&bChannel ID: &3" + (channel + 1)));
|
menu.replaceExistingItem(slotCurrent, new CustomItem(ColoredMaterial.WOOL.get(channel), "&bChannel ID: &3" + (channel + 1)));
|
||||||
menu.addMenuClickHandler(slotCurrent, ChestMenuUtils.getEmptyClickHandler());
|
menu.addMenuClickHandler(slotCurrent, ChestMenuUtils.getEmptyClickHandler());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.implementation.items.cargo;
|
package io.github.thebusybiscuit.slimefun4.implementation.items.cargo;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
@ -107,22 +109,12 @@ public class ReactorAccessPort extends SlimefunItem {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void constructMenu(BlockMenuPreset preset) {
|
private void constructMenu(@Nonnull BlockMenuPreset preset) {
|
||||||
for (int i : background) {
|
preset.drawBackground(ChestMenuUtils.getBackground(), background);
|
||||||
preset.addItem(i, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i : fuelBorder) {
|
preset.drawBackground(new CustomItem(Material.LIME_STAINED_GLASS_PANE, " "), fuelBorder);
|
||||||
preset.addItem(i, new CustomItem(new ItemStack(Material.LIME_STAINED_GLASS_PANE), " "), ChestMenuUtils.getEmptyClickHandler());
|
preset.drawBackground(new CustomItem(Material.CYAN_STAINED_GLASS_PANE, " "), inputBorder);
|
||||||
}
|
preset.drawBackground(new CustomItem(Material.GREEN_STAINED_GLASS_PANE, " "), outputBorder);
|
||||||
|
|
||||||
for (int i : inputBorder) {
|
|
||||||
preset.addItem(i, new CustomItem(new ItemStack(Material.CYAN_STAINED_GLASS_PANE), " "), ChestMenuUtils.getEmptyClickHandler());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i : outputBorder) {
|
|
||||||
preset.addItem(i, new CustomItem(new ItemStack(Material.GREEN_STAINED_GLASS_PANE), " "), ChestMenuUtils.getEmptyClickHandler());
|
|
||||||
}
|
|
||||||
|
|
||||||
preset.addItem(1, new CustomItem(SlimefunItems.URANIUM, "&7Fuel Slot", "", "&rThis Slot accepts radioactive Fuel such as:", "&2Uranium &ror &aNeptunium"), ChestMenuUtils.getEmptyClickHandler());
|
preset.addItem(1, new CustomItem(SlimefunItems.URANIUM, "&7Fuel Slot", "", "&rThis Slot accepts radioactive Fuel such as:", "&2Uranium &ror &aNeptunium"), ChestMenuUtils.getEmptyClickHandler());
|
||||||
preset.addItem(22, new CustomItem(SlimefunItems.PLUTONIUM, "&7Byproduct Slot", "", "&rThis Slot contains the Reactor's Byproduct", "&rsuch as &aNeptunium &ror &7Plutonium"), ChestMenuUtils.getEmptyClickHandler());
|
preset.addItem(22, new CustomItem(SlimefunItems.PLUTONIUM, "&7Byproduct Slot", "", "&rThis Slot contains the Reactor's Byproduct", "&rsuch as &aNeptunium &ror &7Plutonium"), ChestMenuUtils.getEmptyClickHandler());
|
||||||
|
@ -13,7 +13,7 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator;
|
|||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
public abstract class BioGenerator extends AGenerator {
|
public class BioGenerator extends AGenerator {
|
||||||
|
|
||||||
public BioGenerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public BioGenerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
|
@ -12,7 +12,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public abstract class CoalGenerator extends AGenerator {
|
public class CoalGenerator extends AGenerator {
|
||||||
|
|
||||||
public CoalGenerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public CoalGenerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
|
@ -10,7 +10,7 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator;
|
|||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
public abstract class CombustionGenerator extends AGenerator {
|
public class CombustionGenerator extends AGenerator {
|
||||||
|
|
||||||
public CombustionGenerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public CombustionGenerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
|
@ -9,7 +9,7 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator;
|
|||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
public abstract class LavaGenerator extends AGenerator {
|
public class LavaGenerator extends AGenerator {
|
||||||
|
|
||||||
public LavaGenerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public LavaGenerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
|
@ -10,7 +10,7 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator;
|
|||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
public abstract class MagnesiumGenerator extends AGenerator {
|
public class MagnesiumGenerator extends AGenerator {
|
||||||
|
|
||||||
public MagnesiumGenerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public MagnesiumGenerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
|
@ -66,17 +66,9 @@ public abstract class AbstractEntityAssembler<T extends Entity> extends SimpleSl
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init() {
|
public void init() {
|
||||||
for (int i : border) {
|
drawBackground(border);
|
||||||
addItem(i, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler());
|
drawBackground(new CustomItem(getHeadBorder(), " "), headBorder);
|
||||||
}
|
drawBackground(new CustomItem(getBodyBorder(), " "), bodyBorder);
|
||||||
|
|
||||||
for (int i : headBorder) {
|
|
||||||
addItem(i, new CustomItem(getHeadBorder(), " "), ChestMenuUtils.getEmptyClickHandler());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i : bodyBorder) {
|
|
||||||
addItem(i, new CustomItem(getBodyBorder(), " "), ChestMenuUtils.getEmptyClickHandler());
|
|
||||||
}
|
|
||||||
|
|
||||||
constructMenu(this);
|
constructMenu(this);
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
|||||||
* @author TheBusyBiscuit
|
* @author TheBusyBiscuit
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public abstract class AutoAnvil extends AContainer {
|
public class AutoAnvil extends AContainer {
|
||||||
|
|
||||||
private final int repairFactor;
|
private final int repairFactor;
|
||||||
|
|
||||||
@ -36,11 +36,6 @@ public abstract class AutoAnvil extends AContainer {
|
|||||||
return new ItemStack(Material.IRON_PICKAXE);
|
return new ItemStack(Material.IRON_PICKAXE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSpeed() {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMachineIdentifier() {
|
public String getMachineIdentifier() {
|
||||||
return "AUTO_ANVIL";
|
return "AUTO_ANVIL";
|
||||||
|
@ -3,6 +3,8 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machine
|
|||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.PotionMeta;
|
import org.bukkit.inventory.meta.PotionMeta;
|
||||||
@ -24,7 +26,7 @@ import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
|||||||
* @author Linox
|
* @author Linox
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public abstract class AutoBrewer extends AContainer {
|
public class AutoBrewer extends AContainer {
|
||||||
|
|
||||||
private static final Map<Material, PotionType> potionRecipes = new EnumMap<>(Material.class);
|
private static final Map<Material, PotionType> potionRecipes = new EnumMap<>(Material.class);
|
||||||
private static final Map<PotionType, PotionType> fermentations = new EnumMap<>(PotionType.class);
|
private static final Map<PotionType, PotionType> fermentations = new EnumMap<>(PotionType.class);
|
||||||
@ -143,7 +145,7 @@ public abstract class AutoBrewer extends AContainer {
|
|||||||
*
|
*
|
||||||
* @return Whether this {@link Material} is a valid potion
|
* @return Whether this {@link Material} is a valid potion
|
||||||
*/
|
*/
|
||||||
private boolean isPotion(Material mat) {
|
private boolean isPotion(@Nonnull Material mat) {
|
||||||
return mat == Material.POTION || mat == Material.SPLASH_POTION || mat == Material.LINGERING_POTION;
|
return mat == Material.POTION || mat == Material.SPLASH_POTION || mat == Material.LINGERING_POTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,18 +154,8 @@ public abstract class AutoBrewer extends AContainer {
|
|||||||
return new ItemStack(Material.FISHING_ROD);
|
return new ItemStack(Material.FISHING_ROD);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getEnergyConsumption() {
|
|
||||||
return 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMachineIdentifier() {
|
public String getMachineIdentifier() {
|
||||||
return "AUTO_BREWER";
|
return "AUTO_BREWER";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCapacity() {
|
|
||||||
return 128;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -51,16 +51,6 @@ public class AutoDisenchanter extends AContainer {
|
|||||||
return new ItemStack(Material.DIAMOND_CHESTPLATE);
|
return new ItemStack(Material.DIAMOND_CHESTPLATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getEnergyConsumption() {
|
|
||||||
return 9;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCapacity() {
|
|
||||||
return 128;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MachineRecipe findNextRecipe(BlockMenu menu) {
|
protected MachineRecipe findNextRecipe(BlockMenu menu) {
|
||||||
Map<Enchantment, Integer> enchantments = new HashMap<>();
|
Map<Enchantment, Integer> enchantments = new HashMap<>();
|
||||||
@ -158,11 +148,6 @@ public class AutoDisenchanter extends AContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSpeed() {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMachineIdentifier() {
|
public String getMachineIdentifier() {
|
||||||
return "AUTO_DISENCHANTER";
|
return "AUTO_DISENCHANTER";
|
||||||
|
@ -101,21 +101,6 @@ public class AutoDrier extends AContainer implements RecipeDisplayItem {
|
|||||||
return recipeList;
|
return recipeList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getEnergyConsumption() {
|
|
||||||
return 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSpeed() {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCapacity() {
|
|
||||||
return 128;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMachineIdentifier() {
|
public String getMachineIdentifier() {
|
||||||
return "AUTO_DRIER";
|
return "AUTO_DRIER";
|
||||||
|
@ -37,16 +37,6 @@ public class AutoEnchanter extends AContainer {
|
|||||||
return new ItemStack(Material.GOLDEN_CHESTPLATE);
|
return new ItemStack(Material.GOLDEN_CHESTPLATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getEnergyConsumption() {
|
|
||||||
return 9;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCapacity() {
|
|
||||||
return 128;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MachineRecipe findNextRecipe(BlockMenu menu) {
|
protected MachineRecipe findNextRecipe(BlockMenu menu) {
|
||||||
for (int slot : getInputSlots()) {
|
for (int slot : getInputSlots()) {
|
||||||
@ -128,11 +118,6 @@ public class AutoEnchanter extends AContainer {
|
|||||||
return sfItem == null || sfItem.isEnchantable();
|
return sfItem == null || sfItem.isEnchantable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSpeed() {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMachineIdentifier() {
|
public String getMachineIdentifier() {
|
||||||
return "AUTO_ENCHANTER";
|
return "AUTO_ENCHANTER";
|
||||||
|
@ -11,7 +11,7 @@ import me.mrCookieSlime.Slimefun.Objects.Category;
|
|||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
public abstract class CarbonPress extends AContainer implements RecipeDisplayItem {
|
public class CarbonPress extends AContainer implements RecipeDisplayItem {
|
||||||
|
|
||||||
public CarbonPress(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public CarbonPress(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
|
@ -32,16 +32,6 @@ public class ChargingBench extends AContainer {
|
|||||||
return new ItemStack(Material.GOLDEN_PICKAXE);
|
return new ItemStack(Material.GOLDEN_PICKAXE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getEnergyConsumption() {
|
|
||||||
return 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCapacity() {
|
|
||||||
return 128;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void tick(Block b) {
|
protected void tick(Block b) {
|
||||||
if (getCharge(b.getLocation()) < getEnergyConsumption()) {
|
if (getCharge(b.getLocation()) < getEnergyConsumption()) {
|
||||||
@ -81,11 +71,6 @@ public class ChargingBench extends AContainer {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSpeed() {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMachineIdentifier() {
|
public String getMachineIdentifier() {
|
||||||
return "CHARGING_BENCH";
|
return "CHARGING_BENCH";
|
||||||
|
@ -14,7 +14,7 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecip
|
|||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
||||||
|
|
||||||
public abstract class ElectricDustWasher extends AContainer {
|
public class ElectricDustWasher extends AContainer {
|
||||||
|
|
||||||
private OreWasher oreWasher;
|
private OreWasher oreWasher;
|
||||||
private final boolean legacyMode;
|
private final boolean legacyMode;
|
||||||
|
@ -12,7 +12,7 @@ import me.mrCookieSlime.Slimefun.Objects.Category;
|
|||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
public abstract class ElectricFurnace extends AContainer {
|
public class ElectricFurnace extends AContainer {
|
||||||
|
|
||||||
public ElectricFurnace(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public ElectricFurnace(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
|
@ -17,7 +17,7 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecip
|
|||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
||||||
|
|
||||||
public abstract class ElectricGoldPan extends AContainer implements RecipeDisplayItem {
|
public class ElectricGoldPan extends AContainer implements RecipeDisplayItem {
|
||||||
|
|
||||||
private final GoldPan goldPan = (GoldPan) SlimefunItems.GOLD_PAN.getItem();
|
private final GoldPan goldPan = (GoldPan) SlimefunItems.GOLD_PAN.getItem();
|
||||||
private final GoldPan netherGoldPan = (GoldPan) SlimefunItems.NETHER_GOLD_PAN.getItem();
|
private final GoldPan netherGoldPan = (GoldPan) SlimefunItems.NETHER_GOLD_PAN.getItem();
|
||||||
|
@ -9,7 +9,7 @@ import me.mrCookieSlime.Slimefun.Objects.Category;
|
|||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
public abstract class ElectricIngotFactory extends AContainer implements RecipeDisplayItem {
|
public class ElectricIngotFactory extends AContainer implements RecipeDisplayItem {
|
||||||
|
|
||||||
public ElectricIngotFactory(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public ElectricIngotFactory(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
|
@ -53,21 +53,6 @@ public class ElectricIngotPulverizer extends AContainer implements RecipeDisplay
|
|||||||
registerRecipe(3, new ItemStack(Material.GOLD_INGOT), SlimefunItems.GOLD_DUST);
|
registerRecipe(3, new ItemStack(Material.GOLD_INGOT), SlimefunItems.GOLD_DUST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getEnergyConsumption() {
|
|
||||||
return 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSpeed() {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCapacity() {
|
|
||||||
return 512;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMachineIdentifier() {
|
public String getMachineIdentifier() {
|
||||||
return "ELECTRIC_INGOT_PULVERIZER";
|
return "ELECTRIC_INGOT_PULVERIZER";
|
||||||
|
@ -9,7 +9,7 @@ import me.mrCookieSlime.Slimefun.Objects.Category;
|
|||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
public abstract class ElectricOreGrinder extends AContainer implements RecipeDisplayItem {
|
public class ElectricOreGrinder extends AContainer implements RecipeDisplayItem {
|
||||||
|
|
||||||
public ElectricOreGrinder(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public ElectricOreGrinder(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
|
@ -11,7 +11,7 @@ import me.mrCookieSlime.Slimefun.Objects.Category;
|
|||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
public abstract class ElectricPress extends AContainer implements RecipeDisplayItem {
|
public class ElectricPress extends AContainer implements RecipeDisplayItem {
|
||||||
|
|
||||||
public ElectricPress(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public ElectricPress(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
|
@ -35,7 +35,7 @@ import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow;
|
|||||||
* @author TheBusyBiscuit
|
* @author TheBusyBiscuit
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public abstract class ElectricSmeltery extends AContainer {
|
public class ElectricSmeltery extends AContainer {
|
||||||
|
|
||||||
private static final int[] border = { 4, 5, 6, 7, 8, 13, 31, 40, 41, 42, 43, 44 };
|
private static final int[] border = { 4, 5, 6, 7, 8, 13, 31, 40, 41, 42, 43, 44 };
|
||||||
private static final int[] inputBorder = { 0, 1, 2, 3, 9, 12, 18, 21, 27, 30, 36, 37, 38, 39 };
|
private static final int[] inputBorder = { 0, 1, 2, 3, 9, 12, 18, 21, 27, 30, 36, 37, 38, 39 };
|
||||||
|
@ -12,7 +12,7 @@ import me.mrCookieSlime.Slimefun.Objects.Category;
|
|||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
public abstract class ElectrifiedCrucible extends AContainer {
|
public class ElectrifiedCrucible extends AContainer {
|
||||||
|
|
||||||
public ElectrifiedCrucible(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public ElectrifiedCrucible(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
|
@ -11,7 +11,7 @@ import me.mrCookieSlime.Slimefun.Objects.Category;
|
|||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
public abstract class FoodComposter extends AContainer implements RecipeDisplayItem {
|
public class FoodComposter extends AContainer implements RecipeDisplayItem {
|
||||||
|
|
||||||
public FoodComposter(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public FoodComposter(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
|
@ -10,7 +10,7 @@ import me.mrCookieSlime.Slimefun.Objects.Category;
|
|||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
public abstract class FoodFabricator extends AContainer {
|
public class FoodFabricator extends AContainer {
|
||||||
|
|
||||||
public FoodFabricator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public FoodFabricator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
|
@ -14,7 +14,7 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
|
|||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe;
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
public abstract class Freezer extends AContainer implements RecipeDisplayItem {
|
public class Freezer extends AContainer implements RecipeDisplayItem {
|
||||||
|
|
||||||
public Freezer(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public Freezer(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
@ -52,9 +52,4 @@ public abstract class Freezer extends AContainer implements RecipeDisplayItem {
|
|||||||
return "FREEZER";
|
return "FREEZER";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCapacity() {
|
|
||||||
return 256;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
|
|||||||
import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu;
|
import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu;
|
||||||
import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow;
|
import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow;
|
||||||
|
|
||||||
public abstract class HeatedPressureChamber extends AContainer {
|
public class HeatedPressureChamber extends AContainer {
|
||||||
|
|
||||||
public HeatedPressureChamber(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public HeatedPressureChamber(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
|
@ -10,7 +10,7 @@ import me.mrCookieSlime.Slimefun.Objects.Category;
|
|||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer;
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
public abstract class Refinery extends AContainer implements RecipeDisplayItem {
|
public class Refinery extends AContainer implements RecipeDisplayItem {
|
||||||
|
|
||||||
public Refinery(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public Refinery(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
|
@ -30,7 +30,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
|||||||
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
||||||
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
|
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
|
||||||
|
|
||||||
public abstract class GEOMiner extends AContainer implements RecipeDisplayItem {
|
public 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[] 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 };
|
private static final int[] OUTPUT_BORDER = { 19, 20, 21, 22, 23, 24, 25, 28, 34, 37, 43, 46, 47, 48, 49, 50, 51, 52 };
|
||||||
|
@ -25,7 +25,7 @@ import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
|
|||||||
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
|
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
|
||||||
import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow;
|
import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow;
|
||||||
|
|
||||||
public abstract class OilPump extends AContainer implements RecipeDisplayItem {
|
public class OilPump extends AContainer implements RecipeDisplayItem {
|
||||||
|
|
||||||
private final GEOResource oil;
|
private final GEOResource oil;
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans;
|
package io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.block.EnderChest;
|
import org.bukkit.block.EnderChest;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
@ -21,12 +23,13 @@ class EnderTalisman extends Talisman {
|
|||||||
|
|
||||||
private static final LockedCategory ENDER_TALISMANS_CATEGORY = new LockedCategory(new NamespacedKey(SlimefunPlugin.instance(), "ender_talismans"), new CustomItem(SlimefunItems.ENDER_TALISMAN, "&7Talismans - &aTier II"), 3, Talisman.TALISMANS_CATEGORY.getKey());
|
private static final LockedCategory ENDER_TALISMANS_CATEGORY = new LockedCategory(new NamespacedKey(SlimefunPlugin.instance(), "ender_talismans"), new CustomItem(SlimefunItems.ENDER_TALISMAN, "&7Talismans - &aTier II"), 3, Talisman.TALISMANS_CATEGORY.getKey());
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
public EnderTalisman(Talisman parent, SlimefunItemStack item) {
|
public EnderTalisman(Talisman parent, SlimefunItemStack item) {
|
||||||
super(ENDER_TALISMANS_CATEGORY, item, new ItemStack[] { SlimefunItems.ENDER_LUMP_3, null, SlimefunItems.ENDER_LUMP_3, null, parent.getItem(), null, SlimefunItems.ENDER_LUMP_3, null, SlimefunItems.ENDER_LUMP_3 }, parent.isConsumable(), parent.isEventCancelled(), parent.getMessageSuffix(), parent.getChance(), parent.getEffects());
|
super(ENDER_TALISMANS_CATEGORY, item, new ItemStack[] { SlimefunItems.ENDER_LUMP_3, null, SlimefunItems.ENDER_LUMP_3, null, parent.getItem(), null, SlimefunItems.ENDER_LUMP_3, null, SlimefunItems.ENDER_LUMP_3 }, parent.isConsumable(), parent.isEventCancelled(), parent.getMessageSuffix(), parent.getChance(), parent.getEffects());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createEnderTalisman() {
|
void loadEnderTalisman() {
|
||||||
// Let's override that, otherwise we would be creating Ender Talismans
|
// Let's override that, otherwise we would be creating Ender Talismans
|
||||||
// for every Ender Talisman
|
// for every Ender Talisman
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,13 @@ import java.util.concurrent.ThreadLocalRandom;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.enchantments.Enchantment;
|
import org.bukkit.enchantments.Enchantment;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
|
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
|
||||||
@ -16,10 +21,18 @@ import io.github.thebusybiscuit.slimefun4.implementation.settings.TalismanEnchan
|
|||||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link MagicianTalisman} is a special kind of {@link Talisman} which awards a {@link Player}
|
||||||
|
* with an extra {@link Enchantment} when they enchant their {@link ItemStack}.
|
||||||
|
*
|
||||||
|
* @author TheBusyBiscuit
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class MagicianTalisman extends Talisman {
|
public class MagicianTalisman extends Talisman {
|
||||||
|
|
||||||
private final Set<TalismanEnchantment> enchantments = new HashSet<>();
|
private final Set<TalismanEnchantment> enchantments = new HashSet<>();
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
public MagicianTalisman(SlimefunItemStack item, ItemStack[] recipe) {
|
public MagicianTalisman(SlimefunItemStack item, ItemStack[] recipe) {
|
||||||
super(item, recipe, false, false, "magician", 80);
|
super(item, recipe, false, false, "magician", 80);
|
||||||
|
|
||||||
@ -47,13 +60,31 @@ public class MagicianTalisman extends Talisman {
|
|||||||
*
|
*
|
||||||
* @return An applicable {@link TalismanEnchantment} or null
|
* @return An applicable {@link TalismanEnchantment} or null
|
||||||
*/
|
*/
|
||||||
public TalismanEnchantment getRandomEnchantment(ItemStack item) {
|
@Nullable
|
||||||
if (item == null || item.getType() == Material.AIR) {
|
public TalismanEnchantment getRandomEnchantment(@Nonnull ItemStack item, @Nonnull Set<Enchantment> existingEnchantments) {
|
||||||
return null;
|
Validate.notNull(item, "The ItemStack cannot be null");
|
||||||
}
|
Validate.notNull(existingEnchantments, "The Enchantments Set cannot be null");
|
||||||
|
|
||||||
|
// @formatter:off
|
||||||
|
List<TalismanEnchantment> enabled = enchantments.stream()
|
||||||
|
.filter(e -> e.getEnchantment().canEnchantItem(item))
|
||||||
|
.filter(e -> hasConflicts(existingEnchantments, e))
|
||||||
|
.filter(TalismanEnchantment::getValue)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
// @formatter:on
|
||||||
|
|
||||||
List<TalismanEnchantment> enabled = enchantments.stream().filter(e -> e.getEnchantment().canEnchantItem(item)).filter(TalismanEnchantment::getValue).collect(Collectors.toList());
|
|
||||||
return enabled.isEmpty() ? null : enabled.get(ThreadLocalRandom.current().nextInt(enabled.size()));
|
return enabled.isEmpty() ? null : enabled.get(ThreadLocalRandom.current().nextInt(enabled.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
private boolean hasConflicts(Set<Enchantment> enchantments, TalismanEnchantment ench) {
|
||||||
|
for (Enchantment existing : enchantments) {
|
||||||
|
if (existing.conflictsWith(ench.getEnchantment())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,10 @@ import java.util.List;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -44,19 +48,23 @@ public class Talisman extends SlimefunItem {
|
|||||||
protected final PotionEffect[] effects;
|
protected final PotionEffect[] effects;
|
||||||
protected final int chance;
|
protected final int chance;
|
||||||
|
|
||||||
public Talisman(SlimefunItemStack item, ItemStack[] recipe, boolean consumable, boolean cancelEvent, String messageSuffix, PotionEffect... effects) {
|
@ParametersAreNonnullByDefault
|
||||||
|
public Talisman(SlimefunItemStack item, ItemStack[] recipe, boolean consumable, boolean cancelEvent, @Nullable String messageSuffix, PotionEffect... effects) {
|
||||||
this(item, recipe, consumable, cancelEvent, messageSuffix, 100, effects);
|
this(item, recipe, consumable, cancelEvent, messageSuffix, 100, effects);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Talisman(SlimefunItemStack item, ItemStack[] recipe, String messageSuffix, int chance, PotionEffect... effects) {
|
@ParametersAreNonnullByDefault
|
||||||
|
public Talisman(SlimefunItemStack item, ItemStack[] recipe, @Nullable String messageSuffix, int chance, PotionEffect... effects) {
|
||||||
this(item, recipe, true, true, messageSuffix, chance, effects);
|
this(item, recipe, true, true, messageSuffix, chance, effects);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Talisman(SlimefunItemStack item, ItemStack[] recipe, boolean consumable, boolean cancelEvent, String messageSuffix, int chance, PotionEffect... effects) {
|
@ParametersAreNonnullByDefault
|
||||||
|
public Talisman(SlimefunItemStack item, ItemStack[] recipe, boolean consumable, boolean cancelEvent, @Nullable String messageSuffix, int chance, PotionEffect... effects) {
|
||||||
this(TALISMANS_CATEGORY, item, recipe, consumable, cancelEvent, messageSuffix, chance, effects);
|
this(TALISMANS_CATEGORY, item, recipe, consumable, cancelEvent, messageSuffix, chance, effects);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Talisman(Category category, SlimefunItemStack item, ItemStack[] recipe, boolean consumable, boolean cancelEvent, String messageSuffix, int chance, PotionEffect... effects) {
|
@ParametersAreNonnullByDefault
|
||||||
|
protected Talisman(Category category, SlimefunItemStack item, ItemStack[] recipe, boolean consumable, boolean cancelEvent, @Nullable String messageSuffix, int chance, PotionEffect... effects) {
|
||||||
super(category, item, RecipeType.MAGIC_WORKBENCH, recipe, new CustomItem(item, consumable ? 4 : 1));
|
super(category, item, RecipeType.MAGIC_WORKBENCH, recipe, new CustomItem(item, consumable ? 4 : 1));
|
||||||
|
|
||||||
this.consumable = consumable;
|
this.consumable = consumable;
|
||||||
@ -81,14 +89,26 @@ public class Talisman extends SlimefunItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns whether the {@link Talisman} will be consumed upon use.
|
||||||
|
*
|
||||||
|
* @return Whether this {@link Talisman} is consumed on use.
|
||||||
|
*/
|
||||||
public boolean isConsumable() {
|
public boolean isConsumable() {
|
||||||
return consumable;
|
return consumable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns the chance of this {@link Talisman} activating.
|
||||||
|
* The chance will be between 1 and 100.
|
||||||
|
*
|
||||||
|
* @return The chance of this {@link Talisman} activating.
|
||||||
|
*/
|
||||||
public int getChance() {
|
public int getChance() {
|
||||||
return chance;
|
return chance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public PotionEffect[] getEffects() {
|
public PotionEffect[] getEffects() {
|
||||||
return effects;
|
return effects;
|
||||||
}
|
}
|
||||||
@ -101,6 +121,7 @@ public class Talisman extends SlimefunItem {
|
|||||||
return cancel;
|
return cancel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private SlimefunItemStack getEnderVariant() {
|
private SlimefunItemStack getEnderVariant() {
|
||||||
return enderTalisman;
|
return enderTalisman;
|
||||||
}
|
}
|
||||||
@ -114,10 +135,10 @@ public class Talisman extends SlimefunItem {
|
|||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load() {
|
||||||
super.load();
|
super.load();
|
||||||
createEnderTalisman();
|
loadEnderTalisman();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void createEnderTalisman() {
|
void loadEnderTalisman() {
|
||||||
EnderTalisman talisman = (EnderTalisman) SlimefunItem.getByItem(getEnderVariant());
|
EnderTalisman talisman = (EnderTalisman) SlimefunItem.getByItem(getEnderVariant());
|
||||||
Optional<Research> research = Research.getResearch(new NamespacedKey(SlimefunPlugin.instance(), "ender_talismans"));
|
Optional<Research> research = Research.getResearch(new NamespacedKey(SlimefunPlugin.instance(), "ender_talismans"));
|
||||||
|
|
||||||
@ -126,14 +147,16 @@ public class Talisman extends SlimefunItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean hasMessage(Talisman talisman) {
|
private static boolean hasMessage(@Nonnull Talisman talisman) {
|
||||||
return talisman.getMessageSuffix() != null;
|
return talisman.getMessageSuffix() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
public static boolean checkFor(Event e, SlimefunItemStack stack) {
|
public static boolean checkFor(Event e, SlimefunItemStack stack) {
|
||||||
return checkFor(e, stack.getItem());
|
return checkFor(e, stack.getItem());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
public static boolean checkFor(Event e, SlimefunItem item) {
|
public static boolean checkFor(Event e, SlimefunItem item) {
|
||||||
if (!(item instanceof Talisman)) {
|
if (!(item instanceof Talisman)) {
|
||||||
return false;
|
return false;
|
||||||
@ -153,7 +176,7 @@ public class Talisman extends SlimefunItem {
|
|||||||
|
|
||||||
if (SlimefunUtils.containsSimilarItem(p.getInventory(), talismanItem, true)) {
|
if (SlimefunUtils.containsSimilarItem(p.getInventory(), talismanItem, true)) {
|
||||||
if (Slimefun.hasUnlocked(p, talisman, true)) {
|
if (Slimefun.hasUnlocked(p, talisman, true)) {
|
||||||
activateTalisman(e, p, p.getInventory(), talisman);
|
activateTalisman(e, p, p.getInventory(), talisman, talismanItem);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -163,7 +186,7 @@ public class Talisman extends SlimefunItem {
|
|||||||
|
|
||||||
if (SlimefunUtils.containsSimilarItem(p.getEnderChest(), enderTalisman, true)) {
|
if (SlimefunUtils.containsSimilarItem(p.getEnderChest(), enderTalisman, true)) {
|
||||||
if (Slimefun.hasUnlocked(p, talisman, true)) {
|
if (Slimefun.hasUnlocked(p, talisman, true)) {
|
||||||
activateTalisman(e, p, p.getEnderChest(), talisman);
|
activateTalisman(e, p, p.getEnderChest(), talisman, enderTalisman);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -174,38 +197,43 @@ public class Talisman extends SlimefunItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void activateTalisman(Event e, Player p, Inventory inv, Talisman talisman) {
|
@ParametersAreNonnullByDefault
|
||||||
consumeItem(inv, talisman);
|
private static void activateTalisman(Event e, Player p, Inventory inv, Talisman talisman, ItemStack talismanItem) {
|
||||||
|
consumeItem(inv, talisman, talismanItem);
|
||||||
applyTalismanEffects(p, talisman);
|
applyTalismanEffects(p, talisman);
|
||||||
cancelEvent(e, talisman);
|
cancelEvent(e, talisman);
|
||||||
sendMessage(p, talisman);
|
sendMessage(p, talisman);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
private static void applyTalismanEffects(Player p, Talisman talisman) {
|
private static void applyTalismanEffects(Player p, Talisman talisman) {
|
||||||
for (PotionEffect effect : talisman.getEffects()) {
|
for (PotionEffect effect : talisman.getEffects()) {
|
||||||
p.addPotionEffect(effect);
|
p.addPotionEffect(effect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
private static void cancelEvent(Event e, Talisman talisman) {
|
private static void cancelEvent(Event e, Talisman talisman) {
|
||||||
if (e instanceof Cancellable && talisman.isEventCancelled()) {
|
if (e instanceof Cancellable && talisman.isEventCancelled()) {
|
||||||
((Cancellable) e).setCancelled(true);
|
((Cancellable) e).setCancelled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
private static void sendMessage(Player p, Talisman talisman) {
|
private static void sendMessage(Player p, Talisman talisman) {
|
||||||
if (hasMessage(talisman)) {
|
if (hasMessage(talisman)) {
|
||||||
SlimefunPlugin.getLocalization().sendMessage(p, "messages.talisman." + talisman.getMessageSuffix(), true);
|
SlimefunPlugin.getLocalization().sendMessage(p, "messages.talisman." + talisman.getMessageSuffix(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void consumeItem(Inventory inv, Talisman talisman) {
|
@ParametersAreNonnullByDefault
|
||||||
|
private static void consumeItem(Inventory inv, Talisman talisman, ItemStack talismanItem) {
|
||||||
if (talisman.isConsumable()) {
|
if (talisman.isConsumable()) {
|
||||||
ItemStack[] contents = inv.getContents();
|
ItemStack[] contents = inv.getContents();
|
||||||
for (int i = 0; i < contents.length; i++) {
|
for (int i = 0; i < contents.length; i++) {
|
||||||
ItemStack item = contents[i];
|
ItemStack item = contents[i];
|
||||||
|
|
||||||
if (SlimefunUtils.isItemSimilar(item, talisman.getItem(), true, false)) {
|
if (SlimefunUtils.isItemSimilar(item, talismanItem, true, false)) {
|
||||||
ItemUtils.consumeItem(item, false);
|
ItemUtils.consumeItem(item, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
@ -14,7 +16,6 @@ import org.bukkit.inventory.ItemStack;
|
|||||||
|
|
||||||
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
|
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
|
||||||
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
|
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlockMachine;
|
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
@ -23,7 +24,7 @@ import me.mrCookieSlime.Slimefun.Objects.Category;
|
|||||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
||||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||||
|
|
||||||
public class ArmorForge extends MultiBlockMachine {
|
public class ArmorForge extends BackpackCrafter {
|
||||||
|
|
||||||
public ArmorForge(Category category, SlimefunItemStack item) {
|
public ArmorForge(Category category, SlimefunItemStack item) {
|
||||||
super(category, item, new ItemStack[] { null, null, null, null, new ItemStack(Material.ANVIL), null, null, new CustomItem(Material.DISPENSER, "Dispenser (Facing up)"), null }, BlockFace.SELF);
|
super(category, item, new ItemStack[] { null, null, null, null, new ItemStack(Material.ANVIL), null, null, new CustomItem(Material.DISPENSER, "Dispenser (Facing up)"), null }, BlockFace.SELF);
|
||||||
@ -31,8 +32,8 @@ public class ArmorForge extends MultiBlockMachine {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInteract(Player p, Block b) {
|
public void onInteract(Player p, Block b) {
|
||||||
Block dispBlock = b.getRelative(BlockFace.DOWN);
|
Block dispenser = b.getRelative(BlockFace.DOWN);
|
||||||
BlockState state = PaperLib.getBlockState(dispBlock, false).getState();
|
BlockState state = PaperLib.getBlockState(dispenser, false).getState();
|
||||||
|
|
||||||
if (state instanceof Dispenser) {
|
if (state instanceof Dispenser) {
|
||||||
Dispenser disp = (Dispenser) state;
|
Dispenser disp = (Dispenser) state;
|
||||||
@ -44,13 +45,7 @@ public class ArmorForge extends MultiBlockMachine {
|
|||||||
ItemStack output = RecipeType.getRecipeOutputList(this, inputs.get(i)).clone();
|
ItemStack output = RecipeType.getRecipeOutputList(this, inputs.get(i)).clone();
|
||||||
|
|
||||||
if (Slimefun.hasUnlocked(p, output, true)) {
|
if (Slimefun.hasUnlocked(p, output, true)) {
|
||||||
Inventory outputInv = findOutputInventory(output, dispBlock, inv);
|
craft(p, output, inv, dispenser);
|
||||||
|
|
||||||
if (outputInv != null) {
|
|
||||||
craft(p, output, inv, outputInv);
|
|
||||||
} else {
|
|
||||||
SlimefunPlugin.getLocalization().sendMessage(p, "machines.full-inventory", true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -71,26 +66,35 @@ public class ArmorForge extends MultiBlockMachine {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void craft(Player p, ItemStack output, Inventory inv, Inventory outputInv) {
|
@ParametersAreNonnullByDefault
|
||||||
for (int j = 0; j < 9; j++) {
|
private void craft(Player p, ItemStack output, Inventory inv, Block dispenser) {
|
||||||
ItemStack item = inv.getContents()[j];
|
Inventory fakeInv = createVirtualInventory(inv);
|
||||||
|
Inventory outputInv = findOutputInventory(output, dispenser, inv, fakeInv);
|
||||||
|
|
||||||
if (item != null && item.getType() != Material.AIR) {
|
if (outputInv != null) {
|
||||||
ItemUtils.consumeItem(item, true);
|
for (int j = 0; j < 9; j++) {
|
||||||
}
|
ItemStack item = inv.getContents()[j];
|
||||||
}
|
|
||||||
|
|
||||||
for (int j = 0; j < 4; j++) {
|
if (item != null && item.getType() != Material.AIR) {
|
||||||
int current = j;
|
ItemUtils.consumeItem(item, true);
|
||||||
|
|
||||||
SlimefunPlugin.runSync(() -> {
|
|
||||||
if (current < 3) {
|
|
||||||
p.getWorld().playSound(p.getLocation(), Sound.BLOCK_ANVIL_USE, 1F, 2F);
|
|
||||||
} else {
|
|
||||||
p.getWorld().playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1F, 1F);
|
|
||||||
outputInv.addItem(output);
|
|
||||||
}
|
}
|
||||||
}, j * 20L);
|
}
|
||||||
|
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
int current = j;
|
||||||
|
|
||||||
|
SlimefunPlugin.runSync(() -> {
|
||||||
|
if (current < 3) {
|
||||||
|
p.getWorld().playSound(p.getLocation(), Sound.BLOCK_ANVIL_USE, 1F, 2F);
|
||||||
|
} else {
|
||||||
|
p.getWorld().playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1F, 1F);
|
||||||
|
outputInv.addItem(output);
|
||||||
|
}
|
||||||
|
}, j * 20L);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
SlimefunPlugin.getLocalization().sendMessage(p, "machines.full-inventory", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
|||||||
*
|
*
|
||||||
* @see EnhancedCraftingTable
|
* @see EnhancedCraftingTable
|
||||||
* @see MagicWorkbench
|
* @see MagicWorkbench
|
||||||
|
* @see ArmorForge
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
abstract class BackpackCrafter extends MultiBlockMachine {
|
abstract class BackpackCrafter extends MultiBlockMachine {
|
||||||
|
@ -15,6 +15,7 @@ import org.bukkit.inventory.ItemStack;
|
|||||||
import org.bukkit.inventory.meta.PotionMeta;
|
import org.bukkit.inventory.meta.PotionMeta;
|
||||||
import org.bukkit.potion.PotionEffect;
|
import org.bukkit.potion.PotionEffect;
|
||||||
|
|
||||||
|
import io.github.thebusybiscuit.slimefun4.api.events.CoolerFeedPlayerEvent;
|
||||||
import io.github.thebusybiscuit.slimefun4.api.player.PlayerBackpack;
|
import io.github.thebusybiscuit.slimefun4.api.player.PlayerBackpack;
|
||||||
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
|
import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
@ -37,11 +38,13 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
|
|||||||
*/
|
*/
|
||||||
public class CoolerListener implements Listener {
|
public class CoolerListener implements Listener {
|
||||||
|
|
||||||
|
private final SlimefunPlugin plugin;
|
||||||
private final Cooler cooler;
|
private final Cooler cooler;
|
||||||
|
|
||||||
public CoolerListener(@Nonnull SlimefunPlugin plugin, @Nonnull Cooler cooler) {
|
public CoolerListener(@Nonnull SlimefunPlugin plugin, @Nonnull Cooler cooler) {
|
||||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||||
|
|
||||||
|
this.plugin = plugin;
|
||||||
this.cooler = cooler;
|
this.cooler = cooler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,12 +96,12 @@ public class CoolerListener implements Listener {
|
|||||||
private void takeJuiceFromCooler(@Nonnull Player p, @Nonnull ItemStack cooler) {
|
private void takeJuiceFromCooler(@Nonnull Player p, @Nonnull ItemStack cooler) {
|
||||||
PlayerProfile.getBackpack(cooler, backpack -> {
|
PlayerProfile.getBackpack(cooler, backpack -> {
|
||||||
if (backpack != null) {
|
if (backpack != null) {
|
||||||
SlimefunPlugin.runSync(() -> consumeJuice(p, backpack));
|
SlimefunPlugin.runSync(() -> consumeJuice(p, cooler, backpack));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean consumeJuice(@Nonnull Player p, @Nonnull PlayerBackpack backpack) {
|
private boolean consumeJuice(@Nonnull Player p, @Nonnull ItemStack coolerItem, @Nonnull PlayerBackpack backpack) {
|
||||||
Inventory inv = backpack.getInventory();
|
Inventory inv = backpack.getInventory();
|
||||||
int slot = -1;
|
int slot = -1;
|
||||||
|
|
||||||
@ -112,17 +115,26 @@ public class CoolerListener implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (slot >= 0) {
|
if (slot >= 0) {
|
||||||
PotionMeta im = (PotionMeta) inv.getItem(slot).getItemMeta();
|
ItemStack item = inv.getItem(slot);
|
||||||
|
CoolerFeedPlayerEvent event = new CoolerFeedPlayerEvent(p, cooler, coolerItem, item);
|
||||||
|
plugin.getServer().getPluginManager().callEvent(event);
|
||||||
|
|
||||||
for (PotionEffect effect : im.getCustomEffects()) {
|
if (!event.isCancelled()) {
|
||||||
p.addPotionEffect(effect);
|
PotionMeta im = (PotionMeta) event.getConsumedItem().getItemMeta();
|
||||||
|
|
||||||
|
for (PotionEffect effect : im.getCustomEffects()) {
|
||||||
|
p.addPotionEffect(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
p.setSaturation(6F);
|
||||||
|
p.playSound(p.getLocation(), Sound.ENTITY_GENERIC_DRINK, 1F, 1F);
|
||||||
|
inv.setItem(slot, null);
|
||||||
|
backpack.markDirty();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
p.setSaturation(6F);
|
|
||||||
p.playSound(p.getLocation(), Sound.ENTITY_GENERIC_DRINK, 1F, 1F);
|
|
||||||
inv.setItem(slot, null);
|
|
||||||
backpack.markDirty();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -40,7 +40,7 @@ public class SlimefunBootsListener implements Listener {
|
|||||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||||
public void onDamage(EntityDamageEvent e) {
|
public void onDamage(EntityDamageEvent e) {
|
||||||
if (e.getEntity() instanceof Player && e.getCause() == DamageCause.FALL) {
|
if (e.getEntity() instanceof Player && e.getCause() == DamageCause.FALL) {
|
||||||
onFallDamage(e);
|
onFallDamage(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@ package io.github.thebusybiscuit.slimefun4.implementation.listeners;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@ -231,26 +231,28 @@ public class TalismanListener implements Listener {
|
|||||||
@EventHandler
|
@EventHandler
|
||||||
public void onEnchant(EnchantItemEvent e) {
|
public void onEnchant(EnchantItemEvent e) {
|
||||||
Random random = ThreadLocalRandom.current();
|
Random random = ThreadLocalRandom.current();
|
||||||
|
Map<Enchantment, Integer> enchantments = e.getEnchantsToAdd();
|
||||||
|
|
||||||
|
// Magician Talisman
|
||||||
if (Talisman.checkFor(e, SlimefunItems.TALISMAN_MAGICIAN)) {
|
if (Talisman.checkFor(e, SlimefunItems.TALISMAN_MAGICIAN)) {
|
||||||
MagicianTalisman talisman = (MagicianTalisman) SlimefunItems.TALISMAN_MAGICIAN.getItem();
|
MagicianTalisman talisman = (MagicianTalisman) SlimefunItems.TALISMAN_MAGICIAN.getItem();
|
||||||
TalismanEnchantment enchantment = talisman.getRandomEnchantment(e.getItem());
|
TalismanEnchantment enchantment = talisman.getRandomEnchantment(e.getItem(), enchantments.keySet());
|
||||||
|
|
||||||
if (enchantment != null) {
|
if (enchantment != null) {
|
||||||
e.getEnchantsToAdd().put(enchantment.getEnchantment(), enchantment.getLevel());
|
enchantments.put(enchantment.getEnchantment(), enchantment.getLevel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!e.getEnchantsToAdd().containsKey(Enchantment.SILK_TOUCH) && Enchantment.LOOT_BONUS_BLOCKS.canEnchantItem(e.getItem()) && Talisman.checkFor(e, SlimefunItems.TALISMAN_WIZARD)) {
|
// Wizard Talisman
|
||||||
Set<Enchantment> enchantments = e.getEnchantsToAdd().keySet();
|
if (!enchantments.containsKey(Enchantment.SILK_TOUCH) && Enchantment.LOOT_BONUS_BLOCKS.canEnchantItem(e.getItem()) && Talisman.checkFor(e, SlimefunItems.TALISMAN_WIZARD)) {
|
||||||
|
|
||||||
for (Enchantment enchantment : enchantments) {
|
for (Enchantment enchantment : enchantments.keySet()) {
|
||||||
if (random.nextInt(100) < 40) {
|
if (random.nextInt(100) < 40) {
|
||||||
e.getEnchantsToAdd().put(enchantment, random.nextInt(3) + 1);
|
e.getEnchantsToAdd().put(enchantment, random.nextInt(3) + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
e.getEnchantsToAdd().put(Enchantment.LOOT_BONUS_BLOCKS, random.nextInt(3) + 3);
|
enchantments.put(Enchantment.LOOT_BONUS_BLOCKS, random.nextInt(3) + 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ package io.github.thebusybiscuit.slimefun4.implementation.listeners.crafting;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import org.bukkit.block.BrewingStand;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.Event.Result;
|
import org.bukkit.event.Event.Result;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
@ -15,8 +14,8 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
|||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This {@link Listener} prevents any {@link SlimefunItem} from being used in a
|
* This {@link Listener} prevents any {@link SlimefunItem} from being used in an
|
||||||
* {@link BrewingStand}.
|
* anvil.
|
||||||
*
|
*
|
||||||
* @author TheBusyBiscuit
|
* @author TheBusyBiscuit
|
||||||
*
|
*
|
||||||
|
@ -17,7 +17,7 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This {@link Listener} prevents any {@link SlimefunItem} from being used in a
|
* This {@link Listener} prevents any {@link SlimefunItem} from being used in a
|
||||||
* {@link BrewingStand}.
|
* brewing stand.
|
||||||
*
|
*
|
||||||
* @author VoidAngel
|
* @author VoidAngel
|
||||||
* @author SoSeDiK
|
* @author SoSeDiK
|
||||||
|
@ -21,7 +21,7 @@ public class TalismanEnchantment extends ItemSetting<Boolean> {
|
|||||||
private final int level;
|
private final int level;
|
||||||
|
|
||||||
public TalismanEnchantment(@Nonnull Enchantment enchantment, int level) {
|
public TalismanEnchantment(@Nonnull Enchantment enchantment, int level) {
|
||||||
super("allow-enchantments." + enchantment.getKey().getKey() + ".level." + level, true);
|
super("allow-enchantments." + enchantment.getKey().getNamespace() + '.' + enchantment.getKey().getKey() + ".level." + level, true);
|
||||||
|
|
||||||
this.enchantment = enchantment;
|
this.enchantment = enchantment;
|
||||||
this.level = level;
|
this.level = level;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -29,6 +29,9 @@ public final class ChestMenuUtils {
|
|||||||
private static final ItemStack INPUT_SLOT = new SlimefunItemStack("_UI_INPUT_SLOT", Material.CYAN_STAINED_GLASS_PANE, " ");
|
private static final ItemStack INPUT_SLOT = new SlimefunItemStack("_UI_INPUT_SLOT", Material.CYAN_STAINED_GLASS_PANE, " ");
|
||||||
private static final ItemStack OUTPUT_SLOT = new SlimefunItemStack("_UI_OUTPUT_SLOT", Material.ORANGE_STAINED_GLASS_PANE, " ");
|
private static final ItemStack OUTPUT_SLOT = new SlimefunItemStack("_UI_OUTPUT_SLOT", Material.ORANGE_STAINED_GLASS_PANE, " ");
|
||||||
|
|
||||||
|
private static final ItemStack NO_PERMISSION = new SlimefunItemStack("_UI_NO_PERMISSION", Material.BARRIER, "No Permission");
|
||||||
|
private static final ItemStack NOT_RESEARCHED = new SlimefunItemStack("_UI_NOT_RESEARCHED", Material.BARRIER, "Not researched");
|
||||||
|
|
||||||
private static final ItemStack BACK_BUTTON = new SlimefunItemStack("_UI_BACK", Material.ENCHANTED_BOOK, "&7\u21E6 Back", meta -> meta.addItemFlags(ItemFlag.HIDE_ENCHANTS));
|
private static final ItemStack BACK_BUTTON = new SlimefunItemStack("_UI_BACK", Material.ENCHANTED_BOOK, "&7\u21E6 Back", meta -> meta.addItemFlags(ItemFlag.HIDE_ENCHANTS));
|
||||||
private static final ItemStack MENU_BUTTON = new SlimefunItemStack("_UI_MENU", Material.COMPARATOR, "&eSettings / Info", "", "&7\u21E8 Click to see more");
|
private static final ItemStack MENU_BUTTON = new SlimefunItemStack("_UI_MENU", Material.COMPARATOR, "&eSettings / Info", "", "&7\u21E8 Click to see more");
|
||||||
private static final ItemStack SEARCH_BUTTON = new SlimefunItemStack("_UI_SEARCH", Material.NAME_TAG, "&bSearch");
|
private static final ItemStack SEARCH_BUTTON = new SlimefunItemStack("_UI_SEARCH", Material.NAME_TAG, "&bSearch");
|
||||||
@ -46,6 +49,16 @@ public final class ChestMenuUtils {
|
|||||||
return UI_BACKGROUND;
|
return UI_BACKGROUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public static ItemStack getNoPermissionItem() {
|
||||||
|
return NO_PERMISSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public static ItemStack getNotResearchedItem() {
|
||||||
|
return NOT_RESEARCHED;
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static ItemStack getInputSlotTexture() {
|
public static ItemStack getInputSlotTexture() {
|
||||||
return INPUT_SLOT;
|
return INPUT_SLOT;
|
||||||
|
@ -4,6 +4,10 @@ import java.util.Arrays;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.DyeColor;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
|
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
|
||||||
@ -17,18 +21,14 @@ import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
|
|||||||
* @see SlimefunTag
|
* @see SlimefunTag
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public final class ColoredMaterials {
|
public enum ColoredMaterial {
|
||||||
|
|
||||||
/**
|
// @formatter:off (We want this to stay formatted like this)
|
||||||
* We don't want any instances of this class, so we set the
|
|
||||||
* constructor to be private.
|
|
||||||
*/
|
|
||||||
private ColoredMaterials() {}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This {@link List} contains all wool colors ordered by their appearance ingame.
|
* This {@link List} contains all wool colors ordered by their appearance ingame.
|
||||||
*/
|
*/
|
||||||
public static final List<Material> WOOL = Collections.unmodifiableList(Arrays.asList(
|
WOOL(new Material[] {
|
||||||
Material.WHITE_WOOL,
|
Material.WHITE_WOOL,
|
||||||
Material.ORANGE_WOOL,
|
Material.ORANGE_WOOL,
|
||||||
Material.MAGENTA_WOOL,
|
Material.MAGENTA_WOOL,
|
||||||
@ -45,12 +45,12 @@ public final class ColoredMaterials {
|
|||||||
Material.GREEN_WOOL,
|
Material.GREEN_WOOL,
|
||||||
Material.RED_WOOL,
|
Material.RED_WOOL,
|
||||||
Material.BLACK_WOOL
|
Material.BLACK_WOOL
|
||||||
));
|
}),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This {@link List} contains all stained glass colors ordered by their appearance ingame.
|
* This {@link List} contains all stained glass colors ordered by their appearance ingame.
|
||||||
*/
|
*/
|
||||||
public static final List<Material> STAINED_GLASS = Collections.unmodifiableList(Arrays.asList(
|
STAINED_GLASS(new Material[] {
|
||||||
Material.WHITE_STAINED_GLASS,
|
Material.WHITE_STAINED_GLASS,
|
||||||
Material.ORANGE_STAINED_GLASS,
|
Material.ORANGE_STAINED_GLASS,
|
||||||
Material.MAGENTA_STAINED_GLASS,
|
Material.MAGENTA_STAINED_GLASS,
|
||||||
@ -67,12 +67,12 @@ public final class ColoredMaterials {
|
|||||||
Material.GREEN_STAINED_GLASS,
|
Material.GREEN_STAINED_GLASS,
|
||||||
Material.RED_STAINED_GLASS,
|
Material.RED_STAINED_GLASS,
|
||||||
Material.BLACK_STAINED_GLASS
|
Material.BLACK_STAINED_GLASS
|
||||||
));
|
}),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This {@link List} contains all stained glass pane colors ordered by their appearance ingame.
|
* This {@link List} contains all stained glass pane colors ordered by their appearance ingame.
|
||||||
*/
|
*/
|
||||||
public static final List<Material> STAINED_GLASS_PANE = Collections.unmodifiableList(Arrays.asList(
|
STAINED_GLASS_PANE(new Material[] {
|
||||||
Material.WHITE_STAINED_GLASS_PANE,
|
Material.WHITE_STAINED_GLASS_PANE,
|
||||||
Material.ORANGE_STAINED_GLASS_PANE,
|
Material.ORANGE_STAINED_GLASS_PANE,
|
||||||
Material.MAGENTA_STAINED_GLASS_PANE,
|
Material.MAGENTA_STAINED_GLASS_PANE,
|
||||||
@ -89,12 +89,12 @@ public final class ColoredMaterials {
|
|||||||
Material.GREEN_STAINED_GLASS_PANE,
|
Material.GREEN_STAINED_GLASS_PANE,
|
||||||
Material.RED_STAINED_GLASS_PANE,
|
Material.RED_STAINED_GLASS_PANE,
|
||||||
Material.BLACK_STAINED_GLASS_PANE
|
Material.BLACK_STAINED_GLASS_PANE
|
||||||
));
|
}),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This {@link List} contains all terracotta colors ordered by their appearance ingame.
|
* This {@link List} contains all terracotta colors ordered by their appearance ingame.
|
||||||
*/
|
*/
|
||||||
public static final List<Material> TERRACOTTA = Collections.unmodifiableList(Arrays.asList(
|
TERRACOTTA(new Material[] {
|
||||||
Material.WHITE_TERRACOTTA,
|
Material.WHITE_TERRACOTTA,
|
||||||
Material.ORANGE_TERRACOTTA,
|
Material.ORANGE_TERRACOTTA,
|
||||||
Material.MAGENTA_TERRACOTTA,
|
Material.MAGENTA_TERRACOTTA,
|
||||||
@ -111,12 +111,12 @@ public final class ColoredMaterials {
|
|||||||
Material.GREEN_TERRACOTTA,
|
Material.GREEN_TERRACOTTA,
|
||||||
Material.RED_TERRACOTTA,
|
Material.RED_TERRACOTTA,
|
||||||
Material.BLACK_TERRACOTTA
|
Material.BLACK_TERRACOTTA
|
||||||
));
|
}),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This {@link List} contains all glazed terracotta colors ordered by their appearance ingame.
|
* This {@link List} contains all glazed terracotta colors ordered by their appearance ingame.
|
||||||
*/
|
*/
|
||||||
public static final List<Material> GLAZED_TERRACOTTA = Collections.unmodifiableList(Arrays.asList(
|
GLAZED_TERRACOTTA(new Material[] {
|
||||||
Material.WHITE_GLAZED_TERRACOTTA,
|
Material.WHITE_GLAZED_TERRACOTTA,
|
||||||
Material.ORANGE_GLAZED_TERRACOTTA,
|
Material.ORANGE_GLAZED_TERRACOTTA,
|
||||||
Material.MAGENTA_GLAZED_TERRACOTTA,
|
Material.MAGENTA_GLAZED_TERRACOTTA,
|
||||||
@ -133,12 +133,12 @@ public final class ColoredMaterials {
|
|||||||
Material.GREEN_GLAZED_TERRACOTTA,
|
Material.GREEN_GLAZED_TERRACOTTA,
|
||||||
Material.RED_GLAZED_TERRACOTTA,
|
Material.RED_GLAZED_TERRACOTTA,
|
||||||
Material.BLACK_GLAZED_TERRACOTTA
|
Material.BLACK_GLAZED_TERRACOTTA
|
||||||
));
|
}),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This {@link List} contains all concrete colors ordered by their appearance ingame.
|
* This {@link List} contains all concrete colors ordered by their appearance ingame.
|
||||||
*/
|
*/
|
||||||
public static final List<Material> CONCRETE = Collections.unmodifiableList(Arrays.asList(
|
CONCRETE(new Material[] {
|
||||||
Material.WHITE_CONCRETE,
|
Material.WHITE_CONCRETE,
|
||||||
Material.ORANGE_CONCRETE,
|
Material.ORANGE_CONCRETE,
|
||||||
Material.MAGENTA_CONCRETE,
|
Material.MAGENTA_CONCRETE,
|
||||||
@ -155,6 +155,42 @@ public final class ColoredMaterials {
|
|||||||
Material.GREEN_CONCRETE,
|
Material.GREEN_CONCRETE,
|
||||||
Material.RED_CONCRETE,
|
Material.RED_CONCRETE,
|
||||||
Material.BLACK_CONCRETE
|
Material.BLACK_CONCRETE
|
||||||
));
|
});
|
||||||
|
|
||||||
|
// @formatter:on
|
||||||
|
|
||||||
|
private final List<Material> list;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This creates a new constant of {@link ColoredMaterial}.
|
||||||
|
* The array must have a length of 16 and cannot contain null elements!
|
||||||
|
*
|
||||||
|
* @param materials
|
||||||
|
* The {@link Material Materials} for this {@link ColoredMaterial}.
|
||||||
|
*/
|
||||||
|
ColoredMaterial(@Nonnull Material[] materials) {
|
||||||
|
Validate.noNullElements(materials, "The List cannot contain any null elements");
|
||||||
|
Validate.isTrue(materials.length == 16, "Expected 16, received: " + materials.length + ". Did you miss a color?");
|
||||||
|
|
||||||
|
list = Collections.unmodifiableList(Arrays.asList(materials));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public List<Material> asList() {
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public Material get(int index) {
|
||||||
|
Validate.isTrue(index >= 0 && index < 16, "The index must be between 0 and 15 (inclusive).");
|
||||||
|
|
||||||
|
return list.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Material get(@Nonnull DyeColor color) {
|
||||||
|
Validate.notNull(color, "Color cannot be null!");
|
||||||
|
|
||||||
|
return get(color.ordinal());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package io.github.thebusybiscuit.slimefun4.utils;
|
package io.github.thebusybiscuit.slimefun4.utils;
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
|
import java.text.DecimalFormatSymbols;
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
@ -24,7 +25,7 @@ public final class NumberUtils {
|
|||||||
/**
|
/**
|
||||||
* This is our {@link DecimalFormat} for decimal values.
|
* This is our {@link DecimalFormat} for decimal values.
|
||||||
*/
|
*/
|
||||||
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.##");
|
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.##", DecimalFormatSymbols.getInstance(Locale.ROOT));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We do not want any instance of this to be created.
|
* We do not want any instance of this to be created.
|
||||||
@ -105,8 +106,31 @@ public final class NumberUtils {
|
|||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static String getElapsedTime(@Nonnull LocalDateTime date) {
|
public static String getElapsedTime(@Nonnull LocalDateTime date) {
|
||||||
Validate.notNull(date, "Provided date was null");
|
return getElapsedTime(LocalDateTime.now(), date);
|
||||||
long hours = Duration.between(date, LocalDateTime.now()).toHours();
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns the elapsed time between the two given {@link LocalDateTime LocalDateTimes}.
|
||||||
|
* The output will be nicely formatted based on the elapsed hours or days between the
|
||||||
|
* given {@link LocalDateTime LocalDateTime}.
|
||||||
|
*
|
||||||
|
* If a {@link LocalDateTime} from today and yesterday (exactly 24h apart) was passed it
|
||||||
|
* will return {@code "1d"}.
|
||||||
|
* One hour later it will read {@code "1d 1h"}. For values smaller than an hour {@code "< 1h"}
|
||||||
|
* will be returned instead.
|
||||||
|
*
|
||||||
|
* @param start
|
||||||
|
* The starting {@link LocalDateTime}.
|
||||||
|
* @param end
|
||||||
|
* The ending {@link LocalDateTime}.
|
||||||
|
*
|
||||||
|
* @return The elapsed time as a {@link String}
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
public static String getElapsedTime(@Nonnull LocalDateTime start, @Nonnull LocalDateTime end) {
|
||||||
|
Validate.notNull(start, "Provided start was null");
|
||||||
|
Validate.notNull(end, "Provided end was null");
|
||||||
|
long hours = Duration.between(start, end).toHours();
|
||||||
|
|
||||||
if (hours == 0) {
|
if (hours == 0) {
|
||||||
return "< 1h";
|
return "< 1h";
|
||||||
@ -133,12 +157,24 @@ public final class NumberUtils {
|
|||||||
return timeleft + seconds + "s";
|
return timeleft + seconds + "s";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method parses a {@link String} into an {@link Integer}.
|
||||||
|
* If the {@link String} could not be parsed correctly, the provided
|
||||||
|
* default value will be returned instead.
|
||||||
|
*
|
||||||
|
* @param str
|
||||||
|
* The {@link String} to parse
|
||||||
|
* @param defaultValue
|
||||||
|
* The default value for when the {@link String} could not be parsed
|
||||||
|
*
|
||||||
|
* @return The resulting {@link Integer}
|
||||||
|
*/
|
||||||
public static int getInt(@Nonnull String str, int defaultValue) {
|
public static int getInt(@Nonnull String str, int defaultValue) {
|
||||||
if (PatternUtils.NUMERIC.matcher(str).matches()) {
|
if (PatternUtils.NUMERIC.matcher(str).matches()) {
|
||||||
return Integer.parseInt(str);
|
return Integer.parseInt(str);
|
||||||
|
} else {
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return defaultValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -183,6 +219,8 @@ public final class NumberUtils {
|
|||||||
* The value to clamp
|
* The value to clamp
|
||||||
* @param max
|
* @param max
|
||||||
* The maximum value
|
* The maximum value
|
||||||
|
*
|
||||||
|
* @return The clamped value
|
||||||
*/
|
*/
|
||||||
public static int clamp(int min, int value, int max) {
|
public static int clamp(int min, int value, int max) {
|
||||||
if (value < min) {
|
if (value < min) {
|
||||||
|
@ -84,7 +84,7 @@ public class SlimefunItem implements Placeable {
|
|||||||
* This is a reference to the {@link SlimefunAddon} that registered this
|
* This is a reference to the {@link SlimefunAddon} that registered this
|
||||||
* {@link SlimefunItem}, if the item has not been registered yet, it will be null.
|
* {@link SlimefunItem}, if the item has not been registered yet, it will be null.
|
||||||
*/
|
*/
|
||||||
private SlimefunAddon addon;
|
protected SlimefunAddon addon;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the state of this {@link SlimefunItem}.
|
* This is the state of this {@link SlimefunItem}.
|
||||||
@ -930,6 +930,8 @@ public class SlimefunItem implements Placeable {
|
|||||||
* The message to send
|
* The message to send
|
||||||
*/
|
*/
|
||||||
public void info(@Nonnull String message) {
|
public void info(@Nonnull String message) {
|
||||||
|
Validate.notNull(addon, "Cannot log a message for an unregistered item!");
|
||||||
|
|
||||||
String msg = toString() + ": " + message;
|
String msg = toString() + ": " + message;
|
||||||
addon.getLogger().log(Level.INFO, msg);
|
addon.getLogger().log(Level.INFO, msg);
|
||||||
}
|
}
|
||||||
@ -943,6 +945,8 @@ public class SlimefunItem implements Placeable {
|
|||||||
* The message to send
|
* The message to send
|
||||||
*/
|
*/
|
||||||
public void warn(@Nonnull String message) {
|
public void warn(@Nonnull String message) {
|
||||||
|
Validate.notNull(addon, "Cannot send a warning for an unregistered item!");
|
||||||
|
|
||||||
String msg = toString() + ": " + message;
|
String msg = toString() + ": " + message;
|
||||||
addon.getLogger().log(Level.WARNING, msg);
|
addon.getLogger().log(Level.WARNING, msg);
|
||||||
|
|
||||||
@ -962,6 +966,8 @@ public class SlimefunItem implements Placeable {
|
|||||||
* The {@link Throwable} to throw as a stacktrace.
|
* The {@link Throwable} to throw as a stacktrace.
|
||||||
*/
|
*/
|
||||||
public void error(@Nonnull String message, @Nonnull Throwable throwable) {
|
public void error(@Nonnull String message, @Nonnull Throwable throwable) {
|
||||||
|
Validate.notNull(addon, "Cannot send an error for an unregistered item!");
|
||||||
|
|
||||||
addon.getLogger().log(Level.SEVERE, "Item \"{0}\" from {1} v{2} has caused an Error!", new Object[] { id, addon.getName(), addon.getPluginVersion() });
|
addon.getLogger().log(Level.SEVERE, "Item \"{0}\" from {1} v{2} has caused an Error!", new Object[] { id, addon.getName(), addon.getPluginVersion() });
|
||||||
|
|
||||||
if (addon.getBugTrackerURL() != null) {
|
if (addon.getBugTrackerURL() != null) {
|
||||||
|
@ -5,9 +5,12 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -17,7 +20,9 @@ import org.bukkit.inventory.ItemStack;
|
|||||||
|
|
||||||
import io.github.thebusybiscuit.cscorelib2.inventory.InvUtils;
|
import io.github.thebusybiscuit.cscorelib2.inventory.InvUtils;
|
||||||
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
|
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
|
||||||
import io.github.thebusybiscuit.slimefun4.api.events.AsyncMachineProcessCompleteEvent;
|
import io.github.thebusybiscuit.slimefun4.api.events.AsyncMachineProcessCompleteEvent;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.api.items.ItemState;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
|
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
|
||||||
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType;
|
import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType;
|
||||||
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
|
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
|
||||||
@ -47,6 +52,10 @@ public abstract class AContainer extends SlimefunItem implements InventoryBlock,
|
|||||||
|
|
||||||
protected final List<MachineRecipe> recipes = new ArrayList<>();
|
protected final List<MachineRecipe> recipes = new ArrayList<>();
|
||||||
|
|
||||||
|
private int energyConsumedPerTick = -1;
|
||||||
|
private int energyCapacity = -1;
|
||||||
|
private int processingSpeed = -1;
|
||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
public AContainer(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public AContainer(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
@ -114,6 +123,7 @@ public abstract class AContainer extends SlimefunItem implements InventoryBlock,
|
|||||||
*
|
*
|
||||||
* @return The title of the {@link Inventory} of this {@link AContainer}
|
* @return The title of the {@link Inventory} of this {@link AContainer}
|
||||||
*/
|
*/
|
||||||
|
@Nonnull
|
||||||
public String getInventoryTitle() {
|
public String getInventoryTitle() {
|
||||||
return getItemName();
|
return getItemName();
|
||||||
}
|
}
|
||||||
@ -128,12 +138,23 @@ public abstract class AContainer extends SlimefunItem implements InventoryBlock,
|
|||||||
*/
|
*/
|
||||||
public abstract ItemStack getProgressBar();
|
public abstract ItemStack getProgressBar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the max amount of electricity this machine can hold.
|
||||||
|
*
|
||||||
|
* @return The max amount of electricity this Block can store.
|
||||||
|
*/
|
||||||
|
public int getCapacity() {
|
||||||
|
return energyCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns the amount of energy that is consumed per operation.
|
* This method returns the amount of energy that is consumed per operation.
|
||||||
*
|
*
|
||||||
* @return The rate of energy consumption
|
* @return The rate of energy consumption
|
||||||
*/
|
*/
|
||||||
public abstract int getEnergyConsumption();
|
public int getEnergyConsumption() {
|
||||||
|
return energyConsumedPerTick;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns the speed at which this machine will operate.
|
* This method returns the speed at which this machine will operate.
|
||||||
@ -142,7 +163,86 @@ public abstract class AContainer extends SlimefunItem implements InventoryBlock,
|
|||||||
*
|
*
|
||||||
* @return The speed of this machine
|
* @return The speed of this machine
|
||||||
*/
|
*/
|
||||||
public abstract int getSpeed();
|
public int getSpeed() {
|
||||||
|
return processingSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This sets the energy capacity for this machine.
|
||||||
|
* This method <strong>must</strong> be called before registering the item
|
||||||
|
* and only before registering.
|
||||||
|
*
|
||||||
|
* @param capacity
|
||||||
|
* The amount of energy this machine can store
|
||||||
|
*
|
||||||
|
* @return This method will return the current instance of {@link AContainer}, so that can be chained.
|
||||||
|
*/
|
||||||
|
public final AContainer setCapacity(int capacity) {
|
||||||
|
Validate.isTrue(capacity > 0, "The capacity must be greater than zero!");
|
||||||
|
|
||||||
|
if (getState() == ItemState.UNREGISTERED) {
|
||||||
|
this.energyCapacity = capacity;
|
||||||
|
return this;
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("You cannot modify the capacity after the Item was registered.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This sets the speed of this machine.
|
||||||
|
*
|
||||||
|
* @param speed
|
||||||
|
* The speed multiplier for this machine, must be above zero
|
||||||
|
*
|
||||||
|
* @return This method will return the current instance of {@link AContainer}, so that can be chained.
|
||||||
|
*/
|
||||||
|
public final AContainer setProcessingSpeed(int speed) {
|
||||||
|
Validate.isTrue(speed > 0, "The speed must be greater than zero!");
|
||||||
|
|
||||||
|
this.processingSpeed = speed;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the energy consumed by this machine per tick.
|
||||||
|
*
|
||||||
|
* @param energyConsumption
|
||||||
|
* The energy consumed per tick
|
||||||
|
*
|
||||||
|
* @return This method will return the current instance of {@link AContainer}, so that can be chained.
|
||||||
|
*/
|
||||||
|
public final AContainer setEnergyConsumption(int energyConsumption) {
|
||||||
|
Validate.isTrue(energyConsumption > 0, "The energy consumption must be greater than zero!");
|
||||||
|
Validate.isTrue(energyCapacity > 0, "You must specify the capacity before you can set the consumption amount.");
|
||||||
|
Validate.isTrue(energyConsumption <= energyCapacity, "The energy consumption cannot be higher than the capacity (" + energyCapacity + ')');
|
||||||
|
|
||||||
|
this.energyConsumedPerTick = energyConsumption;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void register(@Nonnull SlimefunAddon addon) {
|
||||||
|
this.addon = addon;
|
||||||
|
|
||||||
|
if (getCapacity() <= 0) {
|
||||||
|
warn("The capacity has not been configured correctly. The Item was disabled.");
|
||||||
|
warn("Make sure to call '" + getClass().getSimpleName() + "#setEnergyCapacity(...)' before registering!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getEnergyConsumption() <= 0) {
|
||||||
|
warn("The energy consumption has not been configured correctly. The Item was disabled.");
|
||||||
|
warn("Make sure to call '" + getClass().getSimpleName() + "#setEnergyConsumption(...)' before registering!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getSpeed() <= 0) {
|
||||||
|
warn("The processing speed has not been configured correctly. The Item was disabled.");
|
||||||
|
warn("Make sure to call '" + getClass().getSimpleName() + "#setProcessingSpeed(...)' before registering!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getCapacity() > 0 && getEnergyConsumption() > 0 && getSpeed() > 0) {
|
||||||
|
super.register(addon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns an internal identifier that is used to identify this {@link AContainer}
|
* This method returns an internal identifier that is used to identify this {@link AContainer}
|
||||||
@ -154,6 +254,7 @@ public abstract class AContainer extends SlimefunItem implements InventoryBlock,
|
|||||||
*
|
*
|
||||||
* @return The identifier of this machine
|
* @return The identifier of this machine
|
||||||
*/
|
*/
|
||||||
|
@Nonnull
|
||||||
public abstract String getMachineIdentifier();
|
public abstract String getMachineIdentifier();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -238,31 +339,30 @@ public abstract class AContainer extends SlimefunItem implements InventoryBlock,
|
|||||||
BlockMenu inv = BlockStorage.getInventory(b);
|
BlockMenu inv = BlockStorage.getInventory(b);
|
||||||
|
|
||||||
if (isProcessing(b)) {
|
if (isProcessing(b)) {
|
||||||
int timeleft = progress.get(b);
|
|
||||||
|
|
||||||
if (timeleft > 0) {
|
if (takeCharge(b.getLocation())) {
|
||||||
ChestMenuUtils.updateProgressbar(inv, 22, timeleft, processing.get(b).getTicks(), getProgressBar());
|
|
||||||
|
|
||||||
if (isChargeable()) {
|
int timeleft = progress.get(b);
|
||||||
if (getCharge(b.getLocation()) < getEnergyConsumption()) {
|
|
||||||
return;
|
if (timeleft > 0) {
|
||||||
|
ChestMenuUtils.updateProgressbar(inv, 22, timeleft, processing.get(b).getTicks(), getProgressBar());
|
||||||
|
|
||||||
|
progress.put(b, timeleft - 1);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
inv.replaceExistingItem(22, new CustomItem(Material.BLACK_STAINED_GLASS_PANE, " "));
|
||||||
|
|
||||||
|
for (ItemStack output : processing.get(b).getOutput()) {
|
||||||
|
inv.pushItem(output.clone(), getOutputSlots());
|
||||||
}
|
}
|
||||||
|
|
||||||
removeCharge(b.getLocation(), getEnergyConsumption());
|
Bukkit.getPluginManager().callEvent(new AsyncMachineProcessCompleteEvent(b.getLocation(), AContainer.this, getProcessing(b)));
|
||||||
|
|
||||||
|
progress.remove(b);
|
||||||
|
processing.remove(b);
|
||||||
}
|
}
|
||||||
progress.put(b, timeleft - 1);
|
|
||||||
} else {
|
|
||||||
inv.replaceExistingItem(22, new CustomItem(Material.BLACK_STAINED_GLASS_PANE, " "));
|
|
||||||
|
|
||||||
for (ItemStack output : processing.get(b).getOutput()) {
|
|
||||||
inv.pushItem(output.clone(), getOutputSlots());
|
|
||||||
}
|
|
||||||
|
|
||||||
Bukkit.getPluginManager().callEvent(new AsyncMachineProcessCompleteEvent(b.getLocation(), AContainer.this, getProcessing(b)));
|
|
||||||
|
|
||||||
progress.remove(b);
|
|
||||||
processing.remove(b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
MachineRecipe next = findNextRecipe(inv);
|
MachineRecipe next = findNextRecipe(inv);
|
||||||
|
|
||||||
@ -273,6 +373,28 @@ public abstract class AContainer extends SlimefunItem implements InventoryBlock,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will remove charge from a location if it is chargeable.
|
||||||
|
*
|
||||||
|
* @param l
|
||||||
|
* location to try to remove charge from
|
||||||
|
* @return Whether charge was taken if its chargeable
|
||||||
|
*/
|
||||||
|
protected boolean takeCharge(@Nonnull Location l) {
|
||||||
|
Validate.notNull(l, "Can't attempt to take charge from a null location!");
|
||||||
|
|
||||||
|
if (isChargeable()) {
|
||||||
|
if (getCharge(l) < getEnergyConsumption()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
removeCharge(l, getEnergyConsumption());
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected MachineRecipe findNextRecipe(BlockMenu inv) {
|
protected MachineRecipe findNextRecipe(BlockMenu inv) {
|
||||||
Map<Integer, ItemStack> inventory = new HashMap<>();
|
Map<Integer, ItemStack> inventory = new HashMap<>();
|
||||||
|
|
||||||
|
@ -3,8 +3,11 @@ package me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@ -15,7 +18,9 @@ import org.bukkit.inventory.ItemStack;
|
|||||||
|
|
||||||
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
|
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
|
||||||
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
|
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
|
||||||
import io.github.thebusybiscuit.slimefun4.api.events.AsyncGeneratorProcessCompleteEvent;
|
import io.github.thebusybiscuit.slimefun4.api.events.AsyncGeneratorProcessCompleteEvent;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.api.items.ItemState;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.AbstractEnergyProvider;
|
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.AbstractEnergyProvider;
|
||||||
@ -42,6 +47,9 @@ public abstract class AGenerator extends AbstractEnergyProvider {
|
|||||||
private static final int[] border_in = { 9, 10, 11, 12, 18, 21, 27, 28, 29, 30 };
|
private static final int[] border_in = { 9, 10, 11, 12, 18, 21, 27, 28, 29, 30 };
|
||||||
private static final int[] border_out = { 14, 15, 16, 17, 23, 26, 32, 33, 34, 35 };
|
private static final int[] border_out = { 14, 15, 16, 17, 23, 26, 32, 33, 34, 35 };
|
||||||
|
|
||||||
|
private int energyProducedPerTick = -1;
|
||||||
|
private int energyCapacity = -1;
|
||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
public AGenerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
public AGenerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
|
||||||
super(category, item, recipeType, recipe);
|
super(category, item, recipeType, recipe);
|
||||||
@ -188,7 +196,7 @@ public abstract class AGenerator extends AbstractEnergyProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isBucket(ItemStack item) {
|
private boolean isBucket(@Nullable ItemStack item) {
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -210,4 +218,78 @@ public abstract class AGenerator extends AbstractEnergyProvider {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the max amount of electricity this machine can hold.
|
||||||
|
*
|
||||||
|
* @return The max amount of electricity this Block can store.
|
||||||
|
*/
|
||||||
|
public int getCapacity() {
|
||||||
|
return energyCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the amount of energy that is consumed per operation.
|
||||||
|
*
|
||||||
|
* @return The rate of energy consumption
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getEnergyProduction() {
|
||||||
|
return energyProducedPerTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This sets the energy capacity for this machine.
|
||||||
|
* This method <strong>must</strong> be called before registering the item
|
||||||
|
* and only before registering.
|
||||||
|
*
|
||||||
|
* @param capacity
|
||||||
|
* The amount of energy this machine can store
|
||||||
|
*
|
||||||
|
* @return This method will return the current instance of {@link AGenerator}, so that can be chained.
|
||||||
|
*/
|
||||||
|
public final AGenerator setCapacity(int capacity) {
|
||||||
|
Validate.isTrue(capacity >= 0, "The capacity cannot be negative!");
|
||||||
|
|
||||||
|
if (getState() == ItemState.UNREGISTERED) {
|
||||||
|
this.energyCapacity = capacity;
|
||||||
|
return this;
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("You cannot modify the capacity after the Item was registered.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the energy produced by this machine per tick.
|
||||||
|
*
|
||||||
|
* @param energyProduced
|
||||||
|
* The energy produced per tick
|
||||||
|
*
|
||||||
|
* @return This method will return the current instance of {@link AGenerator}, so that can be chained.
|
||||||
|
*/
|
||||||
|
public final AGenerator setEnergyProduction(int energyProduced) {
|
||||||
|
Validate.isTrue(energyProduced > 0, "The energy production must be greater than zero!");
|
||||||
|
|
||||||
|
this.energyProducedPerTick = energyProduced;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void register(@Nonnull SlimefunAddon addon) {
|
||||||
|
this.addon = addon;
|
||||||
|
|
||||||
|
if (getCapacity() < 0) {
|
||||||
|
warn("The capacity has not been configured correctly. The Item was disabled.");
|
||||||
|
warn("Make sure to call '" + getClass().getSimpleName() + "#setEnergyCapacity(...)' before registering!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getEnergyProduction() <= 0) {
|
||||||
|
warn("The energy consumption has not been configured correctly. The Item was disabled.");
|
||||||
|
warn("Make sure to call '" + getClass().getSimpleName() + "#setEnergyProduction(...)' before registering!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getCapacity() >= 0 && getEnergyProduction() > 0) {
|
||||||
|
super.register(addon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow;
|
|||||||
* @deprecated This interface is not designed to be used by addons.
|
* @deprecated This interface is not designed to be used by addons.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
// @Deprecated - commented out because we are not ready to send out warnings yet
|
@Deprecated
|
||||||
public interface InventoryBlock {
|
public interface InventoryBlock {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,6 +15,7 @@ import org.bukkit.inventory.InventoryView;
|
|||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||||
|
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
|
||||||
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
|
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
|
||||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow;
|
import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow;
|
||||||
@ -122,6 +123,33 @@ public abstract class BlockMenuPreset extends ChestMenu {
|
|||||||
throw new UnsupportedOperationException("BlockMenuPreset does not support this method.");
|
throw new UnsupportedOperationException("BlockMenuPreset does not support this method.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will draw unclickable background items into this {@link BlockMenuPreset}.
|
||||||
|
*
|
||||||
|
* @param item
|
||||||
|
* The {@link ItemStack} that should be used as background
|
||||||
|
* @param slots
|
||||||
|
* The slots which should be treated as background
|
||||||
|
*/
|
||||||
|
public void drawBackground(@Nonnull ItemStack item, @Nonnull int[] slots) {
|
||||||
|
Validate.notNull(item, "The background item cannot be null!");
|
||||||
|
checkIfLocked();
|
||||||
|
|
||||||
|
for (int slot : slots) {
|
||||||
|
addItem(slot, item, ChestMenuUtils.getEmptyClickHandler());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will draw unclickable background items into this {@link BlockMenuPreset}.
|
||||||
|
*
|
||||||
|
* @param slots
|
||||||
|
* The slots which should be treated as background
|
||||||
|
*/
|
||||||
|
public void drawBackground(@Nonnull int[] slots) {
|
||||||
|
drawBackground(ChestMenuUtils.getBackground(), slots);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChestMenu addItem(int slot, @Nullable ItemStack item) {
|
public ChestMenu addItem(int slot, @Nullable ItemStack item) {
|
||||||
checkIfLocked();
|
checkIfLocked();
|
||||||
|
@ -37,6 +37,7 @@ URID:
|
|||||||
networks:
|
networks:
|
||||||
max-size: 200
|
max-size: 200
|
||||||
cargo-ticker-delay: 0
|
cargo-ticker-delay: 0
|
||||||
|
enable-visualizer: true
|
||||||
|
|
||||||
items:
|
items:
|
||||||
talismans: true
|
talismans: true
|
||||||
|
@ -6,7 +6,7 @@ slimefun:
|
|||||||
food: 食物
|
food: 食物
|
||||||
basic_machines: 基礎機器
|
basic_machines: 基礎機器
|
||||||
electricity: 電力與能源
|
electricity: 電力與能源
|
||||||
gps: GPS機械
|
gps: GPS 機械
|
||||||
armor: 盔甲
|
armor: 盔甲
|
||||||
magical_items: 魔法物品
|
magical_items: 魔法物品
|
||||||
magical_gadgets: 魔法工具
|
magical_gadgets: 魔法工具
|
||||||
@ -16,11 +16,11 @@ slimefun:
|
|||||||
cargo: 物流管理
|
cargo: 物流管理
|
||||||
tech_misc: 科技組件
|
tech_misc: 科技組件
|
||||||
magical_armor: 魔法盔甲
|
magical_armor: 魔法盔甲
|
||||||
talismans: 護符(初級)
|
talismans: 護符(初級)
|
||||||
ender_talismans: 護符(終界)
|
ender_talismans: 護符(終界)
|
||||||
christmas: 聖誕節
|
christmas: 聖誕節
|
||||||
valentines_day: 西洋情人節
|
valentines_day: 西洋情人節
|
||||||
easter: 復活節
|
easter: 復活節
|
||||||
birthday: TheBusyBiscuit的生日(10月26日)
|
birthday: TheBusyBiscuit 的生日(10 月 26 日)
|
||||||
halloween: 萬聖節
|
halloween: 萬聖節
|
||||||
androids: 可編輯的機器人
|
androids: 可編輯的機器人
|
||||||
|
@ -245,9 +245,9 @@ messages:
|
|||||||
no-tome-yourself: "&cلا يمكنك إستعمال &4القاموس &cعلى نفسك..."
|
no-tome-yourself: "&cلا يمكنك إستعمال &4القاموس &cعلى نفسك..."
|
||||||
not-online: "&4%player% &cغير متصل!"
|
not-online: "&4%player% &cغير متصل!"
|
||||||
not-researched: "&4لا تملك خبرة لفهم هذا الأمر"
|
not-researched: "&4لا تملك خبرة لفهم هذا الأمر"
|
||||||
not-valid-amount: "&4%amount% &cليست قيمة صحيحة: يجب أن تكون أكثر من صفر!"
|
invalid-amount: "&4%amount% &cليست قيمة صحيحة: يجب أن تكون أكثر من صفر!"
|
||||||
not-valid-item: "&4%item% &cليس عنصر صحيح!"
|
invalid-item: "&4%item% &cليس عنصر صحيح!"
|
||||||
not-valid-research: "&4%research% &cليس بحث صحيح!"
|
invalid-research: "&4%research% &cليس بحث صحيح!"
|
||||||
only-players: "&4هذا الأمر لللاعبين فقط"
|
only-players: "&4هذا الأمر لللاعبين فقط"
|
||||||
opening-backpack: "&bيتم فتح الحقيبة، قد تستغرق ثوان..."
|
opening-backpack: "&bيتم فتح الحقيبة، قد تستغرق ثوان..."
|
||||||
opening-guide: "&bيتم فتح الكتيب، قد يستغرق ثوان..."
|
opening-guide: "&bيتم فتح الكتيب، قد يستغرق ثوان..."
|
||||||
|
@ -100,11 +100,11 @@ messages:
|
|||||||
no-permission: "&4Na tohle nemáš dostatečné povolení"
|
no-permission: "&4Na tohle nemáš dostatečné povolení"
|
||||||
usage: "&4Použití: &c%usage%"
|
usage: "&4Použití: &c%usage%"
|
||||||
not-online: "&4%player% &czrovna není připojen!"
|
not-online: "&4%player% &czrovna není připojen!"
|
||||||
not-valid-item: "&4%item% &cnení platný item!"
|
invalid-item: "&4%item% &cnení platný item!"
|
||||||
not-valid-amount: "&4%amount% &cnení platné číslo : musí být větší než 0!"
|
invalid-amount: "&4%amount% &cnení platné číslo : musí být větší než 0!"
|
||||||
given-item: '&bDostal jsi &a%amount% &7"%item%&7"'
|
given-item: '&bDostal jsi &a%amount% &7"%item%&7"'
|
||||||
give-item: '&bDal jsi %player% &a%amount% &7"%item%&7"'
|
give-item: '&bDal jsi %player% &a%amount% &7"%item%&7"'
|
||||||
not-valid-research: "&4%research% &cnení platný výzkum!"
|
invalid-research: "&4%research% &cnení platný výzkum!"
|
||||||
give-research: '&bUdělil jsi %player% výzkum &7"%research%&7"'
|
give-research: '&bUdělil jsi %player% výzkum &7"%research%&7"'
|
||||||
hungry: "&cJsi moc hladový na to, abys to zvládl!"
|
hungry: "&cJsi moc hladový na to, abys to zvládl!"
|
||||||
disabled-in-world: "&4&lTahle věc není v tomhle světě povolená"
|
disabled-in-world: "&4&lTahle věc není v tomhle světě povolená"
|
||||||
|
@ -108,11 +108,11 @@ messages:
|
|||||||
no-permission: "&4Du hast nicht die benötigten Rechte hierfür"
|
no-permission: "&4Du hast nicht die benötigten Rechte hierfür"
|
||||||
usage: "&4Korrekte Schreibweise: &c%usage%"
|
usage: "&4Korrekte Schreibweise: &c%usage%"
|
||||||
not-online: "&4%player% &cist derzeit nicht online!"
|
not-online: "&4%player% &cist derzeit nicht online!"
|
||||||
not-valid-item: "&4%item% &cist kein gültiges Item!"
|
invalid-item: "&4%item% &cist kein gültiges Item!"
|
||||||
not-valid-amount: "&4%amount% &cist keine gültige Anzahl! Sie muss höher als 0 sein!"
|
invalid-amount: "&4%amount% &cist keine gültige Anzahl! Sie muss höher als 0 sein!"
|
||||||
given-item: '&bDir wurde &a%amount% &7mal "%item%&7" gegeben'
|
given-item: '&bDir wurde &a%amount% &7mal "%item%&7" gegeben'
|
||||||
give-item: '&bDu hast %player% &a%amount% &7"%item%&7" gegeben'
|
give-item: '&bDu hast %player% &a%amount% &7"%item%&7" gegeben'
|
||||||
not-valid-research: "&4%research% &cist kein gültiger Erfahrungsgrad!"
|
invalid-research: "&4%research% &cist kein gültiger Erfahrungsgrad!"
|
||||||
give-research: '&bDu hast %player% den Erfahrungsgrad &7"%research%&7" vergeben'
|
give-research: '&bDu hast %player% den Erfahrungsgrad &7"%research%&7" vergeben'
|
||||||
hungry: "&cDu bist zu hungrig, um dies zu tun!"
|
hungry: "&cDu bist zu hungrig, um dies zu tun!"
|
||||||
disabled-in-world: "&4&lDieses Item wurde in dieser Welt deaktiviert!"
|
disabled-in-world: "&4&lDieses Item wurde in dieser Welt deaktiviert!"
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user