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

Merge branch 'master' into fix/industrial-miner-bug

This commit is contained in:
Jeff 2023-03-04 18:47:18 +08:00 committed by GitHub
commit 65df4d5a9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
97 changed files with 1087 additions and 753 deletions

View File

@ -117,8 +117,6 @@ body:
- 1.18.x
- 1.17.x
- 1.16.x
- 1.15.x
- 1.14.x
- (Older versions are not supported)
- id: slimefun-version

View File

@ -17,7 +17,7 @@
<!-- Don't worry, these are not requirements. They only serve as guidance. -->
- [ ] I have fully tested the proposed changes and promise that they will not break everything into chaos.
- [ ] I have also tested the proposed changes in combination with various popular addons and can confirm my changes do not break them.
- [ ] I have made sure that the proposed changes do not break compatibility across the supported Minecraft versions (1.14.* - 1.19.*).
- [ ] I have made sure that the proposed changes do not break compatibility across the supported Minecraft versions (1.16.* - 1.19.*).
- [ ] I followed the existing code standards and didn't mess up the formatting.
- [ ] I did my best to add documentation to any public classes or methods I added.
- [ ] I have added `Nonnull` and `Nullable` annotations to my methods to indicate their behaviour for null values

View File

@ -20,7 +20,7 @@ jobs:
steps:
- name: Approve via actions
uses: hmarr/auto-approve-action@v2.2.1
uses: hmarr/auto-approve-action@v3.1.0
if: github.actor == 'TheBusyBot' || github.actor == 'renovate[bot]'
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"

View File

@ -22,7 +22,7 @@ jobs:
steps:
- name: Auto squash
uses: pascalgn/automerge-action@v0.15.3
uses: pascalgn/automerge-action@v0.15.5
env:
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
UPDATE_RETRIES: 0
@ -42,7 +42,7 @@ jobs:
steps:
- name: Auto squash
uses: pascalgn/automerge-action@v0.15.3
uses: pascalgn/automerge-action@v0.15.5
env:
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
UPDATE_RETRIES: 0

View File

@ -21,10 +21,10 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v3.0.2
uses: actions/checkout@v3.3.0
- name: Set up Java JDK 17
uses: actions/setup-java@v3.4.1
uses: actions/setup-java@v3.10.0
with:
distribution: 'adopt'
java-version: '17'

View File

@ -12,6 +12,7 @@ on:
- '.github/workflows/**'
- 'src/**'
- 'pom.xml'
- 'CHANGELOG.md'
permissions:
contents: read
@ -27,7 +28,7 @@ jobs:
uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3.4.1
uses: actions/setup-java@v3.10.0
with:
distribution: 'adopt'
java-version: '17'

View File

@ -31,7 +31,7 @@ jobs:
api: '🔧 API'
compatibility: '🤝 Compatibility'
- uses: thollander/actions-comment-pull-request@v1.4.1
- uses: thollander/actions-comment-pull-request@v2.3.1
name: Leave a comment about the applied label
if: ${{ steps.labeller.outputs.applied != 0 }}
with:
@ -40,7 +40,7 @@ jobs:
Your Pull Request was automatically labelled as: "${{ steps.labeller.outputs.applied }}"
Thank you for contributing to this project! ❤️
- uses: thollander/actions-comment-pull-request@v1.4.1
- uses: thollander/actions-comment-pull-request@v2.3.1
name: Leave a comment about our branch naming convention
if: ${{ steps.labeller.outputs.applied == 0 }}
with:

View File

@ -19,12 +19,12 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v3.0.2
uses: actions/checkout@v3.3.0
with:
fetch-depth: 0
- name: Set up JDK 17
uses: actions/setup-java@v3.4.1
uses: actions/setup-java@v3.10.0
with:
distribution: 'adopt'
java-version: '17'

View File

@ -21,6 +21,6 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v3
- name: YAML Linter
uses: ibiqlik/action-yamllint@v3.1.0
uses: ibiqlik/action-yamllint@v3.1.1
with:
config_file: '.github/configs/yaml-linter.yml'

View File

@ -1,5 +1,6 @@
# Table of contents
- [Release Candidate 33 (TBD)](#release-candidate-33-tbd)
- [Release Candidate 34 (TBD)](#release-candidate-34-tbd)
- [Release Candidate 33 (07 Jan 2023)](#release-candidate-33-07-jan-2023)
- [Release Candidate 32 (26 Jun 2022)](#release-candidate-32-26-jun-2022)
- [Release Candidate 31 (14 Mar 2022)](#release-candidate-31-14-mar-2022)
- [Release Candidate 30 (31 Dec 2021)](#release-candidate-30-31-dec-2021)
@ -34,7 +35,35 @@
- [Release Candidate 1 (26 Sep 2019)](#release-candidate-1-26-sep-2019)
## Release Candidate 33 (TBD)
## Release Candidate 34 (TBD)
#### Additions
* Added "Cobbled Deepslate -> Gravel" recipe to the Grind Stone
* Added "Cobbled Deepslate -> Sand" recipe to the Ore Crusher
* (API) Added EnergyNet#getGenerators()
* (API) Added EnergyNet#getCapacitors()
* (API) Added EnergyNet#getConsumers()
* Added Bamboo as a fuel type for Tier 1 Androids
#### Changes
* Removed 1.14.* and 1.15.* support
* The Climbing Pick now also works on:
* Calcite
* Deepslate
* Dripstone blocks
* Smooth Basalt
* Tuff
* Clay
* Skulk
#### Fixes
* Fixed #3741
* Fixed #3724
* Fixed #3462
* Fixed #3758
## Release Candidate 33 (07 Jan 2023)
https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#33
#### Additions
* (API) Added Tinted Glass to "GLASS_BLOCKS" tag
@ -44,6 +73,8 @@
* (API) Added a method for item groups to allow addons to choose if they want to allow items from other addons
* Added a new option to Eletric Gold Pans: "override-output-limit"
* Added "Mud -> Clay" recipe to the Auto Drier
* Added a third tier for Freezers
* Added Glow Berry Juice
#### Changes
* Tree Growth Accelerators can now actually cause the Tree to fully grow (1.17+ only)
@ -51,12 +82,19 @@
* "Connected / Not connected" messages for cargo nodes are now sent via the actionbar
* "/sf stats" can no longer be used if researching is disabled
* "/sf research" can no longer be used if researching is disabled
* Removed the Hercules Pickaxe from Slimefun
* If CS-CoreLib is present, Slimefun will disable itself (previously it would just error)
#### Fixes
* Fixed #3597
* Fixed an issue related to "Bee Wings"
* Fixed #3573
* Fixed "round-robin" mode for cargo networks being very unreliable
* Fixed #3664
* Fixed #3651
* Fixed #3677
* Fixed #3705
* Fixed BlockPlacer being able to place disabled items
## Release Candidate 32 (26 Jun 2022)
https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#32

View File

@ -30,8 +30,8 @@ Here is a full summary of the differences between the two different versions of
| | development (latest) | "stable" |
| ------------------ | -------- | -------- |
| **Minecraft version(s)** | :video_game: **1.14.\* - 1.19.\*** | :video_game: **1.14.\* - 1.19.\*** |
| **Java version** | :computer: **Java 16 (or higher)** | :computer: **Java 8 (or higher)** |
| **Minecraft version(s)** | :video_game: **1.16.\* - 1.19.\*** | :video_game: **1.14.\* - 1.19.\*** |
| **Java version** | :computer: **Java 16 (or higher)** | :computer: **Java 16 (or higher)** |
| **automatic updates** | :heavy_check_mark: | :heavy_check_mark: |
| **frequent updates** | :heavy_check_mark: | :x: |
| **latest content** | :heavy_check_mark: | :x: |

26
pom.xml
View File

@ -115,7 +115,7 @@
<!-- Compiler plugin -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<version>3.11.0</version>
<configuration>
<excludes>
@ -146,7 +146,7 @@
<!-- Plugin for Unit Tests -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M7</version>
<version>3.0.0-M9</version>
<configuration>
<junitArtifactName>org.junit.jupiter:junit-jupiter</junitArtifactName>
@ -191,7 +191,7 @@
<!-- Dependency shading -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<version>3.4.1</version>
<configuration>
<!-- Relocate these to avoid clashes and conflicts -->
@ -239,7 +239,7 @@
<!-- Javadocs -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.4.0</version>
<version>3.5.0</version>
<configuration>
<reportOutputDirectory>${project.basedir}</reportOutputDirectory>
@ -360,13 +360,13 @@
<dependency>
<groupId>io.papermc</groupId>
<artifactId>paperlib</artifactId>
<version>1.0.7</version>
<version>1.0.8</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.konghq</groupId>
<artifactId>unirest-java</artifactId>
<version>3.13.10</version>
<version>3.14.1</version>
<scope>compile</scope>
<exclusions>
@ -382,13 +382,13 @@
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.9.0</version>
<version>5.9.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.6.1</version>
<version>5.1.1</version>
<scope>test</scope>
</dependency>
<dependency>
@ -411,7 +411,7 @@
<dependency>
<groupId>com.sk89q.worldedit</groupId>
<artifactId>worldedit-core</artifactId>
<version>7.2.11</version>
<version>7.2.13</version>
<scope>provided</scope>
<exclusions>
@ -425,7 +425,7 @@
<dependency>
<groupId>com.sk89q.worldedit</groupId>
<artifactId>worldedit-bukkit</artifactId>
<version>7.2.11</version>
<version>7.2.13</version>
<scope>provided</scope>
<exclusions>
@ -439,7 +439,7 @@
<dependency>
<groupId>com.gmail.nossr50.mcMMO</groupId>
<artifactId>mcMMO</artifactId>
<version>2.1.216</version>
<version>2.1.218</version>
<scope>provided</scope>
<exclusions>
@ -481,7 +481,7 @@
<dependency>
<groupId>com.github.LoneDev6</groupId>
<artifactId>itemsadder-api</artifactId>
<version>3.2.3c</version>
<version>3.2.5</version>
<scope>provided</scope>
<exclusions>
@ -495,7 +495,7 @@
<dependency>
<groupId>net.imprex</groupId>
<artifactId>orebfuscator-api</artifactId>
<version>5.2.6</version>
<version>5.3.0</version>
<scope>provided</scope>
<exclusions>

View File

@ -19,18 +19,6 @@ import io.papermc.lib.PaperLib;
*/
public enum MinecraftVersion {
/**
* This constant represents Minecraft (Java Edition) Version 1.14
* (The "Village &amp; Pillage" Update)
*/
MINECRAFT_1_14(14, "1.14.x"),
/**
* This constant represents Minecraft (Java Edition) Version 1.15
* (The "Buzzy Bees" Update)
*/
MINECRAFT_1_15(15, "1.15.x"),
/**
* This constant represents Minecraft (Java Edition) Version 1.16
* (The "Nether Update")

View File

@ -103,6 +103,10 @@ public class NestedItemGroup extends FlexItemGroup {
target++;
SubItemGroup itemGroup = subGroups.get(target);
if (!itemGroup.isVisibleInNested(p)) {
continue;
}
menu.addItem(index, itemGroup.getItem(p));
menu.addMenuClickHandler(index, (pl, slot, item, action) -> {
SlimefunGuide.openItemGroup(profile, itemGroup, mode, 1);

View File

@ -10,6 +10,7 @@ import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
/**
* The {@link SubItemGroup} is a child {@link ItemGroup} of the
@ -57,6 +58,24 @@ public class SubItemGroup extends ItemGroup {
return true;
}
/**
* This method returns whether this {@link SubItemGroup} can be viewed
* by the given {@link Player} in a {@link NestedItemGroup}.
* Empty {@link ItemGroup ItemGroups} will not be visible.
* This includes {@link ItemGroup ItemGroups} where every {@link SlimefunItem}
* is disabled. If an {@link ItemGroup} is not accessible by the {@link Player},
* see {@link #isAccessible(Player)}, this method will also return false.
*
* @param p
* The {@link Player} to check for
*
* @return Whether this {@link SubItemGroup} is visible to the given {@link Player}
* in the {@link NestedItemGroup}
*/
public final boolean isVisibleInNested(@Nonnull Player p) {
return super.isVisible(p);
}
/**
* This method returns the parent {@link NestedItemGroup} which this
* {@link SubItemGroup} belongs to.

View File

@ -1,10 +1,14 @@
package io.github.thebusybiscuit.slimefun4.api.player;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.CompletableFuture;
import javax.annotation.Nonnull;
import org.bukkit.Bukkit;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
@ -132,6 +136,30 @@ public class PlayerBackpack {
});
}
/**
* This will close the {@link Inventory} of this backpack for every {@link Player}
* that has opened it.
*
* This process has to run on the main server thread.
*
* @return A {@link CompletableFuture}.
*/
public CompletableFuture<Void> closeForAll() {
CompletableFuture<Void> future = new CompletableFuture<>();
Slimefun.runSync(() -> {
Iterator<HumanEntity> iterator = new ArrayList<>(inventory.getViewers()).iterator();
while (iterator.hasNext()) {
iterator.next().closeInventory();
}
future.complete(null);
});
return future;
}
/**
* This will change the current size of this Backpack to the specified size.
*

View File

@ -23,7 +23,6 @@ import org.bukkit.inventory.ItemStack;
import io.github.bakedlibs.dough.items.CustomItemStack;
import io.github.bakedlibs.dough.recipes.MinecraftRecipe;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlockMachine;
@ -56,6 +55,7 @@ public class RecipeType implements Keyed {
public static final RecipeType MOB_DROP = new RecipeType(new NamespacedKey(Slimefun.instance(), "mob_drop"), new CustomItemStack(Material.IRON_SWORD, "&bMob Drop"), RecipeType::registerMobDrop, "", "&rKill the specified Mob to obtain this Item");
public static final RecipeType BARTER_DROP = new RecipeType(new NamespacedKey(Slimefun.instance(), "barter_drop"), new CustomItemStack(Material.GOLD_INGOT, "&bBarter Drop"), RecipeType::registerBarterDrop, "&aBarter with piglins for a chance", "&ato obtain this item");
public static final RecipeType INTERACT = new RecipeType(new NamespacedKey(Slimefun.instance(), "interact"), new CustomItemStack(Material.PLAYER_HEAD, "&bInteract", "", "&a&oRight click with this item"));
public static final RecipeType HEATED_PRESSURE_CHAMBER = new RecipeType(new NamespacedKey(Slimefun.instance(), "heated_pressure_chamber"), SlimefunItems.HEATED_PRESSURE_CHAMBER);
public static final RecipeType FOOD_FABRICATOR = new RecipeType(new NamespacedKey(Slimefun.instance(), "food_fabricator"), SlimefunItems.FOOD_FABRICATOR);
@ -163,9 +163,7 @@ public class RecipeType implements Keyed {
@ParametersAreNonnullByDefault
private static void registerBarterDrop(ItemStack[] recipe, ItemStack output) {
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
Slimefun.getRegistry().getBarteringDrops().add(output);
}
Slimefun.getRegistry().getBarteringDrops().add(output);
}
@ParametersAreNonnullByDefault

View File

@ -91,7 +91,7 @@ public class RainbowTickHandler extends BlockTicker {
@Override
public void tick(Block b, SlimefunItem item, Config data) {
if (b.getType() == Material.AIR) {
if (b.getType().isAir()) {
/*
The block was broken, setting the Material now would result in a
duplication glitch

View File

@ -14,11 +14,9 @@ import org.bukkit.Tag;
import org.bukkit.World;
import org.bukkit.block.BlockFace;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.events.MultiBlockInteractEvent;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
import io.github.thebusybiscuit.slimefun4.core.handlers.MultiBlockInteractionHandler;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
/**
* A {@link MultiBlock} represents a structure build in a {@link World}.
@ -43,11 +41,7 @@ public class MultiBlock {
SUPPORTED_TAGS.add(Tag.WOODEN_TRAPDOORS);
SUPPORTED_TAGS.add(Tag.WOODEN_SLABS);
SUPPORTED_TAGS.add(Tag.WOODEN_FENCES);
// Add Soul Fire support on 1.16
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
SUPPORTED_TAGS.add(Tag.FIRE);
}
SUPPORTED_TAGS.add(Tag.FIRE);
}
@Nonnull
@ -155,7 +149,6 @@ public class MultiBlock {
public boolean isSymmetric() {
return isSymmetric;
}
@Override
public String toString() {
return "MultiBlock (" + item.getId() + ") {" + Arrays.toString(blocks) + "}";

View File

@ -69,21 +69,7 @@ final class CargoUtils {
}
Material type = block.getType();
// TODO: Add designated SlimefunTag
return switch (type) {
case CHEST,
TRAPPED_CHEST,
FURNACE,
DISPENSER,
DROPPER,
HOPPER,
BREWING_STAND,
BARREL,
BLAST_FURNACE,
SMOKER -> true;
default -> SlimefunTag.SHULKER_BOXES.isTagged(type);
};
return SlimefunTag.CARGO_SUPPORTED_STORAGE_BLOCKS.isTagged(type);
}
@Nonnull

View File

@ -1,5 +1,6 @@
package io.github.thebusybiscuit.slimefun4.core.networks.energy;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@ -31,7 +32,7 @@ import me.mrCookieSlime.Slimefun.api.BlockStorage;
/**
* The {@link EnergyNet} is an implementation of {@link Network} that deals with
* electrical energy being send from and to nodes.
* electrical energy being sent from and to nodes.
*
* @author meiamsome
* @author TheBusyBiscuit
@ -59,8 +60,35 @@ public class EnergyNet extends Network implements HologramOwner {
return RANGE;
}
/**
* This creates an immutable {@link Map} of {@link EnergyNetProvider}s within this {@link EnergyNet} instance.
*
* @return An immutable {@link Map} of generators
*/
public @Nonnull Map<Location, EnergyNetProvider> getGenerators() {
return Collections.unmodifiableMap(generators);
}
/**
* This creates an immutable {@link Map} of {@link EnergyNetComponentType#CAPACITOR} {@link EnergyNetComponent}s within this {@link EnergyNet} instance.
*
* @return An immutable {@link Map} of capacitors
*/
public @Nonnull Map<Location, EnergyNetComponent> getCapacitors() {
return Collections.unmodifiableMap(capacitors);
}
/**
* This creates an immutable {@link Map} of {@link EnergyNetComponentType#CONSUMER} {@link EnergyNetComponent}s within this {@link EnergyNet} instance.
*
* @return An immutable {@link Map} of consumers
*/
public @Nonnull Map<Location, EnergyNetComponent> getConsumers() {
return Collections.unmodifiableMap(consumers);
}
@Override
public String getId() {
public @Nonnull String getId() {
return "ENERGY_NETWORK";
}
@ -129,7 +157,9 @@ public class EnergyNet extends Network implements HologramOwner {
if (connectorNodes.isEmpty() && terminusNodes.isEmpty()) {
updateHologram(b, "&4No Energy Network found");
} else {
int supply = tickAllGenerators(timestamp::getAndAdd) + tickAllCapacitors();
int generatorsSupply = tickAllGenerators(timestamp::getAndAdd);
int capacitorsSupply = tickAllCapacitors();
int supply = NumberUtils.flowSafeAddition(generatorsSupply, capacitorsSupply);
int remainingEnergy = supply;
int demand = 0;
@ -141,7 +171,7 @@ public class EnergyNet extends Network implements HologramOwner {
if (charge < capacity) {
int availableSpace = capacity - charge;
demand += availableSpace;
demand = NumberUtils.flowSafeAddition(demand, availableSpace);
if (remainingEnergy > 0) {
if (remainingEnergy > availableSpace) {
@ -217,7 +247,7 @@ public class EnergyNet extends Network implements HologramOwner {
int energy = provider.getGeneratedOutput(loc, data);
if (provider.isChargeable()) {
energy += provider.getCharge(loc, data);
energy = NumberUtils.flowSafeAddition(energy, provider.getCharge(loc, data));
}
if (provider.willExplode(loc, data)) {
@ -229,7 +259,7 @@ public class EnergyNet extends Network implements HologramOwner {
loc.getWorld().createExplosion(loc, 0F, false);
});
} else {
supply += energy;
supply = NumberUtils.flowSafeAddition(supply, energy);
}
} catch (Exception | LinkageError throwable) {
explodedBlocks.add(loc);
@ -252,7 +282,7 @@ public class EnergyNet extends Network implements HologramOwner {
int supply = 0;
for (Map.Entry<Location, EnergyNetComponent> entry : capacitors.entrySet()) {
supply += entry.getValue().getCharge(entry.getKey());
supply = NumberUtils.flowSafeAddition(supply, entry.getValue().getCharge(entry.getKey()));
}
return supply;

View File

@ -6,6 +6,7 @@ import java.util.logging.Level;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.Keyed;
@ -137,32 +138,7 @@ public class BlockDataService implements Keyed {
return false;
}
// TODO: Add designated SlimefunTag
return switch (type) {
case PLAYER_HEAD,
PLAYER_WALL_HEAD,
CHEST,
DISPENSER,
BREWING_STAND,
DROPPER,
FURNACE,
BLAST_FURNACE,
HOPPER,
LECTERN,
JUKEBOX,
ENDER_CHEST,
ENCHANTING_TABLE,
DAYLIGHT_DETECTOR,
SMOKER,
BARREL,
SPAWNER,
BEACON ->
// All of the above Materials are Tile Entities
true;
default ->
// Otherwise we assume they're not Tile Entities
false;
};
return SlimefunTag.TILE_ENTITIES.isTagged(type);
}
}

View File

@ -269,6 +269,8 @@ public final class Slimefun extends JavaPlugin implements SlimefunAddon {
// Check if CS-CoreLib is installed (it is no longer needed)
if (getServer().getPluginManager().getPlugin("CS-CoreLib") != null) {
StartupWarnings.discourageCSCoreLib(logger);
getServer().getPluginManager().disablePlugin(this);
return;
}
// Encourage newer Java version
@ -630,18 +632,10 @@ public final class Slimefun extends JavaPlugin implements SlimefunAddon {
new AutoCrafterListener(this);
new SlimefunItemHitListener(this);
new MiddleClickListener(this);
// Bees were added in 1.15
if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_15)) {
new BeeListener(this);
new BeeWingsListener(this, (BeeWings) SlimefunItems.BEE_WINGS.getItem());
}
// Piglins were added in 1.16
if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
new PiglinListener(this);
new SmithingTableListener(this);
}
new BeeListener(this);
new BeeWingsListener(this, (BeeWings) SlimefunItems.BEE_WINGS.getItem());
new PiglinListener(this);
new SmithingTableListener(this);
// Item-specific Listeners
new CoolerListener(this, (Cooler) SlimefunItems.COOLER.getItem());

View File

@ -14,7 +14,6 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
import io.github.thebusybiscuit.slimefun4.core.attributes.MachineTier;
import io.github.thebusybiscuit.slimefun4.core.attributes.MachineType;
@ -149,6 +148,7 @@ public final class SlimefunItems {
public static final SlimefunItemStack CARROT_JUICE = new SlimefunItemStack("CARROT_JUICE", Color.ORANGE, new PotionEffect(PotionEffectType.SATURATION, 5, 0), "&6Carrot Juice", "", LoreBuilder.hunger(3));
public static final SlimefunItemStack PUMPKIN_JUICE = new SlimefunItemStack("PUMPKIN_JUICE", Color.ORANGE, new PotionEffect(PotionEffectType.SATURATION, 5, 0), "&6Pumpkin Juice", "", LoreBuilder.hunger(3));
public static final SlimefunItemStack SWEET_BERRY_JUICE = new SlimefunItemStack("SWEET_BERRY_JUICE", Color.RED, new PotionEffect(PotionEffectType.SATURATION, 5, 0), "&cSweet Berry Juice", "", LoreBuilder.hunger(3));
public static final SlimefunItemStack GLOW_BERRY_JUICE = new SlimefunItemStack("GLOW_BERRY_JUICE", Color.ORANGE, new PotionEffect(PotionEffectType.SATURATION, 5, 0), "&6Glow Berry Juice", "", LoreBuilder.hunger(3));
public static final SlimefunItemStack GOLDEN_APPLE_JUICE = new SlimefunItemStack("GOLDEN_APPLE_JUICE", Color.YELLOW, new PotionEffect(PotionEffectType.ABSORPTION, 20 * 20, 0), "&bGolden Apple Juice");
public static final SlimefunItemStack BEEF_JERKY = new SlimefunItemStack("BEEF_JERKY", Material.COOKED_BEEF, "&6Beef Jerky", "", "&fExtra saturating!");
@ -204,7 +204,6 @@ public final class SlimefunItems {
public static final SlimefunItemStack SMELTERS_PICKAXE = new SlimefunItemStack("SMELTERS_PICKAXE", Material.DIAMOND_PICKAXE, "&6Smelter's Pickaxe", "&c&lAuto-Smelting", "", "&9Works with Fortune");
public static final SlimefunItemStack LUMBER_AXE = new SlimefunItemStack("LUMBER_AXE", Material.DIAMOND_AXE, "&6Lumber Axe", "&a&oCuts down the whole Tree...");
public static final SlimefunItemStack PICKAXE_OF_CONTAINMENT = new SlimefunItemStack("PICKAXE_OF_CONTAINMENT", Material.IRON_PICKAXE, "&cPickaxe of Containment", "", "&9Can pickup Spawners");
public static final SlimefunItemStack HERCULES_PICKAXE = new SlimefunItemStack("HERCULES_PICKAXE", Material.IRON_PICKAXE, "&9Hercules' Pickaxe", "", "&4DEPRECATED - Will be removed soon", "", "&fSo powerful that it", "&fcrushes all mined Ores", "&finto Dust...");
public static final SlimefunItemStack EXPLOSIVE_PICKAXE = new SlimefunItemStack("EXPLOSIVE_PICKAXE", Material.DIAMOND_PICKAXE, "&eExplosive Pickaxe", "", "&fAllows you to mine a good bit", "&fof Blocks at once...", "", "&9Works with Fortune");
public static final SlimefunItemStack EXPLOSIVE_SHOVEL = new SlimefunItemStack("EXPLOSIVE_SHOVEL", Material.DIAMOND_SHOVEL, "&eExplosive Shovel", "", "&fAllows you to mine a good bit", "&fof diggable Blocks at once...");
public static final SlimefunItemStack PICKAXE_OF_THE_SEEKER = new SlimefunItemStack("PICKAXE_OF_THE_SEEKER", Material.DIAMOND_PICKAXE, "&aPickaxe of the Seeker", "&fWill always point you to the nearest Ore", "&fbut might get damaged when doing it", "", "&7&eRight Click&7 to be pointed to the nearest Ore");
@ -213,9 +212,6 @@ public final class SlimefunItems {
public static final SlimefunItemStack CLIMBING_PICK = new SlimefunItemStack("CLIMBING_PICK", Material.IRON_PICKAXE, "&bClimbing Pick", "", "&fAllows you to climb certain surfaces", "&fby right-clicking.", "&fEnchant this pick with Efficiency to", "&fclimb even faster!");
static {
HERCULES_PICKAXE.addUnsafeEnchantment(Enchantment.DURABILITY, 5);
HERCULES_PICKAXE.addUnsafeEnchantment(Enchantment.DIG_SPEED, 3);
COBALT_PICKAXE.addUnsafeEnchantment(Enchantment.DURABILITY, 10);
COBALT_PICKAXE.addUnsafeEnchantment(Enchantment.DIG_SPEED, 6);
}
@ -257,10 +253,7 @@ public final class SlimefunItems {
hazmatLore.add("");
hazmatLore.add(ChatColor.GOLD + "Full set effects:");
hazmatLore.add(ChatColor.YELLOW + "- Radiation immunity");
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_15)) {
hazmatLore.add(ChatColor.YELLOW + "- Bee Sting protection");
}
hazmatLore.add(ChatColor.YELLOW + "- Bee Sting protection");
}
public static final SlimefunItemStack SCUBA_HELMET = new SlimefunItemStack("SCUBA_HELMET", Material.LEATHER_HELMET, Color.ORANGE, "&cScuba Helmet", "", "&7Allows you to breathe underwater");
@ -835,6 +828,7 @@ public final class SlimefunItems {
public static final SlimefunItemStack FREEZER = new SlimefunItemStack("FREEZER", Material.LIGHT_BLUE_STAINED_GLASS, "&bFreezer", "", LoreBuilder.machine(MachineTier.ADVANCED, MachineType.MACHINE), LoreBuilder.speed(1), LoreBuilder.powerBuffer(256), LoreBuilder.powerPerSecond(18));
public static final SlimefunItemStack FREEZER_2 = new SlimefunItemStack("FREEZER_2", Material.LIGHT_BLUE_STAINED_GLASS, "&bFreezer &7(&eII&7)", "", LoreBuilder.machine(MachineTier.END_GAME, MachineType.MACHINE), LoreBuilder.speed(2), LoreBuilder.powerBuffer(256), LoreBuilder.powerPerSecond(30));
public static final SlimefunItemStack FREEZER_3 = new SlimefunItemStack("FREEZER_3", Material.LIGHT_GRAY_STAINED_GLASS, "&bFreezer &7(&eIII&7)", "", LoreBuilder.machine(MachineTier.END_GAME, MachineType.MACHINE), LoreBuilder.speed(3), LoreBuilder.powerBuffer(256), LoreBuilder.powerPerSecond(42));
public static final SlimefunItemStack ELECTRIC_GOLD_PAN = new SlimefunItemStack("ELECTRIC_GOLD_PAN", Material.BROWN_TERRACOTTA, "&6Electric Gold Pan", "", LoreBuilder.machine(MachineTier.BASIC, MachineType.MACHINE), LoreBuilder.speed(1), LoreBuilder.powerPerSecond(2));
public static final SlimefunItemStack ELECTRIC_GOLD_PAN_2 = new SlimefunItemStack("ELECTRIC_GOLD_PAN_2", Material.BROWN_TERRACOTTA, "&6Electric Gold Pan &7(&eII&7)", "", LoreBuilder.machine(MachineTier.BASIC, MachineType.MACHINE), LoreBuilder.speed(3), LoreBuilder.powerPerSecond(4));

View File

@ -24,14 +24,13 @@ final class StartupWarnings {
@ParametersAreNonnullByDefault
static void discourageCSCoreLib(Logger logger) {
logger.log(Level.WARNING, BORDER);
logger.log(Level.WARNING, PREFIX + "It looks like you are still using CS-CoreLib.");
logger.log(Level.WARNING, PREFIX);
logger.log(Level.WARNING, PREFIX + "Slimefun no longer requires CS-CoreLib to be");
logger.log(Level.WARNING, PREFIX + "installed as of January 30th 2021. It is safe");
logger.log(Level.WARNING, PREFIX + "to remove and we recommend you to uninstall");
logger.log(Level.WARNING, PREFIX + "CS-CoreLib from your server immediately.");
logger.log(Level.WARNING, BORDER);
logger.log(Level.SEVERE, BORDER);
logger.log(Level.SEVERE, PREFIX + "It looks like you are still using CS-CoreLib.");
logger.log(Level.SEVERE, PREFIX);
logger.log(Level.SEVERE, PREFIX + "Slimefun no longer requires CS-CoreLib to be");
logger.log(Level.SEVERE, PREFIX + "installed as of January 30th 2021. You need to");
logger.log(Level.SEVERE, PREFIX + "remove CS-CoreLib for Slimefun to run.");
logger.log(Level.SEVERE, BORDER);
}
@ParametersAreNonnullByDefault

View File

@ -332,7 +332,7 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation {
Slimefun.getLocalization().sendMessage(pl, "messages.no-permission", true);
}
} catch (Exception | LinkageError x) {
printErrorMessage(pl, x);
printErrorMessage(pl, sfitem, x);
}
return false;
@ -383,7 +383,7 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation {
displayItem(profile, slimefunItem, true);
}
} catch (Exception | LinkageError x) {
printErrorMessage(pl, x);
printErrorMessage(pl, slimefunItem, x);
}
return false;
@ -763,4 +763,10 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation {
Slimefun.logger().log(Level.SEVERE, "An error has occurred while trying to open a SlimefunItem in the guide!", x);
}
@ParametersAreNonnullByDefault
private void printErrorMessage(Player p, SlimefunItem item, Throwable x) {
p.sendMessage(ChatColor.DARK_RED + "An internal server error has occurred. Please inform an admin, check the console for further info.");
item.error("This item has caused an error message to be thrown while viewing it in the Slimefun guide.", x);
}
}

View File

@ -0,0 +1,27 @@
package io.github.thebusybiscuit.slimefun4.implementation.items;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
import io.github.thebusybiscuit.slimefun4.core.attributes.NotConfigurable;
/**
* The {@link HiddenItem} is a {@link NotConfigurable} {@link SlimefunItem}
* that is hidden from the Slimefun guide.
*
* @author char321
*
*/
public class HiddenItem extends SlimefunItem implements NotConfigurable {
@ParametersAreNonnullByDefault
public HiddenItem(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(itemGroup, item, recipeType, recipe);
this.setHidden(true);
}
}

View File

@ -51,7 +51,6 @@ import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import io.github.thebusybiscuit.slimefun4.utils.WorldUtils;
import io.papermc.lib.PaperLib;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
@ -95,7 +94,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
@Override
public boolean canOpen(Block b, Player p) {
boolean open = BlockStorage.getLocationInfo(b.getLocation(), "owner").equals(p.getUniqueId().toString()) || p.hasPermission("slimefun.android.bypass");
boolean open = p.getUniqueId().toString().equals(BlockStorage.getLocationInfo(b.getLocation(), "owner")) || p.hasPermission("slimefun.android.bypass");
if (!open) {
Slimefun.getLocalization().sendMessage(p, "inventory.no-access", true);
@ -603,9 +602,10 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
registerFuelType(new MachineFuel(45, new ItemStack(Material.BLAZE_ROD)));
registerFuelType(new MachineFuel(70, new ItemStack(Material.DRIED_KELP_BLOCK)));
// Coal & Charcoal
// Coal, Charcoal & Bamboo
registerFuelType(new MachineFuel(8, new ItemStack(Material.COAL)));
registerFuelType(new MachineFuel(8, new ItemStack(Material.CHARCOAL)));
registerFuelType(new MachineFuel(1, new ItemStack(Material.BAMBOO)));
// Logs
for (Material mat : Tag.LOGS.getValues()) {
@ -879,7 +879,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
@ParametersAreNonnullByDefault
protected void move(Block b, BlockFace face, Block block) {
if (block.getY() > WorldUtils.getMinHeight(block.getWorld()) && block.getY() < block.getWorld().getMaxHeight() && block.isEmpty()) {
if (block.getY() > block.getWorld().getMinHeight() && block.getY() < block.getWorld().getMaxHeight() && block.isEmpty()) {
if (!block.getWorld().getWorldBorder().isInside(block.getLocation())) {
return;

View File

@ -92,70 +92,73 @@ public class WoodcutterAndroid extends ProgrammableAndroid {
Predicate<Material> soilRequirement = null;
switch (logType) {
case OAK_LOG:
case OAK_WOOD:
case STRIPPED_OAK_LOG:
case STRIPPED_OAK_WOOD:
case OAK_LOG,
OAK_WOOD,
STRIPPED_OAK_LOG,
STRIPPED_OAK_WOOD -> {
saplingType = Material.OAK_SAPLING;
soilRequirement = SlimefunTag.DIRT_VARIANTS::isTagged;
break;
case BIRCH_LOG:
case BIRCH_WOOD:
case STRIPPED_BIRCH_LOG:
case STRIPPED_BIRCH_WOOD:
}
case BIRCH_LOG,
BIRCH_WOOD,
STRIPPED_BIRCH_LOG,
STRIPPED_BIRCH_WOOD -> {
saplingType = Material.BIRCH_SAPLING;
soilRequirement = SlimefunTag.DIRT_VARIANTS::isTagged;
break;
case JUNGLE_LOG:
case JUNGLE_WOOD:
case STRIPPED_JUNGLE_LOG:
case STRIPPED_JUNGLE_WOOD:
}
case JUNGLE_LOG,
JUNGLE_WOOD,
STRIPPED_JUNGLE_LOG,
STRIPPED_JUNGLE_WOOD -> {
saplingType = Material.JUNGLE_SAPLING;
soilRequirement = SlimefunTag.DIRT_VARIANTS::isTagged;
break;
case SPRUCE_LOG:
case SPRUCE_WOOD:
case STRIPPED_SPRUCE_LOG:
case STRIPPED_SPRUCE_WOOD:
}
case SPRUCE_LOG,
SPRUCE_WOOD,
STRIPPED_SPRUCE_LOG,
STRIPPED_SPRUCE_WOOD -> {
saplingType = Material.SPRUCE_SAPLING;
soilRequirement = SlimefunTag.DIRT_VARIANTS::isTagged;
break;
case ACACIA_LOG:
case ACACIA_WOOD:
case STRIPPED_ACACIA_LOG:
case STRIPPED_ACACIA_WOOD:
}
case ACACIA_LOG,
ACACIA_WOOD,
STRIPPED_ACACIA_LOG,
STRIPPED_ACACIA_WOOD -> {
saplingType = Material.ACACIA_SAPLING;
soilRequirement = SlimefunTag.DIRT_VARIANTS::isTagged;
break;
case DARK_OAK_LOG:
case DARK_OAK_WOOD:
case STRIPPED_DARK_OAK_LOG:
case STRIPPED_DARK_OAK_WOOD:
}
case DARK_OAK_LOG,
DARK_OAK_WOOD,
STRIPPED_DARK_OAK_LOG,
STRIPPED_DARK_OAK_WOOD -> {
saplingType = Material.DARK_OAK_SAPLING;
soilRequirement = SlimefunTag.DIRT_VARIANTS::isTagged;
break;
default:
break;
}
case CRIMSON_STEM,
CRIMSON_HYPHAE,
STRIPPED_CRIMSON_STEM,
STRIPPED_CRIMSON_HYPHAE -> {
saplingType = Material.CRIMSON_FUNGUS;
soilRequirement = SlimefunTag.FUNGUS_SOIL::isTagged;
}
case WARPED_STEM,
WARPED_HYPHAE,
STRIPPED_WARPED_STEM,
STRIPPED_WARPED_HYPHAE -> {
saplingType = Material.WARPED_FUNGUS;
soilRequirement = SlimefunTag.FUNGUS_SOIL::isTagged;
}
default -> {}
}
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_19)) {
switch (logType) {
case CRIMSON_STEM:
case CRIMSON_HYPHAE:
case STRIPPED_CRIMSON_STEM:
case STRIPPED_CRIMSON_HYPHAE:
saplingType = Material.CRIMSON_FUNGUS;
soilRequirement = SlimefunTag.FUNGUS_SOIL::isTagged;
break;
case WARPED_STEM:
case WARPED_HYPHAE:
case STRIPPED_WARPED_STEM:
case STRIPPED_WARPED_HYPHAE:
saplingType = Material.WARPED_FUNGUS;
soilRequirement = SlimefunTag.FUNGUS_SOIL::isTagged;
break;
default:
break;
case MANGROVE_LOG,
STRIPPED_MANGROVE_LOG -> {
saplingType = Material.MANGROVE_PROPAGULE;
soilRequirement = SlimefunTag.MANGROVE_BASE_BLOCKS::isTagged;
}
default -> {}
}
}

View File

@ -28,7 +28,6 @@ import org.bukkit.inventory.ItemStack;
import io.github.bakedlibs.dough.data.persistent.PersistentDataAPI;
import io.github.bakedlibs.dough.items.CustomItemStack;
import io.github.bakedlibs.dough.protection.Interaction;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
import io.github.thebusybiscuit.slimefun4.api.items.ItemState;
@ -202,13 +201,7 @@ public abstract class AbstractAutoCrafter extends SlimefunItem implements Energy
protected boolean isValidInventory(@Nonnull Block block) {
Material type = block.getType();
// TODO: Add designated SlimefunTag
return switch (type) {
case CHEST,
TRAPPED_CHEST,
BARREL -> true;
default -> SlimefunTag.SHULKER_BOXES.isTagged(type);
};
return SlimefunTag.AUTO_CRAFTER_SUPPORTED_STORAGE_BLOCKS.isTagged(type);
}
/**
@ -478,24 +471,15 @@ public abstract class AbstractAutoCrafter extends SlimefunItem implements Energy
private ItemStack getLeftoverItem(@Nonnull ItemStack item) {
Material type = item.getType();
switch (type) {
case WATER_BUCKET:
case LAVA_BUCKET:
case MILK_BUCKET:
return new ItemStack(Material.BUCKET);
case DRAGON_BREATH:
case POTION:
return new ItemStack(Material.GLASS_BOTTLE);
default:
MinecraftVersion minecraftVersion = Slimefun.getMinecraftVersion();
// Honey does not exist in 1.14
if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_15) && type == Material.HONEY_BOTTLE) {
return new ItemStack(Material.GLASS_BOTTLE);
} else {
return null;
}
}
return switch (type) {
case WATER_BUCKET,
LAVA_BUCKET,
MILK_BUCKET -> new ItemStack(Material.BUCKET);
case DRAGON_BREATH,
POTION,
HONEY_BOTTLE -> new ItemStack(Material.GLASS_BOTTLE);
default -> null;
};
}
/**

View File

@ -104,7 +104,7 @@ public class BlockPlacer extends SlimefunItem {
if (item != null) {
// Check if this Item can even be placed down
if (!(item instanceof NotPlaceable)) {
if (!(item instanceof NotPlaceable) && !item.isDisabledIn(dispenser.getWorld())) {
placeSlimefunBlock(item, e.getItem(), facedBlock, dispenser);
}
} else if (!Slimefun.getIntegrations().isCustomItem(e.getItem())) {

View File

@ -90,13 +90,11 @@ public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements Rec
items.add(new ItemStack(Material.LAVA_BUCKET));
}
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
items.add(new ItemStack(Material.BLACKSTONE, 8));
items.add(new ItemStack(Material.LAVA_BUCKET));
items.add(new ItemStack(Material.BLACKSTONE, 8));
items.add(new ItemStack(Material.LAVA_BUCKET));
items.add(new ItemStack(Material.BASALT, 12));
items.add(new ItemStack(Material.LAVA_BUCKET));
}
items.add(new ItemStack(Material.BASALT, 12));
items.add(new ItemStack(Material.LAVA_BUCKET));
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_17)) {
items.add(new ItemStack(Material.COBBLED_DEEPSLATE, 12));
@ -199,7 +197,7 @@ public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements Rec
}
private void placeLiquid(@Nonnull Block block, boolean water) {
if (block.getType() == Material.AIR || block.getType() == Material.CAVE_AIR || block.getType() == Material.VOID_AIR) {
if (block.getType().isAir()) {
// Fixes #2903 - Cancel physics update to resolve weird overlapping
block.setType(water ? Material.WATER : Material.LAVA, false);
} else {
@ -220,14 +218,13 @@ public class Crucible extends SimpleSlimefunItem<BlockUseHandler> implements Rec
@ParametersAreNonnullByDefault
private void runPostTask(Block block, Sound sound, int times) {
if (!(block.getBlockData() instanceof Levelled)) {
if (!(block.getBlockData() instanceof Levelled le)) {
block.getWorld().playSound(block.getLocation(), Sound.BLOCK_METAL_BREAK, 1F, 1F);
return;
}
block.getWorld().playSound(block.getLocation(), sound, 1F, 1F);
int level = 8 - times;
Levelled le = (Levelled) block.getBlockData();
le.setLevel(level);
block.setBlockData(le, false);

View File

@ -63,17 +63,13 @@ public class BioGenerator extends AGenerator {
registerFuel(new MachineFuel(1, new ItemStack(m)));
}
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_15)) {
registerFuel(new MachineFuel(4, new ItemStack(Material.HONEYCOMB)));
registerFuel(new MachineFuel(40, new ItemStack(Material.HONEYCOMB_BLOCK)));
}
registerFuel(new MachineFuel(4, new ItemStack(Material.HONEYCOMB)));
registerFuel(new MachineFuel(40, new ItemStack(Material.HONEYCOMB_BLOCK)));
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
registerFuel(new MachineFuel(4, new ItemStack(Material.SHROOMLIGHT)));
registerFuel(new MachineFuel(2, new ItemStack(Material.CRIMSON_FUNGUS)));
registerFuel(new MachineFuel(2, new ItemStack(Material.WARPED_FUNGUS)));
registerFuel(new MachineFuel(16, SlimefunItems.STRANGE_NETHER_GOO));
}
registerFuel(new MachineFuel(4, new ItemStack(Material.SHROOMLIGHT)));
registerFuel(new MachineFuel(2, new ItemStack(Material.CRIMSON_FUNGUS)));
registerFuel(new MachineFuel(2, new ItemStack(Material.WARPED_FUNGUS)));
registerFuel(new MachineFuel(16, SlimefunItems.STRANGE_NETHER_GOO));
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_17)) {
registerFuel(new MachineFuel(2, new ItemStack(Material.GLOW_BERRIES)));

View File

@ -75,9 +75,7 @@ public class ElectricPress extends AContainer implements RecipeDisplayItem {
addRecipe(8, new ItemStack(Material.EMERALD, 9), new ItemStack(Material.EMERALD_BLOCK));
addRecipe(8, new ItemStack(Material.DIAMOND, 9), new ItemStack(Material.DIAMOND_BLOCK));
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
addRecipe(16, new ItemStack(Material.NETHERITE_INGOT, 9), new ItemStack(Material.NETHERITE_BLOCK));
}
addRecipe(16, new ItemStack(Material.NETHERITE_INGOT, 9), new ItemStack(Material.NETHERITE_BLOCK));
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_17)) {
addRecipe(4, new ItemStack(Material.AMETHYST_SHARD, 4), new ItemStack(Material.AMETHYST_BLOCK));

View File

@ -35,10 +35,8 @@ public class ElectrifiedCrucible extends AContainer {
registerRecipe(10, new ItemStack[] { new ItemStack(Material.BUCKET), new ItemStack(leaves, 16) }, new ItemStack[] { new ItemStack(Material.WATER_BUCKET) });
}
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
registerRecipe(10, new ItemStack[] { new ItemStack(Material.BUCKET), new ItemStack(Material.BLACKSTONE, 8) }, new ItemStack[] { new ItemStack(Material.LAVA_BUCKET) });
registerRecipe(10, new ItemStack[] { new ItemStack(Material.BUCKET), new ItemStack(Material.BASALT, 12) }, new ItemStack[] { new ItemStack(Material.LAVA_BUCKET) });
}
registerRecipe(10, new ItemStack[] { new ItemStack(Material.BUCKET), new ItemStack(Material.BLACKSTONE, 8) }, new ItemStack[] { new ItemStack(Material.LAVA_BUCKET) });
registerRecipe(10, new ItemStack[] { new ItemStack(Material.BUCKET), new ItemStack(Material.BASALT, 12) }, new ItemStack[] { new ItemStack(Material.LAVA_BUCKET) });
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_17)) {
registerRecipe(10, new ItemStack[] { new ItemStack(Material.BUCKET), new ItemStack(Material.COBBLED_DEEPSLATE, 12) }, new ItemStack[] { new ItemStack(Material.LAVA_BUCKET) });

View File

@ -9,11 +9,9 @@ import org.bukkit.entity.IronGolem;
import org.bukkit.inventory.ItemStack;
import io.github.bakedlibs.dough.items.CustomItemStack;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset;
@ -73,11 +71,7 @@ public class IronGolemAssembler extends AbstractEntityAssembler<IronGolem> {
@Override
public IronGolem spawnEntity(Location l) {
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_15)) {
// This sound doesn't exist in 1.14 and earlier :/
l.getWorld().playSound(l, Sound.ENTITY_IRON_GOLEM_REPAIR, 0.5F, 1);
}
l.getWorld().playSound(l, Sound.ENTITY_IRON_GOLEM_REPAIR, 0.5F, 1);
return l.getWorld().spawn(l, IronGolem.class);
}

View File

@ -29,7 +29,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.utils.ChatUtils;
import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils;
import io.github.thebusybiscuit.slimefun4.utils.WorldUtils;
import io.papermc.lib.PaperLib;
import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu;
@ -95,7 +94,7 @@ public class ElevatorPlate extends SimpleSlimefunItem<BlockUseHandler> {
LinkedList<ElevatorFloor> floors = new LinkedList<>();
int index = 0;
for (int y = WorldUtils.getMinHeight(b.getWorld()); y < b.getWorld().getMaxHeight(); y++) {
for (int y = b.getWorld().getMinHeight(); y < b.getWorld().getMaxHeight(); y++) {
if (y == b.getY()) {
String name = ChatColors.color(BlockStorage.getLocationInfo(b.getLocation(), DATA_KEY));
floors.addFirst(new ElevatorFloor(name, index, b));

View File

@ -16,7 +16,6 @@ import org.bukkit.inventory.ItemStack;
import io.github.bakedlibs.dough.items.ItemUtils;
import io.github.bakedlibs.dough.protection.Interaction;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent;
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
@ -32,9 +31,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunIte
* This {@link SlimefunItem} allows you to convert any {@link ZombieVillager} to
* their {@link Villager} variant. It is also one of the very few utilisations of {@link EntityInteractHandler}.
*
* This item does not work on earlier versions than 1.14 as the {@link ZombieVillager} {@link EntityType}
* did not exist back then.
*
* @author Linox
*
* @see EntityInteractHandler
@ -64,7 +60,7 @@ public class MagicalZombiePills extends SimpleSlimefunItem<EntityInteractHandler
if (entity instanceof ZombieVillager zombieVillager) {
useItem(p, item);
healZombieVillager(zombieVillager, p);
} else if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16) && entity instanceof PigZombie pigZombie) {
} else if (entity instanceof PigZombie pigZombie) {
useItem(p, item);
healZombifiedPiglin(pigZombie);
}
@ -90,10 +86,7 @@ public class MagicalZombiePills extends SimpleSlimefunItem<EntityInteractHandler
private void healZombieVillager(@Nonnull ZombieVillager zombieVillager, @Nonnull Player p) {
zombieVillager.setConversionTime(1);
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_15)) {
zombieVillager.setConversionPlayer(p);
}
zombieVillager.setConversionPlayer(p);
}
private void healZombifiedPiglin(@Nonnull PigZombie zombiePiglin) {

View File

@ -3,6 +3,7 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -123,7 +124,11 @@ abstract class AbstractCraftingTable extends MultiBlockMachine {
PlayerProfile.fromUUID(UUID.fromString(idSplit[0]), profile -> {
Optional<PlayerBackpack> optional = profile.getBackpack(Integer.parseInt(idSplit[1]));
optional.ifPresent(playerBackpack -> playerBackpack.setSize(size));
optional.ifPresent(playerBackpack -> {
// Safety feature for Issue #3664
CompletableFuture<Void> future = playerBackpack.closeForAll();
future.thenRun(() -> playerBackpack.setSize(size));
});
});
return Optional.of(id);

View File

@ -50,7 +50,7 @@ public class ArmorForge extends AbstractCraftingTable {
}
}
if (SlimefunUtils.isInventoryEmpty(inv)) {
if (inv.isEmpty()) {
Slimefun.getLocalization().sendMessage(p, "machines.inventory-empty", true);
} else {
Slimefun.getLocalization().sendMessage(p, "machines.pattern-not-found", true);

View File

@ -52,7 +52,7 @@ public class EnhancedCraftingTable extends AbstractCraftingTable {
}
}
if (SlimefunUtils.isInventoryEmpty(inv)) {
if (inv.isEmpty()) {
Slimefun.getLocalization().sendMessage(p, "machines.inventory-empty", true);
} else {
Slimefun.getLocalization().sendMessage(p, "machines.pattern-not-found", true);

View File

@ -81,6 +81,9 @@ public class GrindStone extends MultiBlockMachine {
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_17)) {
recipes.add(new ItemStack(Material.AMETHYST_BLOCK));
recipes.add(new ItemStack(Material.AMETHYST_SHARD, 4));
recipes.add(new ItemStack(Material.COBBLED_DEEPSLATE));
recipes.add(new ItemStack(Material.GRAVEL));
}
recipes.add(SlimefunItems.MAGIC_LUMP_2);

View File

@ -59,7 +59,7 @@ public class MagicWorkbench extends AbstractCraftingTable {
}
}
if (SlimefunUtils.isInventoryEmpty(inv)) {
if (inv.isEmpty()) {
Slimefun.getLocalization().sendMessage(p, "machines.inventory-empty", true);
} else {
Slimefun.getLocalization().sendMessage(p, "machines.pattern-not-found", true);

View File

@ -97,6 +97,11 @@ public class OreCrusher extends MultiBlockMachine {
recipes.add(SlimefunItems.COMPRESSED_CARBON);
recipes.add(new SlimefunItemStack(SlimefunItems.CARBON, 4));
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_17)) {
recipes.add(new ItemStack(Material.COBBLED_DEEPSLATE, 8));
recipes.add(new ItemStack(Material.SAND, 1));
}
}
public boolean isOreDoublingEnabled() {
@ -119,13 +124,11 @@ public class OreCrusher extends MultiBlockMachine {
// @formatter:on
// Gold ore variants (1.16+)
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
displayRecipes.add(new ItemStack(Material.NETHER_GOLD_ORE));
displayRecipes.add(doubleOres.getGoldNuggets());
displayRecipes.add(new ItemStack(Material.NETHER_GOLD_ORE));
displayRecipes.add(doubleOres.getGoldNuggets());
displayRecipes.add(new ItemStack(Material.GILDED_BLACKSTONE));
displayRecipes.add(doubleOres.getGoldNuggets());
}
displayRecipes.add(new ItemStack(Material.GILDED_BLACKSTONE));
displayRecipes.add(doubleOres.getGoldNuggets());
// Raw metal ores (1.17+)
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_17)) {

View File

@ -44,7 +44,13 @@ public class TableSaw extends MultiBlockMachine {
@ParametersAreNonnullByDefault
public TableSaw(ItemGroup group, SlimefunItemStack item) {
super(group, item, new ItemStack[] { null, null, null, new ItemStack(Material.SMOOTH_STONE_SLAB), new ItemStack(Material.STONECUTTER), new ItemStack(Material.SMOOTH_STONE_SLAB), null, new ItemStack(Material.IRON_BLOCK), null }, BlockFace.SELF);
// @formatter:off
super(group, item, new ItemStack[] {
null, null, null,
new ItemStack(Material.SMOOTH_STONE_SLAB), new ItemStack(Material.STONECUTTER), new ItemStack(Material.SMOOTH_STONE_SLAB),
null, new ItemStack(Material.IRON_BLOCK), null
}, BlockFace.SELF);
// @formatter:on
for (Material log : Tag.LOGS.getValues()) {
Optional<Material> planks = getPlanks(log);
@ -61,10 +67,29 @@ public class TableSaw extends MultiBlockMachine {
}
}
/**
* This method returns the corresponding plank {@link Material} for a given wood {@link Material}.
* The result is wrapped by an {@link Optional}.
* <p>
* {@literal Material.OAK_LOG} for example will return {@literal Material.OAK_PLANKS}.
*
* @param log
* The log type.
*
* @return An {@link Optional} containing the corresponding plank type (or an empty {@link Optional})
*/
private @Nonnull Optional<Material> getPlanks(@Nonnull Material log) {
String materialName = log.name().replace("STRIPPED_", "");
materialName = materialName.substring(0, materialName.lastIndexOf('_')) + "_PLANKS";
return Optional.ofNullable(Material.getMaterial(materialName));
int endIndex = materialName.lastIndexOf('_');
if (endIndex > 0) {
materialName = materialName.substring(0, endIndex) + "_PLANKS";
return Optional.ofNullable(Material.getMaterial(materialName));
} else {
// Fixed #3651 - Do not panic because of one weird wood type.
warn("Could not find a corresponding plank for wood type: '" + log.name() + "'");
return Optional.empty();
}
}
@Override

View File

@ -29,7 +29,6 @@ import io.github.bakedlibs.dough.items.ItemUtils;
import io.github.bakedlibs.dough.protection.Interaction;
import io.github.bakedlibs.dough.scheduling.TaskQueue;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.utils.WorldUtils;
import io.papermc.lib.PaperLib;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel;
@ -190,7 +189,7 @@ class MiningTask implements Runnable {
furnace.getWorld().playEffect(furnace.getLocation(), Effect.STEP_SOUND, Material.STONE);
World world = start.getWorld();
for (int y = height; y > WorldUtils.getMinHeight(world); y--) {
for (int y = height; y > world.getMinHeight(); y--) {
Block b = world.getBlockAt(x, y, z);
if (!Slimefun.getProtectionManager().hasPermission(Bukkit.getOfflinePlayer(owner), b, Interaction.BREAK_BLOCK)) {

View File

@ -26,12 +26,9 @@ interface OreDictionary {
if (version.isAtLeast(MinecraftVersion.MINECRAFT_1_17)) {
// MC 1.17 - 1.18
return new OreDictionary17();
} else if (version.isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
} else {
// MC 1.16
return new OreDictionary16();
} else {
// MC 1.14 - 1.15
return new OreDictionary14();
}
}
}

View File

@ -1,35 +0,0 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.miner;
import java.util.Random;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
/**
* Our {@link OreDictionary} implementation for MC 1.14 or higher.
*
* @author TheBusyBiscuit
*
*/
class OreDictionary14 implements OreDictionary {
@Override
@ParametersAreNonnullByDefault
public @Nonnull ItemStack getDrops(Material material, Random random) {
return switch (material) {
case COAL_ORE -> new ItemStack(Material.COAL);
case DIAMOND_ORE -> new ItemStack(Material.DIAMOND);
case EMERALD_ORE -> new ItemStack(Material.EMERALD);
case REDSTONE_ORE -> new ItemStack(Material.REDSTONE, 4 + random.nextInt(2));
case LAPIS_ORE -> new ItemStack(Material.LAPIS_LAZULI, 4 + random.nextInt(4));
case NETHER_QUARTZ_ORE -> new ItemStack(Material.QUARTZ);
case IRON_ORE -> new ItemStack(Material.IRON_ORE);
case GOLD_ORE -> new ItemStack(Material.GOLD_ORE);
default -> new ItemStack(material);
};
}
}

View File

@ -14,16 +14,23 @@ import org.bukkit.inventory.ItemStack;
* @author TheBusyBiscuit
*
*/
class OreDictionary16 extends OreDictionary14 {
class OreDictionary16 implements OreDictionary {
@Override
@ParametersAreNonnullByDefault
public @Nonnull ItemStack getDrops(Material material, Random random) {
return switch (material) {
// In 1.16, breaking nether gold ores should get gold nuggets
case COAL_ORE -> new ItemStack(Material.COAL);
case DIAMOND_ORE -> new ItemStack(Material.DIAMOND);
case EMERALD_ORE -> new ItemStack(Material.EMERALD);
case REDSTONE_ORE -> new ItemStack(Material.REDSTONE, 4 + random.nextInt(2));
case LAPIS_ORE -> new ItemStack(Material.LAPIS_LAZULI, 4 + random.nextInt(4));
case NETHER_QUARTZ_ORE -> new ItemStack(Material.QUARTZ);
case IRON_ORE -> new ItemStack(Material.IRON_ORE);
case GOLD_ORE -> new ItemStack(Material.GOLD_ORE);
case NETHER_GOLD_ORE -> new ItemStack(Material.GOLD_NUGGET, 2 + random.nextInt(4));
case ANCIENT_DEBRIS -> new ItemStack(Material.ANCIENT_DEBRIS);
default -> super.getDrops(material, random);
default -> new ItemStack(material);
};
}

View File

@ -254,12 +254,10 @@ public class ClimbingPick extends SimpleSlimefunItem<ItemUseHandler> implements
if (version != MinecraftVersion.UNIT_TEST) {
p.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, b.getType());
if (version.isAtLeast(MinecraftVersion.MINECRAFT_1_15)) {
if (hand == EquipmentSlot.HAND) {
p.swingMainHand();
} else {
p.swingOffHand();
}
if (hand == EquipmentSlot.HAND) {
p.swingMainHand();
} else {
p.swingOffHand();
}
}
}

View File

@ -1,71 +0,0 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.tools;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import io.github.bakedlibs.dough.items.CustomItemStack;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
@Deprecated
public class HerculesPickaxe extends SimpleSlimefunItem<ToolUseHandler> {
@ParametersAreNonnullByDefault
public HerculesPickaxe(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(itemGroup, item, recipeType, recipe);
}
@Override
public @Nonnull ToolUseHandler getItemHandler() {
return (e, tool, fortune, drops) -> {
sendDeprecationWarning(e.getPlayer());
Material mat = e.getBlock().getType();
if (SlimefunTag.ORES.isTagged(mat)) {
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_17)) {
switch (mat) {
case DEEPSLATE_IRON_ORE:
drops.add(new CustomItemStack(SlimefunItems.IRON_DUST, 2));
break;
case DEEPSLATE_GOLD_ORE:
drops.add(new CustomItemStack(SlimefunItems.GOLD_DUST, 2));
break;
case COPPER_ORE:
case DEEPSLATE_COPPER_ORE:
drops.add(new CustomItemStack(SlimefunItems.COPPER_DUST, 2));
break;
default:
break;
}
}
switch (mat) {
case IRON_ORE:
drops.add(new CustomItemStack(SlimefunItems.IRON_DUST, 2));
break;
case GOLD_ORE:
drops.add(new CustomItemStack(SlimefunItems.GOLD_DUST, 2));
break;
default:
for (ItemStack drop : e.getBlock().getDrops(tool)) {
drops.add(new CustomItemStack(drop, drop.getAmount() * 2));
}
break;
}
}
};
}
}

View File

@ -33,7 +33,6 @@ import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.utils.WorldUtils;
/**
* The {@link SeismicAxe} is an interesting weapon. It spawns ghostly block entities in a straight line
@ -151,7 +150,7 @@ public class SeismicAxe extends SimpleSlimefunItem<ItemUseHandler> implements No
private @Nonnull Block findGround(@Nonnull Block b) {
if (b.getType() == Material.AIR) {
int minHeight = WorldUtils.getMinHeight(b.getWorld());
int minHeight = b.getWorld().getMinHeight();
for (int y = 0; b.getY() - y > minHeight; y++) {
Block block = b.getRelative(0, -y, 0);

View File

@ -141,7 +141,7 @@ public class AncientAltarListener implements Listener {
// Check if the Item in hand is valid
if (p.getInventory().getItemInMainHand().getType() != Material.AIR) {
// Check for pedestal obstructions
if (pedestal.getRelative(0, 1, 0).getType() != Material.AIR) {
if (!pedestal.getRelative(0, 1, 0).getType().isAir()) {
Slimefun.getLocalization().sendMessage(p, "machines.ANCIENT_PEDESTAL.obstructed", true);
return;
}

View File

@ -96,6 +96,7 @@ public class BackpackListener implements Listener {
if (backpack instanceof SlimefunBackpack slimefunBackpack) {
if (e.getClick() == ClickType.NUMBER_KEY) {
// Prevent disallowed items from being moved using number keys.
if (e.getClickedInventory().getType() != InventoryType.PLAYER) {
ItemStack hotbarItem = e.getWhoClicked().getInventory().getItem(e.getHotbarButton());
@ -103,12 +104,19 @@ public class BackpackListener implements Listener {
e.setCancelled(true);
}
}
} else if (e.getClick() == ClickType.SWAP_OFFHAND && e.getClickedInventory().getType() != InventoryType.PLAYER) {
// Fixes #3265
ItemStack offHandItem = e.getWhoClicked().getInventory().getItemInOffHand();
} else if (e.getClick() == ClickType.SWAP_OFFHAND) {
if (e.getClickedInventory().getType() != InventoryType.PLAYER) {
// Fixes #3265 - Don't move disallowed items using the off hand.
ItemStack offHandItem = e.getWhoClicked().getInventory().getItemInOffHand();
if (!isAllowed(slimefunBackpack, offHandItem)) {
e.setCancelled(true);
if (!isAllowed(slimefunBackpack, offHandItem)) {
e.setCancelled(true);
}
} else {
// Fixes #3664 - Do not swap the backpack to your off hand.
if (e.getCurrentItem() != null && e.getCurrentItem().isSimilar(item)) {
e.setCancelled(true);
}
}
} else if (!isAllowed(slimefunBackpack, e.getCurrentItem())) {
e.setCancelled(true);

View File

@ -70,6 +70,11 @@ public class EnhancedFurnaceListener implements Listener {
if (state instanceof Furnace furnace) {
FurnaceInventory inventory = furnace.getInventory();
// This if statement fixes #3741
if (inventory.getSmelting() == null) {
return;
}
boolean multiplier = SlimefunTag.ENHANCED_FURNACE_LUCK_MATERIALS.isTagged(inventory.getSmelting().getType());
int amount = multiplier ? enhancedFurnace.getRandomOutputAmount() : 1;
Optional<ItemStack> result = Slimefun.getMinecraftRecipeService().getFurnaceOutput(inventory.getSmelting());

View File

@ -3,9 +3,7 @@ package io.github.thebusybiscuit.slimefun4.implementation.resources;
import org.bukkit.World.Environment;
import org.bukkit.block.Biome;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.utils.biomes.BiomeMap;
@ -25,12 +23,7 @@ class NetherIceResource extends AbstractResource {
NetherIceResource() {
super("nether_ice", "Nether Ice", SlimefunItems.NETHER_ICE, 6, true);
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
// 1.16+ introduced Nether biomes
biomes = getBiomeMap(this, "/biome-maps/nether_ice_v1.16.json");
} else {
biomes = getBiomeMap(this, "/biome-maps/nether_ice_v1.14.json");
}
biomes = getBiomeMap(this, "/biome-maps/nether_ice_v1.16.json");
}
@Override

View File

@ -36,7 +36,7 @@ class OilResource extends AbstractResource {
// 1.18+ renamed most biomes
biomes = getBiomeMap(this, "/biome-maps/oil_v1.18.json");
} else {
biomes = getBiomeMap(this, "/biome-maps/oil_v1.14.json");
biomes = getBiomeMap(this, "/biome-maps/oil_v1.16.json");
}
}

View File

@ -30,7 +30,7 @@ class SaltResource extends AbstractResource {
// 1.18+ renamed most biomes
biomes = getBiomeMap(this, "/biome-maps/salt_v1.18.json");
} else {
biomes = getBiomeMap(this, "/biome-maps/salt_v1.14.json");
biomes = getBiomeMap(this, "/biome-maps/salt_v1.16.json");
}
}

View File

@ -32,11 +32,8 @@ class UraniumResource extends AbstractResource {
} else if (version.isAtLeast(MinecraftVersion.MINECRAFT_1_17)) {
// 1.17+ introduced cave biomes
biomes = getBiomeMap(this, "/biome-maps/uranium_v1.17.json");
} else if (version.isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
// 1.16+ introduced Nether biomes
biomes = getBiomeMap(this, "/biome-maps/uranium_v1.16.json");
} else {
biomes = getBiomeMap(this, "/biome-maps/uranium_v1.14.json");
biomes = getBiomeMap(this, "/biome-maps/uranium_v1.16.json");
}
}

View File

@ -113,7 +113,6 @@ public final class ResearchSetup {
register("gold_armor", 87, "Shiny Armor", 13, SlimefunItems.GOLDEN_HELMET_12K, SlimefunItems.GOLDEN_CHESTPLATE_12K, SlimefunItems.GOLDEN_LEGGINGS_12K, SlimefunItems.GOLDEN_BOOTS_12K);
register("night_vision_googles", 89, "Night Vision Goggles", 10, SlimefunItems.NIGHT_VISION_GOGGLES);
register("pickaxe_of_containment", 90, "Pickaxe of Containment", 14, SlimefunItems.PICKAXE_OF_CONTAINMENT, SlimefunItems.BROKEN_SPAWNER);
register("hercules_pickaxe", 91, "Hercules Pickaxe", 28, SlimefunItems.HERCULES_PICKAXE);
register("table_saw", 92, "Table Saw", 4, SlimefunItems.TABLE_SAW);
register("slime_steel_armor", 93, "Slimy Steel Armor", 27, SlimefunItems.SLIME_HELMET_STEEL, SlimefunItems.SLIME_CHESTPLATE_STEEL, SlimefunItems.SLIME_LEGGINGS_STEEL, SlimefunItems.SLIME_BOOTS_STEEL);
register("blade_of_vampires", 94, "Blade of Vampires", 26, SlimefunItems.BLADE_OF_VAMPIRES);
@ -144,7 +143,7 @@ public final class ResearchSetup {
register("bound_weapons", 125, "Soulbound Weapons", 29, SlimefunItems.SOULBOUND_SWORD, SlimefunItems.SOULBOUND_BOW, SlimefunItems.SOULBOUND_TRIDENT);
register("bound_tools", 126, "Soulbound Tools", 29, SlimefunItems.SOULBOUND_PICKAXE, SlimefunItems.SOULBOUND_AXE, SlimefunItems.SOULBOUND_SHOVEL, SlimefunItems.SOULBOUND_HOE);
register("bound_armor", 127, "Soulbound Armor", 29, SlimefunItems.SOULBOUND_HELMET, SlimefunItems.SOULBOUND_CHESTPLATE, SlimefunItems.SOULBOUND_LEGGINGS, SlimefunItems.SOULBOUND_BOOTS);
register("juicer", 129, "Delicious Drinks", 29, SlimefunItems.JUICER, SlimefunItems.APPLE_JUICE, SlimefunItems.MELON_JUICE, SlimefunItems.CARROT_JUICE, SlimefunItems.PUMPKIN_JUICE, SlimefunItems.SWEET_BERRY_JUICE);
register("juicer", 129, "Delicious Drinks", 29, SlimefunItems.JUICER, SlimefunItems.APPLE_JUICE, SlimefunItems.MELON_JUICE, SlimefunItems.CARROT_JUICE, SlimefunItems.PUMPKIN_JUICE, SlimefunItems.SWEET_BERRY_JUICE, SlimefunItems.GLOW_BERRY_JUICE);
register("repaired_spawner", 130, "Repairing Spawners", 15, SlimefunItems.REPAIRED_SPAWNER);
register("enhanced_furnace", 132, "Enhanced Furnace", 7, SlimefunItems.ENHANCED_FURNACE, SlimefunItems.ENHANCED_FURNACE_2);
register("more_enhanced_furnaces", 133, "Better Furnaces", 18, SlimefunItems.ENHANCED_FURNACE_3, SlimefunItems.ENHANCED_FURNACE_4, SlimefunItems.ENHANCED_FURNACE_5, SlimefunItems.ENHANCED_FURNACE_6, SlimefunItems.ENHANCED_FURNACE_7);
@ -221,7 +220,7 @@ public final class ResearchSetup {
register("better_food_fabricator", 211, "Upgraded Food Fabrication", 28, SlimefunItems.FOOD_FABRICATOR_2, SlimefunItems.FOOD_COMPOSTER_2);
register("reactor_access_port", 212, "Reactor Interaction", 18, SlimefunItems.REACTOR_ACCESS_PORT);
register("fluid_pump", 213, "Fluid Pump", 28, SlimefunItems.FLUID_PUMP);
register("better_freezer", 214, "Upgraded Freezer", 29, SlimefunItems.FREEZER_2);
register("better_freezer", 214, "Upgraded Freezer", 29, SlimefunItems.FREEZER_2, SlimefunItems.FREEZER_3);
register("boosted_uranium", 215, "Never-Ending Circle", 30, SlimefunItems.BOOSTED_URANIUM);
register("trash_can", 216, "Trash", 8, SlimefunItems.TRASH_CAN);
register("advanced_output_node", 217, "Advanced Output Node", 24, SlimefunItems.CARGO_OUTPUT_NODE_2);

View File

@ -26,6 +26,7 @@ import io.github.thebusybiscuit.slimefun4.core.attributes.Radioactivity;
import io.github.thebusybiscuit.slimefun4.core.handlers.RainbowTickHandler;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.items.HiddenItem;
import io.github.thebusybiscuit.slimefun4.implementation.items.RadioactiveItem;
import io.github.thebusybiscuit.slimefun4.implementation.items.VanillaItem;
import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientAltar;
@ -195,7 +196,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.tools.ExplosivePi
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.ExplosiveShovel;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.GoldPan;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.GrapplingHook;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.HerculesPickaxe;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.LumberAxe;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.NetherGoldPan;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.PickaxeOfContainment;
@ -532,11 +532,11 @@ public final class SlimefunItemSetup {
new ItemStack[] {SlimefunItems.SIFTED_ORE, null, null, null, null, null, null, null, null})
.register(plugin);
new SlimefunItem(itemGroups.resources, SlimefunItems.LEAD_DUST, RecipeType.ORE_WASHER,
new SlimefunItem(itemGroups.resources, SlimefunItems.SILVER_DUST, RecipeType.ORE_WASHER,
new ItemStack[] {SlimefunItems.SIFTED_ORE, null, null, null, null, null, null, null, null})
.register(plugin);
new SlimefunItem(itemGroups.resources, SlimefunItems.SILVER_DUST, RecipeType.ORE_WASHER,
new SlimefunItem(itemGroups.resources, SlimefunItems.LEAD_DUST, RecipeType.ORE_WASHER,
new ItemStack[] {SlimefunItems.SIFTED_ORE, null, null, null, null, null, null, null, null})
.register(plugin);
@ -1032,10 +1032,6 @@ public final class SlimefunItemSetup {
new ItemStack[] {SlimefunItems.FERROSILICON, SlimefunItems.FERROSILICON, SlimefunItems.FERROSILICON, null, SlimefunItems.GILDED_IRON, null, null, SlimefunItems.GILDED_IRON, null})
.register(plugin);
new HerculesPickaxe(itemGroups.tools, SlimefunItems.HERCULES_PICKAXE, RecipeType.MAGIC_WORKBENCH,
new ItemStack[] {SlimefunItems.HARDENED_METAL_INGOT, SlimefunItems.HARDENED_METAL_INGOT, SlimefunItems.HARDENED_METAL_INGOT, null, SlimefunItems.FERROSILICON, null, null, SlimefunItems.FERROSILICON, null})
.register(plugin);
new TableSaw(itemGroups.basicMachines, SlimefunItems.TABLE_SAW).register(plugin);
new SlimefunArmorPiece(itemGroups.magicalArmor, SlimefunItems.SLIME_HELMET_STEEL, RecipeType.ARMOR_FORGE,
@ -1376,6 +1372,10 @@ public final class SlimefunItemSetup {
new SlimefunItemStack(SlimefunItems.FLASK_OF_KNOWLEDGE, 8))
.register(plugin);
new HiddenItem(itemGroups.magicalGadgets, SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE, RecipeType.INTERACT,
new ItemStack[] {SlimefunItems.FLASK_OF_KNOWLEDGE, null, null, null, null, null, null, null, null})
.register(plugin);
new BirthdayCake(itemGroups.birthday, new SlimefunItemStack("BIRTHDAY_CAKE", Material.CAKE, "&bBirthday Cake"), RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {null, new ItemStack(Material.TORCH), null, new ItemStack(Material.SUGAR), new ItemStack(Material.CAKE), new ItemStack(Material.SUGAR), null, null, null})
.register(plugin);
@ -2444,6 +2444,13 @@ public final class SlimefunItemSetup {
.setProcessingSpeed(2)
.register(plugin);
new Freezer(itemGroups.electricity, SlimefunItems.FREEZER_3, RecipeType.ENHANCED_CRAFTING_TABLE,
new ItemStack[] {SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.REINFORCED_ALLOY_INGOT, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.FREEZER_2, SlimefunItems.ELECTRO_MAGNET, SlimefunItems.COOLING_UNIT, SlimefunItems.COOLING_UNIT, SlimefunItems.COOLING_UNIT})
.setCapacity(256)
.setEnergyConsumption(21)
.setProcessingSpeed(3)
.register(plugin);
new CoolantCell(itemGroups.technicalComponents, SlimefunItems.REACTOR_COOLANT_CELL, RecipeType.FREEZER,
new ItemStack[] {new ItemStack(Material.BLUE_ICE), null, null, null, null, null, null, null, null})
.register(plugin);
@ -2584,33 +2591,35 @@ public final class SlimefunItemSetup {
MinecraftVersion minecraftVersion = Slimefun.getMinecraftVersion();
if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_15)) {
new SlimefunItem(itemGroups.magicalArmor, SlimefunItems.BEE_HELMET, RecipeType.ARMOR_FORGE,
new ItemStack[] {SlimefunItems.GOLD_8K, new ItemStack(Material.HONEY_BLOCK), SlimefunItems.GOLD_8K, new ItemStack(Material.HONEYCOMB_BLOCK), null, new ItemStack(Material.HONEYCOMB_BLOCK), null, null, null})
.register(plugin);
new SlimefunItem(itemGroups.magicalArmor, SlimefunItems.BEE_HELMET, RecipeType.ARMOR_FORGE,
new ItemStack[] {SlimefunItems.GOLD_8K, new ItemStack(Material.HONEY_BLOCK), SlimefunItems.GOLD_8K, new ItemStack(Material.HONEYCOMB_BLOCK), null, new ItemStack(Material.HONEYCOMB_BLOCK), null, null, null})
.register(plugin);
new BeeWings(itemGroups.magicalArmor, SlimefunItems.BEE_WINGS, RecipeType.ARMOR_FORGE,
new ItemStack[] {SlimefunItems.GOLD_8K, null, SlimefunItems.GOLD_8K, new ItemStack(Material.HONEYCOMB_BLOCK), new ItemStack(Material.ELYTRA), new ItemStack(Material.HONEYCOMB_BLOCK), new ItemStack(Material.HONEY_BLOCK), SlimefunItems.GOLD_8K, new ItemStack(Material.HONEY_BLOCK)})
.register(plugin);
new BeeWings(itemGroups.magicalArmor, SlimefunItems.BEE_WINGS, RecipeType.ARMOR_FORGE,
new ItemStack[] {SlimefunItems.GOLD_8K, null, SlimefunItems.GOLD_8K, new ItemStack(Material.HONEYCOMB_BLOCK), new ItemStack(Material.ELYTRA), new ItemStack(Material.HONEYCOMB_BLOCK), new ItemStack(Material.HONEY_BLOCK), SlimefunItems.GOLD_8K, new ItemStack(Material.HONEY_BLOCK)})
.register(plugin);
new SlimefunItem(itemGroups.magicalArmor, SlimefunItems.BEE_LEGGINGS, RecipeType.ARMOR_FORGE,
new ItemStack[] {SlimefunItems.GOLD_8K, new ItemStack(Material.HONEY_BLOCK), SlimefunItems.GOLD_8K, new ItemStack(Material.HONEYCOMB_BLOCK), null, new ItemStack(Material.HONEYCOMB_BLOCK), new ItemStack(Material.HONEYCOMB_BLOCK), null, new ItemStack(Material.HONEYCOMB_BLOCK)})
.register(plugin);
new SlimefunItem(itemGroups.magicalArmor, SlimefunItems.BEE_LEGGINGS, RecipeType.ARMOR_FORGE,
new ItemStack[] {SlimefunItems.GOLD_8K, new ItemStack(Material.HONEY_BLOCK), SlimefunItems.GOLD_8K, new ItemStack(Material.HONEYCOMB_BLOCK), null, new ItemStack(Material.HONEYCOMB_BLOCK), new ItemStack(Material.HONEYCOMB_BLOCK), null, new ItemStack(Material.HONEYCOMB_BLOCK)})
.register(plugin);
new LongFallBoots(itemGroups.magicalArmor, SlimefunItems.BEE_BOOTS, RecipeType.ARMOR_FORGE,
new ItemStack[] {null, null, null, SlimefunItems.GOLD_8K, null, SlimefunItems.GOLD_8K, new ItemStack(Material.HONEY_BLOCK), null, new ItemStack(Material.HONEY_BLOCK)},
new PotionEffect[] {new PotionEffect(PotionEffectType.JUMP, 300, 2)})
.register(plugin);
}
new LongFallBoots(itemGroups.magicalArmor, SlimefunItems.BEE_BOOTS, RecipeType.ARMOR_FORGE,
new ItemStack[] {null, null, null, SlimefunItems.GOLD_8K, null, SlimefunItems.GOLD_8K, new ItemStack(Material.HONEY_BLOCK), null, new ItemStack(Material.HONEY_BLOCK)},
new PotionEffect[] {new PotionEffect(PotionEffectType.JUMP, 300, 2)})
.register(plugin);
if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
new VillagerRune(itemGroups.magicalResources, SlimefunItems.VILLAGER_RUNE, RecipeType.ANCIENT_ALTAR,
new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, SlimefunItems.MAGICAL_GLASS, new ItemStack(Material.CRYING_OBSIDIAN), SlimefunItems.STRANGE_NETHER_GOO, SlimefunItems.FIRE_RUNE, SlimefunItems.STRANGE_NETHER_GOO, new ItemStack(Material.CRYING_OBSIDIAN), SlimefunItems.MAGICAL_GLASS, SlimefunItems.MAGIC_LUMP_3},
new SlimefunItemStack(SlimefunItems.VILLAGER_RUNE, 3))
.register(plugin);
new VillagerRune(itemGroups.magicalResources, SlimefunItems.VILLAGER_RUNE, RecipeType.ANCIENT_ALTAR,
new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, SlimefunItems.MAGICAL_GLASS, new ItemStack(Material.CRYING_OBSIDIAN), SlimefunItems.STRANGE_NETHER_GOO, SlimefunItems.FIRE_RUNE, SlimefunItems.STRANGE_NETHER_GOO, new ItemStack(Material.CRYING_OBSIDIAN), SlimefunItems.MAGICAL_GLASS, SlimefunItems.MAGIC_LUMP_3},
new SlimefunItemStack(SlimefunItems.VILLAGER_RUNE, 3))
.register(plugin);
new StrangeNetherGoo(itemGroups.magicalResources, SlimefunItems.STRANGE_NETHER_GOO, RecipeType.BARTER_DROP,
new ItemStack[] {null, null, null, null, new CustomItemStack(HeadTexture.PIGLIN_HEAD.getAsItemStack(), "&fPiglin"), null, null, null, null})
new StrangeNetherGoo(itemGroups.magicalResources, SlimefunItems.STRANGE_NETHER_GOO, RecipeType.BARTER_DROP,
new ItemStack[] {null, null, null, null, new CustomItemStack(HeadTexture.PIGLIN_HEAD.getAsItemStack(), "&fPiglin"), null, null, null, null})
.register(plugin);
if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_17)) {
new Juice(itemGroups.food, SlimefunItems.GLOW_BERRY_JUICE, RecipeType.JUICER,
new ItemStack[] {new ItemStack(Material.GLOW_BERRIES), null, null, null, null, null, null, null, null})
.register(plugin);
}

View File

@ -100,14 +100,7 @@ public class TickerTask implements Runnable {
}
// Fixes #2576 - Remove any deleted instances of BlockStorage
Iterator<BlockStorage> worlds = Slimefun.getRegistry().getWorlds().values().iterator();
while (worlds.hasNext()) {
BlockStorage storage = worlds.next();
if (storage.isMarkedForRemoval()) {
worlds.remove();
}
}
Slimefun.getRegistry().getWorlds().values().removeIf(BlockStorage::isMarkedForRemoval);
// Run our ticker code
if (!halted) {

View File

@ -281,4 +281,38 @@ public final class NumberUtils {
return 0;
}
}
/**
* This detects if 2 integers will overflow/underflow and if they will, returns the corresponding value
* @param a the first integer
* @param b the second integer
* @return {@link Integer#MAX_VALUE} if overflow detected, {@link Integer#MIN_VALUE} if underflow detected, otherwise the sum of a and b
*/
public static int flowSafeAddition(int a, int b) {
return limitedAddition(a, b, Integer.MIN_VALUE, Integer.MAX_VALUE);
}
/**
* This detects if 2 integers will overflow/underflow past a maximum or minimum value and if they will, returns the corresponding value
* @param a the first integer
* @param b the second integer
* @param min the minimum value for the operation
* @param max the maximum value for the operation
* @return max if overflow detected, min if underflow detected, otherwise the sum of a and b
*/
public static int limitedAddition(int a, int b, int min, int max) {
boolean willOverflow = (a == max && b > 0 || b == max && a > 0) || a > 0 && b > max - a;
if (willOverflow) {
return max;
}
boolean willUnderflow = (a == min && b < 0 || b == min && a < 0) || a < 0 && b < min - a;
if (willUnderflow) {
return min;
} else {
return a + b;
}
}
}

View File

@ -519,27 +519,4 @@ public final class SlimefunUtils {
public static @Nullable Item spawnItem(Location loc, ItemStack item, ItemSpawnReason reason) {
return spawnItem(loc, item, reason, false);
}
/**
* Helper method to check if an Inventory is empty (has no items in "storage").
* If the MC version is 1.16 or above
* this will call {@link Inventory#isEmpty()} (Which calls MC code resulting in a faster method).
*
* @param inventory
* The {@link Inventory} to check.
*
* @return True if the inventory is empty and false otherwise
*/
public static boolean isInventoryEmpty(@Nonnull Inventory inventory) {
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
return inventory.isEmpty();
} else {
for (ItemStack is : inventory.getStorageContents()) {
if (is != null && !is.getType().isAir()) {
return false;
}
}
return true;
}
}
}

View File

@ -1,40 +0,0 @@
package io.github.thebusybiscuit.slimefun4.utils;
import javax.annotation.Nonnull;
import org.apache.commons.lang.Validate;
import org.bukkit.World;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
/**
* This class holds utilities for {@link World}. This will become especially useful with the changes
* in the "Cliffs and Caves" update.
*
* @author Walshy
*/
public final class WorldUtils {
private WorldUtils() {}
/**
* Get the minimum Y of the given {@link World}. This is a feature introduced in Minecraft 1.17
* and introduced into the Bukkit API in Minecraft 1.16.
*
* @param world
* The world of which to get minimum Y in.
*
* @return The minimum Y of the given world.
*/
public static int getMinHeight(@Nonnull World world) {
Validate.notNull(world, "World cannot be null!");
if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
return world.getMinHeight();
} else {
// Default to zero for pre-1.16 worlds
return 0;
}
}
}

View File

@ -9,6 +9,7 @@ import org.bukkit.Color;
import org.bukkit.FireworkEffect;
import org.bukkit.FireworkEffect.Type;
import org.bukkit.Material;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.FireworkEffectMeta;
@ -42,6 +43,8 @@ public class ColoredFireworkStar extends CustomItemStack {
im.setLore(lines);
}
im.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS);
});
}

View File

@ -12,6 +12,7 @@ import java.util.stream.Stream;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import io.github.thebusybiscuit.slimefun4.implementation.items.autocrafters.AbstractAutoCrafter;
import org.apache.commons.lang.Validate;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
@ -143,6 +144,12 @@ public enum SlimefunTag implements Tag<Material> {
*/
FUNGUS_SOIL,
/**
* All block types for mangrove to grow on.
* This includes all dirt variants, mud and clay.
*/
MANGROVE_BASE_BLOCKS,
/**
* All variants of concrete powder.
* Can you believe there is no tag for this already?
@ -254,9 +261,24 @@ public enum SlimefunTag implements Tag<Material> {
GRAVITY_AFFECTED_BLOCKS,
/**
* All wool carpets
* All wool carpets.
*/
WOOL_CARPETS;
WOOL_CARPETS,
/**
* All supported storage blocks for the {@link AbstractAutoCrafter}
*/
AUTO_CRAFTER_SUPPORTED_STORAGE_BLOCKS,
/**
* All supported storage blocks for cargo.
*/
CARGO_SUPPORTED_STORAGE_BLOCKS,
/**
* All tile entities.
*/
TILE_ENTITIES;
/**
* Lookup table for tag names.

View File

@ -1,8 +0,0 @@
[
{
"value" : 32,
"biomes" : [
"minecraft:nether"
]
}
]

View File

@ -1,41 +0,0 @@
[
{
"value" : 5,
"biomes" : [
"minecraft:desert",
"minecraft:beach",
"minecraft:stone_shore"
]
},
{
"value" : 8,
"biomes" : [
"minecraft:mountains",
"minecraft:wooded_mountains",
"minecraft:desert_hills",
"minecraft:wooded_hills",
"minecraft:taiga_hills",
"minecraft:mountain_edge",
"minecraft:jungle_hills",
"minecraft:gravelly_mountains",
"minecraft:taiga_mountains",
"minecraft:tall_birch_hills",
"minecraft:dark_forest_hills",
"minecraft:snowy_taiga_mountains",
"minecraft:giant_spruce_taiga_hills",
"minecraft:modified_gravelly_mountains",
"minecraft:bamboo_jungle_hills"
]
},
{
"value" : 12,
"biomes" : [
"minecraft:badlands",
"minecraft:wooded_badlands_plateau",
"minecraft:modified_wooded_badlands_plateau",
"minecraft:modified_badlands_plateau",
"minecraft:eroded_badlands",
"minecraft:badlands_plateau"
]
}
]

View File

@ -1,5 +1,18 @@
---
commands:
help: اين صفحه ي کمک را نشان بده
cheat: به شما اجازه ي تقلب آيتم مي دهد
teleporter: محل تلپورت پلير ديگر را ببينيد
versions: همه ي افزونه های نصب شده را به صورت يک ليست به شما نشان ميدهد
search: دنبال کلمه داده شده در کتاب راهنما می گردد
research:
description: تحقیقات یک پلیر را باز یا ریست میکند
reset-target: '&cدانش شما بازنشانی شده است'
backpack:
description: يک کپي از کوله پشتي موجود را بازیابي کنید
charge:
charge-success: وسیله شما شارژ شد!
not-rechargeable: اين وسیله قابل شارژ نيست!
debug:
description: 'ثبت اشکال زدایی را برای توسعه دهندگان اجرا کنید'
disabled: '&7حالت اشکال زدایی غیرفعال شد.'
@ -8,6 +21,10 @@ placeholderapi:
guide:
locked: 'قفل شده است'
work-in-progress: 'اين قابليت هنوز کامل نشده!'
locked-itemgroup:
- 'براي باز کردن اين گروه شما بايد'
- 'نیاز به باز کردن قفل همه موارد از'
- 'دسته های زیر'
search:
message: '&bدوست دارید دنبال چه چیزی بگردید?'
name: '&7جست و جو...'
@ -16,6 +33,9 @@ guide:
tooltips:
open-itemgroup: 'براي باز کردن کليک کنيد'
versions-notice: 'این موارد هنگام گزارش باگ بسیار مهم هستند!'
wiki: 'این آیتم را در ویکی رسمی Slimefun مشاهده کنید'
recipes:
generator: 'نوع هاي موجود سوخت'
pages:
previous: 'صفحه ي قبل'
next: 'صفحه ی بعد'
@ -23,25 +43,61 @@ guide:
title: 'برگشت'
settings: 'به صفحه تنظیمات بازگرد'
languages:
selected-language: 'در حال حاضر انتخاب شده:'
select: 'برای انتخاب این زبان کلیک کنید'
select-default: 'برای انتخاب زبان پیش فرض کلیک کنید'
change: 'برای انتخاب زبان جدید کلیک کنید'
description:
- '&7اکنون این گزینه را دارید که تغییر دهید'
- '&7زبان در Slimefun'
- '&7به شما ارائه خواهد شد. آیتم ها'
- '&7فعلا قابل ترجمه نیست.'
translations:
name: '&aچیزی فراموش شده است?'
lore: 'برای افزودن ترجمه خود کلیک کنید'
title:
main: 'راهنمای Slimefun'
settings: 'تنظیمات و اطلاعات'
credits: 'مشارکت کنندگان Slimefun4'
wiki: 'ویکی Slimefun4'
addons: 'افزون ها برای Slimefun4'
bugs: 'گزارش اشکال ها'
source: 'کد منبع'
versions: 'نسخه های نصب شده'
credits:
profile-link: 'برای دیدن نمایه آنها در GitHub کلیک کنید'
open: 'برای دیدن مشارکت کنندگان ما کلیک کنید'
roles:
developer: '&6توسعه دهندگان'
wiki: '&3ویرایش کننده ویکی'
resourcepack: '&cهنرمند بسته منابع'
translator: '&9مترجم'
messages:
hungry: '&cشما برای انجام این کار زیادی گرسنه هستید! برای انجام آن نوار گرسنگی خود را پر کنید!'
disabled-in-world: '&4&lاين آيتم در این جهان غير فعال شده است'
auto-crafting:
select: 'این دستور غذا را انتخاب کنید'
soulbound-rune:
fail: '&cشما نمی توانید چند وسیله را به طور همزمان به روح خود متصل کنید.'
success: '&aشما با موفقیت این مورد را به روح خود متصل کردید! در صورت مردن شما این وسیله را از دست نمی دهید.'
tape-measure:
distance: '&7اندازه گیری انجام شده. &eفاصله: %distance%'
no-pvp: '&cشما نمی توانید در اینجا مبارزه کنید!'
link-prompt: '&eاینجا کلیک کنید:'
machines:
HOLOGRAM_PROJECTOR:
inventory-title: 'ویرایشگر هولوگرام'
ELEVATOR:
no-destinations: '&4مقصدی پیدا نشد'
TELEPORTER:
teleporting: '&3درحال جا به جایی...'
teleported: '&3جا به جا شدی!'
gui:
title: 'نقاط راه شما'
tooltip: 'کلیک برای جا به جایی'
time: 'زمان تخمین زده شده'
GPS_CONTROL_PANEL:
waypoints: 'نمای کلی نقطه راه'
CARGO_NODES:
connected: '&2وصل است!'
not-connected: '&4وصل نیست!'
@ -50,6 +106,7 @@ gps:
status-offline: 'آفلاین'
android:
scripts:
editor: 'ویرایش برنامه'
uploaded:
- '&bدرحال آپلود...'
- '&aSuccessfully uploaded your script!'
@ -60,10 +117,18 @@ languages:
fr: 'فرانسوی'
it: 'ایتالیایی'
es: 'اسپانیایی'
pl: 'لهستانی'
nl: 'هلندی'
cs: 'کشور چک'
hu: 'مجارستانی'
ru: 'روسی'
zh-TW: 'چینی (تایوان)'
vi: 'ویتنامی'
id: 'اندونزیایی'
el: 'یونانی'
he: 'عبری'
pt: 'پرتغالی (پرتغال)'
pt-BR: 'پرتغالی (برزیل)'
ar: 'عربی'
da: 'دانمارکی'
fi: 'فنلاندی'
@ -72,3 +137,14 @@ languages:
'no': 'نروژی'
ja: 'ژاپنی'
fa: 'فارسی'
th: 'تایلندی'
tl: 'تاگالوگی'
ro: 'رومانیایی'
bg: 'بلغاری'
ko: 'کره ای'
tr: 'ترکی'
hr: 'کرواتی'
mk: 'مقدونی'
sr: 'صربی'
si-LK: 'سینهالی'
lt: 'لیتوانیایی'

View File

@ -18,7 +18,9 @@ slimefun:
solar_panel_and_helmet: نیروی خورشیدی
cactus_armor: کت و شلوار کاکتوس
slimefun_metals: فلزات جدید
magic_workbench: میز کار جادویی
gold_carats: طلای خالص
lava_crystal: موقعیت آتشین
gilded_iron: آهن براق
synthetic_emerald: جواهر تقلبی
hazmat_suit: لباس ضد آتش
@ -28,6 +30,7 @@ slimefun:
24k_gold_block: شهر طلایی
backpacks: کوله پشتی ها
juicer: نوشیدنی های خوشمزه
more_enhanced_furnaces: کوره های بهتر
carbonado_furnace: کوره لبه دار کربونادو
block_placer: بلوک گذار
scroll_of_dimensional_teleposition: چرخاندن چیزها
@ -44,12 +47,20 @@ slimefun:
oil: نفت
fuel: سوخت
hologram_projector: هولوگرام ها
solar_generators: نیروگاه خورشیدی
electric_furnaces: کوره برقی
electric_ore_grinding: خرد کردن و آسیاب کردن
bio_reactor: راکتور زیستی
elevator: آسانسورها
nuclear_reactor: نیروگاه هسته ای
trash_can: اشغال
elytra: بال
special_elytras: بال مخصوص
trident: نیزه سه شاخه
lava_generator: مولد گدازه
auto_drier: یک روز خشک
diet_cookie: کوکی رژیمی
tree_growth_accelerator: درختان سریعتر
lead_clothing: لباس سرب
tape_measure: نوار اندازه گیری
bee_armor: زره زنبوری

View File

@ -146,6 +146,8 @@ messages:
multimeter: '&bאחסון אנרגיה: &3%stored% &b/ &3%capacity%'
piglin-barter: 'אתה לא יכול לסחור עם חזירונים באמצעות חפצי סליים פאן'
bee-suit-slow-fall: '&eכנפי הדבורה שלך יעזרו לך להגיע לקרקע בצורה איטית ובטוחה'
deprecated-item: '&4פריט זה מיושן ויוסר מסליים פאן בקרוב.'
researching-is-disabled: '&cמחקר לא פעיל בשרת זה. לפי ברירת מחדל הכול פתוח!'
multi-tool:
mode-change: '&b%device% &9: המצב השתנה ל: %mode%'
not-shears: '&c מולטי טול לא יכול לשמש כמזמרה!'
@ -256,6 +258,9 @@ machines:
pick-a-floor: '&3- בחר קומה -'
current-floor: '&e אתה נמצא כרגע על קומה:'
click-to-teleport: '&eלחץ &7 כדי להשתגר לקומה:'
enter-name: '&7אנא הכנס את שם הרצפה הרצוי לצ''אט שלך. &f(קודי צבע נתמכים!)'
named: '&2 בהצלחה נקבע שם קומה זאת: &f%floor%'
editor-title: 'הגדר מעלית זו'
TELEPORTER:
teleporting: '&3משתגר....'
teleported: '&3שוגר!'
@ -271,6 +276,8 @@ machines:
waypoints: 'סקירת נקודות דרך'
CARGO_NODES:
must-be-placed: '&4חייב להיות מונח על תיבה או מכונה!'
connected: '&2מחובר!'
not-connected: '&4לא מחובר!'
INDUSTRIAL_MINER:
no-fuel: 'לכורה התעשייתית שלך אזל הדלק! שים את הדלק שלך בתיבה מעל.'
piston-facing: '&cהכורה התעשייתי שלך דורש בוכנות מופנות כלפי מעלה!'
@ -300,6 +307,8 @@ cauldron:
no-discoloring: '&4אתה לא יכול לשנות את הצבע של שריון סליים פאן'
gps:
deathpoint: "&4נקודת מוות\n&7%date%"
status-online: 'מקוון'
status-offline: 'לא מקוון'
waypoint:
new: '&eהקלד שם לנקודת הדרך החדשה שלך בצ''אט. (קודי צבע נתמכים!)'
added: '&a נוסף בהצלחה נקודת דרך חדשה'
@ -399,3 +408,5 @@ languages:
mk: 'מקדונית'
sr: 'סרבית'
be: 'בלארוסית'
si-LK: 'סינהאלית'
lt: 'ליטאית'

View File

@ -25,6 +25,7 @@ placeholderapi:
profile-loading: 'Memuat...'
guide:
locked: 'TERKUNCI'
work-in-progress: 'Fitur ini belum sepenuhnya selesai!'
locked-itemgroup:
- 'Untuk membuka kategori ini anda'
- 'harus membuka semua barang dari'
@ -57,6 +58,7 @@ guide:
selected-language: 'Yang sedang dipilih:'
select: 'Klik untuk memilih bahasa ini'
select-default: 'Klik untuk menggunakan bahasa standar server'
change: 'Klik untuk memilih sebuah bahasa baru'
translations:
name: '&aAda yang kurang?'
lore: 'Klik untuk menambahkan terjemahan anda'
@ -84,6 +86,7 @@ guide:
addons: 'Addons untuk Slimefun4'
bugs: 'Laporkan masalah'
source: 'Kode sumber'
versions: 'Versi Terinstal'
credits:
commit: 'Melakukan'
profile-link: 'Klik untuk mengunjungi profil mereka di GitHub'
@ -196,6 +199,8 @@ machines:
waypoints: 'Gambaran titik jalan'
CARGO_NODES:
must-be-placed: '&4Harus diletakan di dalam peti atau mesin!'
connected: '&2Terhubung!'
not-connected: '&4Tidak Terhubung!'
INDUSTRIAL_MINER:
no-fuel: '&c Penambang Industri Anda kehabisan bahan bakar! Masuklah bahan bakar Anda ke peti di atas.'
piston-facing: '& c Penambang Industri Anda membutuhkan piston untuk menghadap ke atas!'
@ -311,4 +316,8 @@ languages:
ko: 'Korea'
tr: 'Turki'
hr: 'Croation'
mk: 'Makedonia'
sr: 'Serbian'
be: 'Belarusian'
si-LK: 'Sinhala'
lt: 'Lithuanian'

View File

@ -147,6 +147,7 @@ messages:
piglin-barter: '&4Slimefunアイテムはピグリンとの物々交換に使用できません'
bee-suit-slow-fall: '&e蜂の羽が着地を安全でゆっくりにした'
deprecated-item: '&4このアイテムは廃止予定です。近日中にSlimefunから削除されます。'
researching-is-disabled: '%cこのサーバーではリサーチが無効化されていました。すべてがデフォルトでアンロックされました'
multi-tool:
mode-change: '&b%device% モード変更: &9%mode%'
not-shears: '&cMulti Toolはハサミとして利用できません'
@ -257,6 +258,7 @@ machines:
pick-a-floor: '&3- 行先の選択 -'
current-floor: '&e現在の階:'
click-to-teleport: '&eクリック&7でこの階に移動:'
editor-title: 'エレベーターの設定'
TELEPORTER:
teleporting: '&3テレポート中…'
teleported: '&3テレポート完了'
@ -272,6 +274,7 @@ machines:
waypoints: 'ウェイポイント一覧'
CARGO_NODES:
must-be-placed: '&4チェストや機械に対して設置してください'
not-connected: '&4接続されていません!'
INDUSTRIAL_MINER:
no-fuel: '&cIndustrial Minerは燃料切れです上のチェストに燃料を補充してください。'
piston-facing: '&cIndustrial Minerのピストンは上向きに設置してください'
@ -301,6 +304,8 @@ cauldron:
no-discoloring: '&4Slimefunアイテムの脱色はできません'
gps:
deathpoint: '&4死亡地点 &7%date%'
status-online: 'オンライン'
status-offline: 'オフライン'
waypoint:
new: '&eウェイポイント名をチャットで入力してください&7カラーコード対応'
added: '&a新しいウェイポイントを登録しました'

View File

@ -153,10 +153,10 @@ slimefun:
electric_ore_grinding: 粉砕粉砕
heated_pressure_chamber: 加熱圧力室Ⅰ
coal_generator: 火力発電所
bio_reactor: バイオマス発電所
bio_reactor: バイオリアクター
auto_enchanting: エンチャント操作術
auto_anvil: 電動修理術
multimeter: マルチメーター
auto_anvil: 自動金床
multimeter: 電力計測
gps_setup: GPS時代の夜明け
gps_emergency_transmitter: 緊急戦線復帰
programmable_androids: アンドロイド
@ -250,7 +250,7 @@ slimefun:
iron_golem_assembler: 人造アイアンゴーレム
villager_rune: 村人の初期化
elytra_cap: 衝撃緩和装備
bee_armor: 蜂アーマー
bee_armor: 養蜂用防護服
book_binder: エンチャントの本の製本
auto_crafting: 自動クラフト
produce_collector: 自動搾乳

View File

@ -2,15 +2,56 @@
commands:
help: Mostra este ecrã de ajuda
cheat: Deixa-te fazer batota
give: Dá itens de Slimefun a alguém
guide: Dá-te um guia de Slimefun
teleporter: Vê os Waypoints de outros
versions: Lista os Addons Instalados
open_guide: Abre o guia de slimefun sem utilizar o livro
stats: Mostra estatísticas de um jogador
research:
description: Desbloqueia/Apaga pesquisas de um jogador
reset: '&cTu apagaste a sabedoria do %player%'
reset-target: '&cA tua sabedoria foi apagada'
backpack:
description: Recuperar uma cópia de uma mochila existente
invalid-id: '&4O id deve ser um número não-negativo!'
player-never-joined: '&4Nenhum jogador com este nome foi encontrado!'
backpack-does-not-exist: 'A mochila especificada não existe!'
restored-backpack-given: '&aA sua mochila foi restaurada e adicionada ao seu inventário!'
charge:
description: Carrega o item que estás a segurar
charge-success: O item foi carregado!
not-rechargeable: Este item não pode ser carregado!
timings:
description: Timings de Slimefun e addons
please-wait: '&ePor favor, espere um segundo... Os resultados estão a chegar!'
verbose-player: '&4A flag verbose não pode ser utilizada por um jogador!'
unknown-flag: '&4Flag desconhecida: &c%flag%'
debug:
disabled: '&7Modo de debug desabilitado.'
placeholderapi:
profile-loading: 'A carregar...'
guide:
locked: 'BLOQUEADO'
work-in-progress: 'Isto ainda não está totalmente concluído!'
locked-itemgroup:
- 'Para desbloquear esta categoria tu vais ter de'
- 'precisas de desbloquear todos os itens das'
- 'categorias seguintes'
search:
message: '&bO que gostarias de procurar?'
name: '&7Pesquisar...'
tooltip: '&bClica para procurar um item'
inventory: 'À procura de: %item%'
tooltips:
open-itemgroup: 'Clique para abrir'
versions-notice: 'Estes são muito importantes para dar report a bugs!'
wiki: 'Veja este item na Wiki oficial do Slimefun'
recipes:
machine: 'Itens feitos nesta máquina'
miner: 'Recursos que podes obter com este Miner'
generator: 'Tipos de combustível disponíveis'
gold-pan: 'Recursos que podes obter'
pages:
previous: 'Página anterior'
next: 'Página seguinte'
@ -24,6 +65,11 @@ guide:
select: 'Clique para selecionar esta linguagem'
select-default: 'Clique para selecionar a linguagem padrão'
change: 'Cliqua para selecionar uma linguagem nova'
description:
- '&7Agora tens a opção de alterar'
- '&7o idioma em que Slimefun'
- '&7lhe irá ser apresentado. Itens'
- '&7não podem ser traduzido por agora.'
translations:
name: '&aFalta alguma coisa?'
lore: 'Cliqua para adicionar a tua própria tradução'
@ -64,6 +110,9 @@ guide:
resourcepack: '&cArtista de Resourcepack'
translator: '&9Tradutor'
messages:
only-players: '&4Este comando é apenas para Jogadores'
unknown-player: '&4Jogador Desconhecido: &c%player%'
no-permission: '&4Não tens as permissões necessárias para fazer isto'
usage: '&4Utilização: &c%usage%'
not-online: '&4%player% &cnão está online!'
invalid-item: '&4%item% &cnão é um item válido!'
@ -71,20 +120,49 @@ messages:
hungry: '&cEstás com demasiada fome para fazer isso!'
disabled-in-world: '&4&lEsse item foi desativado neste mundo'
disabled-item: '&4&lEsse item foi desativado! Como é que o conseguiste?'
piglin-barter: '&4Não podes trocar com piglins utilizando itens de Slimefun'
auto-crafting:
tooltips:
disabled:
- '&cEsta receita está desativada no momento'
- ''
- '&eLeft Click &7to re-enable this recipe'
- '&eRight Click &7to remove this recipe'
no-pvp: '&cNão podes fazer pvp aqui!'
opening-guide: '&bA abrir o guia, isto pode demorar alguns segundos...'
opening-backpack: '&bA abrir a mochila, isto pode demorar alguns segundos...'
link-prompt: '&eClique aqui:'
machines:
full-inventory: '&eDesculpa, o meu inventário está cheio!'
HOLOGRAM_PROJECTOR:
inventory-title: 'Editor de Holograma'
ELEVATOR:
no-destinations: '&4Não foram encontrados destinos'
pick-a-floor: '&3- Escolha um piso -'
TELEPORTER:
teleporting: '&3A teletransportar...'
teleported: '&3Teletransportado!'
cancelled: '&4Teletransporte cancelado!'
gui:
title: 'Os teus waypoints'
tooltip: 'Clica para te teletransportares'
time: 'Tempo estimado'
GPS_CONTROL_PANEL:
transmitters: 'Transmissores'
waypoints: 'Waypoints'
anvil:
not-working: '&4Não podes usar itens de Slimefun em uma bigorna!'
mcmmo-salvaging: '&4Não podes destruir itens do Slimefun!'
brewing_stand:
not-working: '&4Não podes usar itens do Slimefun em um suporte de poções!'
cartography_table:
not-working: '&4Não podes usar itens do Slimefun em uma mesa de cartografia!'
smithing_table:
not-working: '&4Você não pode usar um item do Slimefun como um material de ferreiro!'
villagers:
no-trading: '&4Não podes trocar itens de Slimefun com Villagers!'
backpack:
already-open: '&cEsta mochila está aberta em outro lugar!'
inventory:
no-access: '&4Não tens permissão para aceder este bloco'
android:
@ -134,6 +212,7 @@ languages:
fr: 'Francês'
it: 'Italiano'
es: 'Espanhol'
pl: 'Polaco'
sv: 'Sueco'
nl: 'Holandês'
cs: 'Checo'

View File

@ -1 +1,21 @@
---
slimefun:
fortune_cookie: Bolinho da sorte
portable_dustbin: Caixote do Lixo Portátil
meat_jerky: Jerky de Carne
magic_sugar: Açúcar Mágico
monster_jerky: Jerky de Monstro
slime_armor: Armadura de Slime
sword_of_beheading: Espada da Decapitação
parachute: Pára-quedas
grappling_hook: Gancho-arpão
jetpacks: Jetpack
slimefun_metals: Metais Novos
carbonado: Diamantes Negros
synthetic_emerald: Jóia Falsa
chainmail_armor: Armadura de Malha
uranium: Radioativo
crushed_ore: Purificação de Minérios
first_aid: Primeiros socorros
gold_armor: Armadura Brilhante
backpacks: Mochilas

View File

@ -1 +1,23 @@
---
slimefun:
weapons: 'Arme'
food: 'Mâncare'
basic_machines: 'Maşinarii de bază'
electricity: 'Energie şi electricitate'
androids: 'Androizi programabili'
gps: 'Mașinarii GPS'
armor: 'Armură'
magical_items: 'Obiecte Magice'
magical_gadgets: 'Gadget-uri Magice'
misc: 'Obiecte Diverse'
technical_gadgets: 'Gadget-uri Tehnice'
resources: 'Resurse'
tech_misc: 'Componente Tehnice'
magical_armor: 'Armură Magică'
talismans: 'Talismane (nivelul I)'
ender_talismans: 'Talismane Ender (nivelul II)'
christmas: 'Crăciun (decembrie)'
valentines_day: 'Ziua Îndrăgostiților (14 februarie)'
easter: 'Paște (Aprilie)'
birthday: 'Ziua de naștere a lui TheBusyBiscuit (26 octombrie)'
halloween: 'Halloween (31 octombrie)'

View File

@ -1,4 +1,7 @@
---
commands:
timings:
please-wait: '&eTe rugam sa astepti o secunda... Rezultatele se incarca!'
placeholderapi:
profile-loading: 'Se încarcă...'
guide:
@ -8,38 +11,90 @@ guide:
name: '&7Cauta...'
tooltip: '&bClick pentru a căuta un obiect'
inventory: 'Caută pentru: %item%'
tooltips:
versions-notice: 'Acestea sunt foarte importante atunci când raportezi problemele!'
wiki: 'Vezi acest articol pe Wiki-ul Slimefun Oficial'
pages:
previous: 'Pagina anterioară'
next: 'Pagina următoare'
back:
guide: 'Inapoi la Ghidul Slimefun'
languages:
selected-language: 'Selectare actuală:'
select: 'Click pentru a selecta această limbă'
select-default: 'Click pentru a selecta limba implicita'
change: 'Click pentru a selecta o nouă limbă'
translations:
name: '&aLipseste ceva?'
lore: 'Click pentru a adăuga propria ta traducere'
title:
main: 'Ghid Slimefun'
settings: 'Setări și informații'
languages: 'Selectați limba preferată'
credits: 'Contribuitori Slimefun4'
wiki: 'Wiki Slimefun4'
addons: 'Addons pentru Slimefun4'
bugs: 'Raportare Buguri'
source: 'Cod sursă'
versions: 'Versiuni instalate'
credits:
commit: 'Commit'
commits: 'Commit-uri'
profile-link: 'Faceți clic pentru a le vizita profilul pe GitHub'
open: 'Click pentru a vedea contribuitorii noștri'
roles:
developer: '&6Dezvoltator'
wiki: '&3Editor Wiki'
resourcepack: '&cArtist Resurse'
translator: '&9Traducator'
messages:
not-researched: '&4Nu ai suficiente cunostinte pentru a intelege acest obiect. &cVa trebui sa deblochezi &f"%item%&f"'
not-enough-xp: '&4Nu ai suficient XP pentru a debloca acest obiect'
unlocked: '&bAi deblocat &7"%research%"'
only-players: '&4Aceasta comanda este doar pentru jucatori'
link-prompt: '&eClick aici:'
machines:
TELEPORTER:
teleporting: '&3Teleportare...'
teleported: '&3Teleportat!'
cancelled: '&4Teleportare anulata!'
invulnerability: '&b&lAi primit 30 de secunde de Invulnerabilitate!'
gui:
title: 'Punctele tale de referinta'
tooltip: 'Click pentru teleportare'
time: 'Timp estimat'
languages:
en: 'Engleză'
de: 'Germană'
fr: 'Franceză'
it: 'Italiană'
es: 'Spaniolă'
pl: 'Poloneză'
sv: 'Suedeză'
nl: 'Olandeză'
cs: 'Cehă'
hu: 'Maghiară'
lv: 'Letonă'
ru: 'Rusă'
sk: 'Slovacă'
zh-CN: 'Chineză (China)'
zh-TW: 'Chineză (Taiwan)'
vi: 'Vietnameză'
id: 'Indoneziană'
el: 'Greacă'
he: 'Ebraică'
pt: 'Portugheză (Portugalia)'
ar: 'Arabă'
fi: 'Finlandeză'
uk: 'Ucraineană'
ja: 'Japoneză'
fa: 'Persiană'
th: 'Tailandeza'
tl: 'Tagalog'
ro: 'Română'
bg: 'Bulgară'
ko: 'Coreeană'
hr: 'Croată'
mk: 'Macedoneană'
sr: 'Sârbă'
be: 'Belarusă'

View File

@ -1 +1,7 @@
---
slimefun:
walking_sticks: Baston
portable_crafter: Masă de fabricare portabilă
portable_dustbin: Dustbin portabil
meat_jerky: Bucati de carne uscata
armor_forge: Masa de fabricare Armuri

View File

@ -1,7 +1,7 @@
---
slimefun:
walking_sticks: Vychádzkové paličky
portable_crafter: Prenosný crafter
portable_crafter: Prenosný pracovný stôl
fortune_cookie: Koláčik šťastia
portable_dustbin: Prenosný kôš
meat_jerky: Sušené mäso
@ -13,14 +13,14 @@ slimefun:
magic_eye_of_ender: Magiké Oko Endu
magic_sugar: Magický cukor
monster_jerky: Sušené mäso z monštier
slime_armor: Slime brnenie
slime_armor: Slizové brnenie
sword_of_beheading: Meč popráv
basic_circuit_board: Základná obvodová doska
advanced_circuit_board: Pokročilá obvodová doska
smeltery: Taviareň
steel: Vek ocele
misc_power_items: Dôležité veci súvisiace s energiou
battery: Tvoja prvá baterka
battery: Tvoja prvá batéria
steel_plate: Oceľové pokovovanie
steel_thruster: Oceľová tryska
parachute: Padák

View File

@ -174,5 +174,11 @@
"Day-OS",
"ooicram",
"Sxigames"
],
"fa" : [
"mohammadamin22",
"AmirYaKuZa",
"amooking",
"taha2hosseini1"
]
}

View File

@ -93,7 +93,7 @@ guide:
click: '&e单击禁用解锁研究动画'
disabled:
text:
- '&b解锁动画: &a禁用'
- '&b解锁动画: &4禁用'
- ''
- '&7现在你可以选择是否'
- '&7跳过解锁物品研究'

View File

@ -22,10 +22,10 @@ slimefun:
- '如合成表所示'
- '使用磨石制作'
smeltery:
name: '冶炼 (Smeltery)'
name: '冶炼 (Smeltery)'
lore:
- '如合成表所示'
- '用冶炼合成'
- '用冶炼合成'
ore_crusher:
name: '矿石粉碎机 (Ore Crusher)'
lore:

View File

@ -9,7 +9,7 @@ description: Slimefun basically turns your entire Server into a FTB modpack with
# Technical settings
main: io.github.thebusybiscuit.slimefun4.implementation.Slimefun
api-version: '1.14'
api-version: '1.16'
# (Soft) dependencies of Slimefun, we hook into these plugins.
softdepend:

View File

@ -0,0 +1,8 @@
{
"values" : [
"#slimefun:shulker_boxes",
"minecraft:chest",
"minecraft:trapped_chest",
"minecraft:barrel"
]
}

View File

@ -0,0 +1,15 @@
{
"values" : [
"#slimefun:shulker_boxes",
"minecraft:chest",
"minecraft:trapped_chest",
"minecraft:barrel",
"minecraft:furnace",
"minecraft:dispenser",
"minecraft:dropper",
"minecraft:hopper",
"minecraft:brewing_stand",
"minecraft:blast_furnace",
"minecraft:smoker"
]
}

View File

@ -11,6 +11,26 @@
{
"id" : "minecraft:basalt",
"required" : false
},
{
"id" : "minecraft:calcite",
"required" : false
},
{
"id" : "minecraft:deepslate",
"required" : false
},
{
"id" : "minecraft:dripstone_block",
"required" : false
},
{
"id" : "minecraft:smooth_basalt",
"required" : false
},
{
"id" : "minecraft:tuff",
"required" : false
}
]
}

View File

@ -2,6 +2,11 @@
"values" : [
"#slimefun:concrete_powders",
"#minecraft:sand",
"minecraft:gravel"
"minecraft:gravel",
"minecraft:clay",
{
"id" : "minecraft:skulk",
"required" : false
}
]
}

View File

@ -0,0 +1,10 @@
{
"values" : [
"#slimefun:dirt_variants",
"minecraft:clay",
{
"id" : "minecraft:mud",
"required" : false
}
]
}

View File

@ -0,0 +1,42 @@
{
"values" : [
"#slimefun:shulker_boxes",
"#minecraft:signs",
"#minecraft:banners",
"#minecraft:beds",
"minecraft:chest",
"minecraft:trapped_chest",
"minecraft:barrel",
"minecraft:furnace",
"minecraft:dispenser",
"minecraft:dropper",
"minecraft:hopper",
"minecraft:brewing_stand",
"minecraft:blast_furnace",
"minecraft:smoker",
"minecraft:beacon",
"minecraft:spawner",
"minecraft:note_block",
"minecraft:jukebox",
"minecraft:enchanting_table",
"minecraft:end_portal",
"minecraft:ender_chest",
"minecraft:command_block",
"minecraft:structure_block",
"minecraft:end_gateway",
"minecraft:comparator",
"minecraft:conduit",
"minecraft:bell",
"minecraft:daylight_detector",
"minecraft:player_head",
"minecraft:player_wall_head",
{
"id" : "minecraft:soul_campfire",
"required" : false
},
{
"id" : "minecraft:lectern",
"required" : false
}
]
}

View File

@ -215,6 +215,7 @@
"GILDED_IRON_CHESTPLATE" : "Armor",
"GILDED_IRON_HELMET" : "Armor",
"GILDED_IRON_LEGGINGS" : "Armor",
"GLOW_BERRY_JUICE" : "Juices",
"GLOWSTONE_BOOTS" : "Magical-Armor",
"GLOWSTONE_CHESTPLATE" : "Magical-Armor",
"GLOWSTONE_HELMET" : "Magical-Armor",

View File

@ -11,57 +11,57 @@ class TestMinecraftVersion {
@Test
@DisplayName("Test if Minecraft versions match themselves")
void testMatches() {
Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_14.isMinecraftVersion(14));
Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_15.isMinecraftVersion(15));
Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_16.isMinecraftVersion(16));
Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_17.isMinecraftVersion(17));
Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_15.isMinecraftVersion(14));
Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_14.isMinecraftVersion(0));
Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_17.isMinecraftVersion(16));
Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_16.isMinecraftVersion(0));
}
@Test
@DisplayName("Test if Minecraft versions are ordered correctly (#atLeast)")
void testAtLeast() {
Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_16.isAtLeast(MinecraftVersion.MINECRAFT_1_14));
Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_15.isAtLeast(MinecraftVersion.MINECRAFT_1_14));
Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_15.isAtLeast(MinecraftVersion.MINECRAFT_1_15));
Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_18.isAtLeast(MinecraftVersion.MINECRAFT_1_16));
Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_17.isAtLeast(MinecraftVersion.MINECRAFT_1_16));
Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_17.isAtLeast(MinecraftVersion.MINECRAFT_1_17));
Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_15.isAtLeast(MinecraftVersion.MINECRAFT_1_16));
Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_17.isAtLeast(MinecraftVersion.MINECRAFT_1_18));
}
@Test
@DisplayName("Test correct behaviour for MinecraftVersion.UNKNOWN.isAtleast(...)")
void testAtLeastUnknown() {
// Unknown should always fall back to false
Assertions.assertFalse(MinecraftVersion.UNKNOWN.isAtLeast(MinecraftVersion.MINECRAFT_1_14));
Assertions.assertFalse(MinecraftVersion.UNKNOWN.isAtLeast(MinecraftVersion.MINECRAFT_1_15));
Assertions.assertFalse(MinecraftVersion.UNKNOWN.isAtLeast(MinecraftVersion.MINECRAFT_1_16));
Assertions.assertFalse(MinecraftVersion.UNKNOWN.isAtLeast(MinecraftVersion.MINECRAFT_1_17));
Assertions.assertThrows(IllegalArgumentException.class, () -> MinecraftVersion.MINECRAFT_1_14.isAtLeast(null));
Assertions.assertThrows(IllegalArgumentException.class, () -> MinecraftVersion.MINECRAFT_1_16.isAtLeast(null));
}
@Test
@DisplayName("Test if Minecraft versions are ordered correctly (#isBefore)")
void testIsBefore() {
Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_14.isBefore(MinecraftVersion.MINECRAFT_1_15));
Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_14.isBefore(MinecraftVersion.MINECRAFT_1_16));
Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_16.isBefore(MinecraftVersion.MINECRAFT_1_17));
Assertions.assertTrue(MinecraftVersion.MINECRAFT_1_16.isBefore(MinecraftVersion.MINECRAFT_1_18));
Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_15.isBefore(MinecraftVersion.MINECRAFT_1_15));
Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_15.isBefore(MinecraftVersion.MINECRAFT_1_14));
Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_17.isBefore(MinecraftVersion.MINECRAFT_1_17));
Assertions.assertFalse(MinecraftVersion.MINECRAFT_1_17.isBefore(MinecraftVersion.MINECRAFT_1_16));
}
@Test
@DisplayName("Test correct behaviour for MinecraftVersion.UNKNOWN.isBefore(...)")
void testIsBeforeUnknown() {
// Unknown should always fall back to true
Assertions.assertTrue(MinecraftVersion.UNKNOWN.isBefore(MinecraftVersion.MINECRAFT_1_14));
Assertions.assertTrue(MinecraftVersion.UNKNOWN.isBefore(MinecraftVersion.MINECRAFT_1_15));
Assertions.assertTrue(MinecraftVersion.UNKNOWN.isBefore(MinecraftVersion.MINECRAFT_1_16));
Assertions.assertTrue(MinecraftVersion.UNKNOWN.isBefore(MinecraftVersion.MINECRAFT_1_17));
Assertions.assertThrows(IllegalArgumentException.class, () -> MinecraftVersion.MINECRAFT_1_14.isBefore(null));
Assertions.assertThrows(IllegalArgumentException.class, () -> MinecraftVersion.MINECRAFT_1_16.isBefore(null));
}
@Test
@DisplayName("Test warning system for lowest supported version checks")
void testLowestSupportedVersion() {
Assertions.assertThrows(IllegalArgumentException.class, () -> MinecraftVersion.UNIT_TEST.isAtLeast(MinecraftVersion.MINECRAFT_1_14));
Assertions.assertThrows(IllegalArgumentException.class, () -> MinecraftVersion.UNIT_TEST.isAtLeast(MinecraftVersion.MINECRAFT_1_16));
}
}

View File

@ -91,4 +91,29 @@ class TestNumberUtils {
Assertions.assertEquals("-2Q", NumberUtils.getCompactDouble(-2000000000000000.0));
}
@Test
@DisplayName("Test flow safe addition")
void testFlowSafeAddition() {
Assertions.assertEquals(Integer.MAX_VALUE, NumberUtils.flowSafeAddition(Integer.MAX_VALUE, 1));
Assertions.assertEquals(Integer.MAX_VALUE, NumberUtils.flowSafeAddition(1, Integer.MAX_VALUE));
Assertions.assertEquals(Integer.MAX_VALUE, NumberUtils.flowSafeAddition(Integer.MAX_VALUE - 1, 2));
Assertions.assertEquals(Integer.MAX_VALUE, NumberUtils.flowSafeAddition(2, Integer.MAX_VALUE - 1));
Assertions.assertEquals(Integer.MIN_VALUE, NumberUtils.flowSafeAddition(Integer.MIN_VALUE, -1));
Assertions.assertEquals(Integer.MIN_VALUE, NumberUtils.flowSafeAddition(-1, Integer.MIN_VALUE));
Assertions.assertEquals(Integer.MIN_VALUE, NumberUtils.flowSafeAddition(Integer.MIN_VALUE + 1, -2));
Assertions.assertEquals(Integer.MIN_VALUE, NumberUtils.flowSafeAddition(-2, Integer.MIN_VALUE + 1));
}
@Test
@DisplayName("Test limited addition")
void testLimitedAddition() {
Assertions.assertEquals(1000, NumberUtils.limitedAddition(1000, 1, -1000, 1000));
Assertions.assertEquals(1000, NumberUtils.limitedAddition(1, 1000, -1000, 1000));
Assertions.assertEquals(1000, NumberUtils.limitedAddition(999, 2, -1000, 1000));
Assertions.assertEquals(1000, NumberUtils.limitedAddition(2, 999, -1000, 1000));
Assertions.assertEquals(-1000, NumberUtils.limitedAddition(-1000, -1, -1000, 1000));
Assertions.assertEquals(-1000, NumberUtils.limitedAddition(-1, -1000, -1000, 1000));
Assertions.assertEquals(-1000, NumberUtils.limitedAddition(-999, -2, -1000, 1000));
Assertions.assertEquals(-1000, NumberUtils.limitedAddition(-2, -999, -1000, 1000));
}
}

View File

@ -98,11 +98,6 @@ class TestBiomeMapCompatibility {
Map<String, MinecraftVersion[]> testCases = new HashMap<>();
// @formatter:off
testCases.put("nether_ice_v1.14", new MinecraftVersion[] {
MinecraftVersion.MINECRAFT_1_14,
MinecraftVersion.MINECRAFT_1_15
});
testCases.put("nether_ice_v1.16", new MinecraftVersion[] {
MinecraftVersion.MINECRAFT_1_16,
MinecraftVersion.MINECRAFT_1_17,
@ -110,9 +105,7 @@ class TestBiomeMapCompatibility {
MinecraftVersion.MINECRAFT_1_19
});
testCases.put("oil_v1.14", new MinecraftVersion[] {
MinecraftVersion.MINECRAFT_1_14,
MinecraftVersion.MINECRAFT_1_15,
testCases.put("oil_v1.16", new MinecraftVersion[] {
MinecraftVersion.MINECRAFT_1_16,
MinecraftVersion.MINECRAFT_1_17
});
@ -122,9 +115,7 @@ class TestBiomeMapCompatibility {
MinecraftVersion.MINECRAFT_1_19
});
testCases.put("salt_v1.14", new MinecraftVersion[] {
MinecraftVersion.MINECRAFT_1_14,
MinecraftVersion.MINECRAFT_1_15,
testCases.put("salt_v1.16", new MinecraftVersion[] {
MinecraftVersion.MINECRAFT_1_16,
MinecraftVersion.MINECRAFT_1_17
});
@ -134,11 +125,6 @@ class TestBiomeMapCompatibility {
MinecraftVersion.MINECRAFT_1_19
});
testCases.put("uranium_v1.14", new MinecraftVersion[] {
MinecraftVersion.MINECRAFT_1_14,
MinecraftVersion.MINECRAFT_1_15
});
testCases.put("uranium_v1.16", new MinecraftVersion[] {
MinecraftVersion.MINECRAFT_1_16
});