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

Conflicts:
	src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNetworkTask.java
	src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/altar/AncientPedestal.java
	src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/miner/IndustrialMiner.java
	src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/miner/MiningTask.java
	src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/seasonal/ChristmasPresent.java
	src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/seasonal/EasterEgg.java
	src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/GoldPan.java
	src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/PickaxeOfContainment.java
	src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/AutoCrafterListener.java
	src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java
This commit is contained in:
TheBusyBiscuit 2021-07-14 14:51:18 +02:00
commit e40222f2fc
33 changed files with 472 additions and 54 deletions

View File

@ -19,6 +19,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v2.3.4
- name: Set up Java JDK 11
uses: actions/setup-java@v2.1.0
with:
@ -26,8 +27,16 @@ jobs:
java-version: '11'
java-package: jdk
architecture: x64
- name: Cache Maven packages
uses: actions/cache@v2
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2
- name: Run Discord Webhook
uses: Slimefun/discord-webhook@master
uses: baked-libs/discord-webhook@1.5.1
with:
id: ${{ secrets.DISCORD_WEBHOOK_ID }}
token: ${{ secrets.DISCORD_WEBHOOK_TOKEN }}

View File

@ -8,8 +8,6 @@ on:
- 'src/**'
- 'pom.xml'
pull_request:
branches:
- master
paths:
- 'src/**'
- 'pom.xml'
@ -23,10 +21,19 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v2.1.0
with:
distribution: 'adopt'
java-version: '8'
- name: Cache Maven packages
uses: actions/cache@v2
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2
- name: Build with Maven
run: mvn package --file pom.xml

View File

@ -13,7 +13,7 @@ jobs:
if: github.repository == 'Slimefun/Slimefun4'
steps:
- uses: WalshyDev/pr-labels@v1.1
- uses: baked-libs/pull-request-labels@v1.1
id: labeller
name: Apply labels based on branch
with:

45
.github/workflows/sonarcloud.yml vendored Normal file
View File

@ -0,0 +1,45 @@
name: SonarCloud Scanner
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
scan:
name: SonarCloud Scanner
runs-on: ubuntu-latest
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
steps:
- name: Checkout repository
uses: actions/checkout@v2.3.4
with:
fetch-depth: 0
- name: Set up JDK 11
uses: actions/setup-java@v2.1.0
with:
distribution: 'adopt'
java-version: '11'
- name: Cache SonarCloud packages
uses: actions/cache@v2
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
- name: Cache Maven packages
uses: actions/cache@v2
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2
- name: SonarCloud analysis
run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar
if: ${{ env.SONAR_TOKEN != 0 }}

View File

@ -31,11 +31,18 @@
#### Additions
* Diamonds can now be ground into Carbon using a Grind Stone
* Deepslate ores can now be doubled using an Ore Crusher
* Tridents can now be crafted
* The Industrial Miner can now mine up to the minimum world limit (previously only until y=0)
* (API) Added SlimefunItemSpawnEvent and ItemSpawnReason
* Added "Amethyst Block -> 4 Amethyst Shards" recipe to the Grind Stone
* Added an option to the IndustrialMiner to configure if they can mine deepslate ores
#### Changes
* The Industrial Miner now properly drops raw ores in 1.17+ instead of ore blocks
#### Fixes
* Fixed #2966
* Fixed Auto-Crafters bypassing the `doLimitedCrafting` gamerule
## Release Candidate 25 (20 Jun 2021)
https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#25

View File

@ -30,7 +30,7 @@ Here is a full summary of the differences between the two different versions of
| | development (latest) | "stable" |
| ------------------ | -------- | -------- |
| **Minecraft version(s)** | :video_game: **1.14.\* - 1.16.\*** | :video_game: **1.14.\* - 1.16.\*** |
| **Minecraft version(s)** | :video_game: **1.14.\* - 1.17.\*** | :video_game: **1.14.\* - 1.17.\*** |
| **automatic updates** | :heavy_check_mark: | :heavy_check_mark: |
| **frequent updates** | :heavy_check_mark: | :x: |
| **latest content** | :heavy_check_mark: | :x: |
@ -65,7 +65,7 @@ Well, we asked some users on our [Discord server](#discord) to send us some scre
| *Screenshot provided by GalaxyKat11#3816* | *Screenshot provided by TamThan#7987* | *Screenshot provided by Kilaruna#4981* |
## :headphones: Discord
You can find Slimefun's community on Discord and connect with **over 5000** users of this plugin from all over the world.<br>
You can find Slimefun's community on Discord and connect with **over 6000** users of this plugin from all over the world.<br>
Click the badge down below to join the server for suggestions/questions or other discussions about this plugin.<br>
We are also hosting a community event every so often, join us to find out more.<br>
**Important: We don't accept bug reports on discord, please use our [Issue Tracker](https://github.com/Slimefun/Slimefun4/issues) to submit bug reports!**

View File

@ -355,7 +355,7 @@
<dependency>
<groupId>com.github.seeseemelk</groupId>
<artifactId>MockBukkit-v1.16</artifactId>
<version>1.3.2</version>
<version>1.5.0</version>
<scope>test</scope>
<exclusions>
@ -372,7 +372,7 @@
<dependency>
<groupId>com.github.thebusybiscuit</groupId>
<artifactId>CS-CoreLib2</artifactId>
<version>0.32.0</version>
<version>0.32.1</version>
<scope>compile</scope>
</dependency>
<dependency>
@ -428,7 +428,7 @@
<dependency>
<groupId>com.gmail.nossr50.mcMMO</groupId>
<artifactId>mcMMO</artifactId>
<version>2.1.199</version>
<version>2.1.200</version>
<scope>provided</scope>
<exclusions>
@ -442,7 +442,7 @@
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>2.10.9</version>
<version>2.10.10</version>
<scope>provided</scope>
<exclusions>

View File

@ -0,0 +1,111 @@
package io.github.thebusybiscuit.slimefun4.api.events;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.apache.commons.lang.Validate;
import org.bukkit.Location;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSpawnReason;
/**
* This {@link Event} is fired whenever slimefun drops an {@link ItemStack}.
* Creating a custom {@link Event} for this allows other plugins to provide
* compatibility with auto-pickup options or similar.
*
* @author TheBusyBiscuit
*
* @see ItemSpawnReason
*/
public class SlimefunItemSpawnEvent extends Event implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private Location location;
private ItemStack itemStack;
private boolean cancelled;
private final ItemSpawnReason itemSpawnReason;
@ParametersAreNonnullByDefault
public SlimefunItemSpawnEvent(Location location, ItemStack itemStack, ItemSpawnReason itemSpawnReason) {
this.location = location;
this.itemStack = itemStack;
this.itemSpawnReason = itemSpawnReason;
this.cancelled = false;
}
/**
* This returns the {@link ItemSpawnReason} why we dropped an {@link ItemStack}.
*
* @return the {@link ItemSpawnReason}.
*/
public @Nonnull ItemSpawnReason getItemSpawnReason() {
return itemSpawnReason;
}
/**
* This returns the {@link Location} where we will drop the item.
*
* @return The {@link Location} where the item will be dropped
*/
public @Nonnull Location getLocation() {
return location;
}
/**
* This sets the {@link Location} on where to drop this item.
*
* @param location
* The {@link Location} where to drop the {@link ItemStack}
*/
public void setLocation(@Nonnull Location location) {
Validate.notNull(location, "The Location cannot be null!");
this.location = location;
}
/**
* This returns the {@link ItemStack} that will be dropped.
*
* @return The {@link ItemStack} that will be dropped
*/
public @Nonnull ItemStack getItemStack() {
return itemStack;
}
/**
* This method sets the {@link ItemStack} that should be dropped.
*
* @param itemStack
* The {@link ItemStack} to drop
*/
public void setItemStack(@Nonnull ItemStack itemStack) {
Validate.notNull(itemStack, "Cannot drop null.");
Validate.isTrue(!itemStack.getType().isAir(), "Cannot drop air.");
this.itemStack = itemStack;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
public static @Nonnull HandlerList getHandlerList() {
return handlers;
}
@Override
public @Nonnull HandlerList getHandlers() {
return getHandlerList();
}
}

View File

@ -0,0 +1,62 @@
package io.github.thebusybiscuit.slimefun4.api.items;
import org.bukkit.block.Block;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.events.SlimefunItemSpawnEvent;
import io.github.thebusybiscuit.slimefun4.core.networks.cargo.CargoNet;
import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientPedestal;
import io.github.thebusybiscuit.slimefun4.implementation.items.seasonal.ChristmasPresent;
import io.github.thebusybiscuit.slimefun4.implementation.items.seasonal.EasterEgg;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.GoldPan;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.PickaxeOfContainment;
/**
* This enum holds the different reasons as to why we may need to spawn an item.
*
* @author TheBusyBiscuit
*
* @see SlimefunItemSpawnEvent
*
*/
public enum ItemSpawnReason {
/**
* The item is spawned on top of an {@link AncientPedestal}.
*/
ANCIENT_PEDESTAL_PLACE_ITEM,
/**
* This {@link ItemStack} is dropped as a result of the {@link PickaxeOfContainment}
* breaking a monster spawner.
*/
BROKEN_SPAWNER_DROP,
/**
* The {@link ItemStack} is dropped as the result of a {@link CargoNet}
* overflowing.
*/
CARGO_OVERFLOW,
/**
* THe {@link ItemStack} is dropped as the result of an opened {@link ChristmasPresent}.
*/
CHRISTMAS_PRESENT_OPENED,
/**
* THe {@link ItemStack} is dropped as the result of an opened {@link EasterEgg}.
*/
EASTER_EGG_OPENED,
/**
* The {@link ItemStack} is dropped as the result of a {@link GoldPan} being used
* on a {@link Block} which yields drops.
*/
GOLD_PAN_USE,
/**
* Other reasons we did not account for.
*/
MISC;
}

View File

@ -21,10 +21,12 @@ import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.blocks.BlockPosition;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSpawnReason;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
import io.github.thebusybiscuit.slimefun4.core.networks.NetworkManager;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
@ -141,7 +143,7 @@ class CargoNetworkTask implements Runnable {
if (rest != null && !manager.isItemDeletionEnabled()) {
// If the item still couldn't be inserted, simply drop it on the ground
inputTarget.getWorld().dropItem(inputTarget.getLocation().add(0, 1, 0), rest);
SlimefunUtils.spawnItem(inputTarget.getLocation().add(0, 1, 0), rest, ItemSpawnReason.CARGO_OVERFLOW);
}
}
} else {
@ -151,7 +153,7 @@ class CargoNetworkTask implements Runnable {
if (menu.getItemInSlot(previousSlot) == null) {
menu.replaceExistingItem(previousSlot, item);
} else if (!manager.isItemDeletionEnabled()) {
inputTarget.getWorld().dropItem(inputTarget.getLocation().add(0, 1, 0), item);
SlimefunUtils.spawnItem(inputTarget.getLocation().add(0, 1, 0), item, ItemSpawnReason.CARGO_OVERFLOW);
}
}
}

View File

@ -76,6 +76,7 @@ class ContributionsConnector extends GitHubConnector {
aliases.put("ramdon-person", "ramdon_person");
aliases.put("NCBPFluffyBear", "FluffyBear_");
aliases.put("martinbrom", "OneTime97");
aliases.put("LilBC", "Lil_BC");
}
/**
@ -135,4 +136,4 @@ class ContributionsConnector extends GitHubConnector {
}
}
}
}
}

View File

@ -22,6 +22,7 @@ import io.github.thebusybiscuit.cscorelib2.chat.ChatColors;
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSpawnReason;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler;
@ -57,8 +58,7 @@ public class AncientPedestal extends SimpleSlimefunItem<BlockDispenseHandler> {
addItemHandler(onBreak());
}
@Nonnull
private BlockBreakHandler onBreak() {
private @Nonnull BlockBreakHandler onBreak() {
return new SimpleBlockBreakHandler() {
@Override
@ -79,12 +79,11 @@ public class AncientPedestal extends SimpleSlimefunItem<BlockDispenseHandler> {
}
@Override
public BlockDispenseHandler getItemHandler() {
public @Nonnull BlockDispenseHandler getItemHandler() {
return (e, d, block, machine) -> e.setCancelled(true);
}
@Nonnull
public Optional<Item> getPlacedItem(@Nonnull Block pedestal) {
public @Nonnull Optional<Item> getPlacedItem(@Nonnull Block pedestal) {
Location l = pedestal.getLocation().add(0.5, 1.2, 0.5);
for (Entity n : l.getWorld().getNearbyEntities(l, 0.5, 0.5, 0.5, this::testItem)) {
@ -107,8 +106,7 @@ public class AncientPedestal extends SimpleSlimefunItem<BlockDispenseHandler> {
}
}
@Nonnull
public ItemStack getOriginalItemStack(@Nonnull Item item) {
public @Nonnull ItemStack getOriginalItemStack(@Nonnull Item item) {
ItemStack stack = item.getItemStack().clone();
String customName = item.getCustomName();
@ -142,12 +140,14 @@ public class AncientPedestal extends SimpleSlimefunItem<BlockDispenseHandler> {
ItemUtils.consumeItem(hand, false);
}
Item entity = b.getWorld().dropItem(b.getLocation().add(0.5, 1.2, 0.5), displayItem);
entity.setVelocity(new Vector(0, 0.1, 0));
entity.setCustomNameVisible(true);
entity.setCustomName(nametag);
SlimefunUtils.markAsNoPickup(entity, "altar_item");
p.playSound(b.getLocation(), Sound.ENTITY_ITEM_PICKUP, 0.3F, 0.3F);
}
Item entity = SlimefunUtils.spawnItem(b.getLocation().add(0.5, 1.2, 0.5), displayItem, ItemSpawnReason.ANCIENT_PEDESTAL_PLACE_ITEM);
if (entity != null) {
entity.setVelocity(new Vector(0, 0.1, 0));
entity.setCustomNameVisible(true);
entity.setCustomName(nametag);
SlimefunUtils.markAsNoPickup(entity, "altar_item");
p.playSound(b.getLocation(), Sound.ENTITY_ITEM_PICKUP, 0.3F, 0.3F);
}
}
}

View File

@ -17,12 +17,13 @@ import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
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.multiblocks.MultiBlockMachine;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import io.papermc.lib.PaperLib;
@ -80,6 +81,11 @@ public class GrindStone extends MultiBlockMachine {
recipes.add(new ItemStack(Material.QUARTZ_BLOCK));
recipes.add(new ItemStack(Material.QUARTZ, 4));
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(SlimefunItems.MAGIC_LUMP_2);
recipes.add(new SlimefunItemStack(SlimefunItems.MAGIC_LUMP_1, 4));

View File

@ -150,6 +150,19 @@ public class OreCrusher extends MultiBlockMachine {
new ItemStack(Material.DEEPSLATE_EMERALD_ORE), doubleOres.getEmerald()
));
// @formatter:on
// More deepslate ores and copper ore
displayRecipes.add(new ItemStack(Material.DEEPSLATE_IRON_ORE));
displayRecipes.add(new SlimefunItemStack(SlimefunItems.IRON_DUST, isOreDoublingEnabled() ? 2 : 1));
displayRecipes.add(new ItemStack(Material.DEEPSLATE_GOLD_ORE));
displayRecipes.add(new SlimefunItemStack(SlimefunItems.GOLD_DUST, isOreDoublingEnabled() ? 2 : 1));
displayRecipes.add(new ItemStack(Material.DEEPSLATE_COPPER_ORE));
displayRecipes.add(new SlimefunItemStack(SlimefunItems.COPPER_DUST, isOreDoublingEnabled() ? 2 : 1));
displayRecipes.add(new ItemStack(Material.COPPER_ORE));
displayRecipes.add(new SlimefunItemStack(SlimefunItems.COPPER_DUST, isOreDoublingEnabled() ? 2 : 1));
}
}

View File

@ -52,6 +52,7 @@ public class IndustrialMiner extends MultiBlockMachine {
protected final List<MachineFuel> fuelTypes = new ArrayList<>();
private final ItemSetting<Boolean> canMineAncientDebris = new ItemSetting<>(this, "can-mine-ancient-debris", false);
private final ItemSetting<Boolean> canMineDeepslateOres = new ItemSetting<>(this, "can-mine-deepslate-ores", true);
private final boolean silkTouch;
private final int range;
@ -64,6 +65,7 @@ public class IndustrialMiner extends MultiBlockMachine {
registerDefaultFuelTypes();
addItemSetting(canMineAncientDebris);
addItemSetting(canMineDeepslateOres);
}
/**
@ -122,8 +124,41 @@ public class IndustrialMiner extends MultiBlockMachine {
return new ItemStack(ore);
}
MinecraftVersion minecraftVersion = Slimefun.getMinecraftVersion();
Random random = ThreadLocalRandom.current();
if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_17)) {
// In 1.17, breaking metal ores should get raw metals. Also support deepslate ores.
switch (ore) {
case DEEPSLATE_COAL_ORE:
return new ItemStack(Material.COAL);
case DEEPSLATE_DIAMOND_ORE:
return new ItemStack(Material.DIAMOND);
case DEEPSLATE_EMERALD_ORE:
return new ItemStack(Material.EMERALD);
case DEEPSLATE_REDSTONE_ORE:
return new ItemStack(Material.REDSTONE, 4 + random.nextInt(2));
case DEEPSLATE_LAPIS_ORE:
return new ItemStack(Material.LAPIS_LAZULI, 4 + random.nextInt(4));
case COPPER_ORE:
case DEEPSLATE_COPPER_ORE:
return new ItemStack(Material.RAW_COPPER);
case IRON_ORE:
case DEEPSLATE_IRON_ORE:
return new ItemStack(Material.RAW_IRON);
case GOLD_ORE:
case DEEPSLATE_GOLD_ORE:
return new ItemStack(Material.RAW_GOLD);
default:
break;
}
}
// In 1.16, breaking nether gold ores should get gold nuggets
if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_16) && ore == Material.NETHER_GOLD_ORE) {
return new ItemStack(Material.GOLD_NUGGET, 2 + random.nextInt(4));
}
switch (ore) {
case COAL_ORE:
return new ItemStack(Material.COAL);
@ -131,12 +166,12 @@ public class IndustrialMiner extends MultiBlockMachine {
return new ItemStack(Material.DIAMOND);
case EMERALD_ORE:
return new ItemStack(Material.EMERALD);
case NETHER_QUARTZ_ORE:
return new ItemStack(Material.QUARTZ);
case REDSTONE_ORE:
return new ItemStack(Material.REDSTONE, 4 + random.nextInt(2));
case LAPIS_ORE:
return new ItemStack(Material.LAPIS_LAZULI, 4 + random.nextInt(4));
case NETHER_QUARTZ_ORE:
return new ItemStack(Material.QUARTZ);
default:
// This includes Iron and Gold ore (and Ancient Debris)
return new ItemStack(ore);
@ -159,12 +194,12 @@ public class IndustrialMiner extends MultiBlockMachine {
}
@Override
public String getLabelLocalPath() {
public @Nonnull String getLabelLocalPath() {
return "guide.tooltips.recipes.generator";
}
@Override
public List<ItemStack> getDisplayRecipes() {
public @Nonnull List<ItemStack> getDisplayRecipes() {
List<ItemStack> list = new ArrayList<>();
for (MachineFuel fuel : fuelTypes) {
@ -217,14 +252,15 @@ public class IndustrialMiner extends MultiBlockMachine {
* @return Whether this {@link IndustrialMiner} is capable of mining this {@link Material}
*/
public boolean canMine(@Nonnull Material type) {
if (SlimefunTag.INDUSTRIAL_MINER_ORES.isTagged(type)) {
return true;
} else if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_16)) {
return type == Material.ANCIENT_DEBRIS && canMineAncientDebris.getValue();
MinecraftVersion version = Slimefun.getMinecraftVersion();
if (version.isAtLeast(MinecraftVersion.MINECRAFT_1_16) && type == Material.ANCIENT_DEBRIS) {
return canMineAncientDebris.getValue();
} else if (version.isAtLeast(MinecraftVersion.MINECRAFT_1_17) && SlimefunTag.DEEPSLATE_ORES.isTagged(type)) {
return canMineDeepslateOres.getValue();
} else {
return SlimefunTag.INDUSTRIAL_MINER_ORES.isTagged(type);
}
return false;
}
}

View File

@ -12,6 +12,7 @@ import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
@ -28,6 +29,7 @@ import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.cscorelib2.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;
@ -180,8 +182,9 @@ class MiningTask implements Runnable {
Block furnace = chest.getRelative(BlockFace.DOWN);
furnace.getWorld().playEffect(furnace.getLocation(), Effect.STEP_SOUND, Material.STONE);
for (int y = height; y > 0; y--) {
Block b = start.getWorld().getBlockAt(x, y, z);
World world = start.getWorld();
for (int y = height; y > WorldUtils.getMinHeight(world); y--) {
Block b = world.getBlockAt(x, y, z);
if (!Slimefun.getProtectionManager().hasPermission(Bukkit.getOfflinePlayer(owner), b, ProtectableAction.BREAK_BLOCK)) {
stop(MinerStoppingReason.NO_PERMISSION);
@ -213,7 +216,7 @@ class MiningTask implements Runnable {
}
/**
* This advanced the {@link IndustrialMiner} to the next column
* This advances the {@link IndustrialMiner} to the next column
*/
private void nextColumn() {
if (x < end.getX()) {

View File

@ -11,6 +11,7 @@ import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSpawnReason;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
@ -18,6 +19,7 @@ import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.utils.FireworkUtils;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
/**
* The {@link ChristmasPresent} is a seasonal {@link SlimefunItem} that drops a random
@ -53,7 +55,7 @@ public class ChristmasPresent extends SimpleSlimefunItem<ItemUseHandler> impleme
Block b = block.getRelative(e.getClickedFace());
ItemStack gift = gifts[ThreadLocalRandom.current().nextInt(gifts.length)].clone();
b.getWorld().dropItemNaturally(b.getLocation(), gift);
SlimefunUtils.spawnItem(b.getLocation(), gift, ItemSpawnReason.CHRISTMAS_PRESENT_OPENED, true);
});
};
}

View File

@ -11,12 +11,14 @@ import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSpawnReason;
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.handlers.ItemUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.utils.FireworkUtils;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
/**
* This {@link SlimefunItem} represents an {@link EasterEgg}.
@ -51,7 +53,7 @@ public class EasterEgg extends SimpleSlimefunItem<ItemUseHandler> {
}
FireworkUtils.launchRandom(p, 2);
p.getWorld().dropItemNaturally(p.getLocation(), gifts[ThreadLocalRandom.current().nextInt(gifts.length)].clone());
SlimefunUtils.spawnItem(p.getLocation(), gifts[ThreadLocalRandom.current().nextInt(gifts.length)].clone(), ItemSpawnReason.EASTER_EGG_OPENED, true);
};
}

View File

@ -18,18 +18,22 @@ import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.collections.RandomizedSet;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSpawnReason;
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.RecipeDisplayItem;
import io.github.thebusybiscuit.slimefun4.core.handlers.EntityInteractHandler;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
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.implementation.items.electric.machines.ElectricGoldPan;
import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.AutomatedPanningMachine;
import io.github.thebusybiscuit.slimefun4.implementation.settings.GoldPanDrop;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
/**
* A {@link GoldPan} is a {@link SlimefunItem} which allows you to obtain various
@ -133,7 +137,7 @@ public class GoldPan extends SimpleSlimefunItem<ItemUseHandler> implements Recip
// Make sure that the randomly selected item is not air
if (output.getType() != Material.AIR) {
b.getWorld().dropItemNaturally(b.getLocation(), output.clone());
SlimefunUtils.spawnItem(b.getLocation(), output.clone(), ItemSpawnReason.GOLD_PAN_USE, true);
}
}
}

View File

@ -11,6 +11,7 @@ import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSpawnReason;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler;
@ -19,6 +20,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunIte
import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.AbstractMonsterSpawner;
import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.BrokenSpawner;
import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.RepairedSpawner;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import io.papermc.lib.PaperLib;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
@ -42,13 +44,13 @@ public class PickaxeOfContainment extends SimpleSlimefunItem<ToolUseHandler> {
}
@Override
public ToolUseHandler getItemHandler() {
public @Nonnull ToolUseHandler getItemHandler() {
return (e, tool, fortune, drops) -> {
Block b = e.getBlock();
if (b.getType() == Material.SPAWNER) {
ItemStack spawner = breakSpawner(b);
b.getLocation().getWorld().dropItemNaturally(b.getLocation(), spawner);
SlimefunUtils.spawnItem(b.getLocation(), spawner, ItemSpawnReason.BROKEN_SPAWNER_DROP, true);
e.setExpToDrop(0);
e.setDropItems(false);
@ -56,8 +58,7 @@ public class PickaxeOfContainment extends SimpleSlimefunItem<ToolUseHandler> {
};
}
@Nonnull
private ItemStack breakSpawner(@Nonnull Block b) {
private @Nonnull ItemStack breakSpawner(@Nonnull Block b) {
AbstractMonsterSpawner spawner;
/**

View File

@ -4,17 +4,23 @@ import java.util.Optional;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.GameRule;
import org.bukkit.Keyed;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.Event.Result;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Recipe;
import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
import io.github.thebusybiscuit.slimefun4.implementation.Slimefun;
import io.github.thebusybiscuit.slimefun4.implementation.items.autocrafters.AbstractAutoCrafter;
import io.github.thebusybiscuit.slimefun4.implementation.items.autocrafters.EnhancedAutoCrafter;
import io.github.thebusybiscuit.slimefun4.implementation.items.autocrafters.VanillaAutoCrafter;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.gadgets.Multimeter;
/**
@ -22,11 +28,12 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.electric.gadgets.
* See Issue #2896 with the {@link EnhancedAutoCrafter}, any {@link SlimefunItem} which
* overrides the right click functonality would be ignored.
* This {@link Listener} resolves that issue.
*
* @author TheBusyBiscuit
*
* @see EnhancedAutoCrafter
*
* @author TheBusyBiscuit
* @author LilBC
*
* @see VanillaAutoCrafter
* @see EnhancedAutoCrafter
*/
public class AutoCrafterListener implements Listener {
@ -61,6 +68,17 @@ public class AutoCrafterListener implements Listener {
// Prevent blocks from being placed, food from being eaten, etc...
e.cancel();
// Check for the "doLimitedCrafting" gamerule when using a Vanilla Auto-Crafter
if (block instanceof VanillaAutoCrafter) {
boolean doLimitedCrafting = e.getPlayer().getWorld().getGameRuleValue(GameRule.DO_LIMITED_CRAFTING);
// Check if the recipe of the item is disabled.
if (doLimitedCrafting && !hasUnlockedRecipe(e.getPlayer(), e.getItem())) {
Slimefun.getLocalization().sendMessage(e.getPlayer(), "messages.auto-crafting.recipe-unavailable");
return;
}
}
// Fixes 2896 - Forward the interaction before items get handled.
AbstractAutoCrafter crafter = (AbstractAutoCrafter) block;
@ -73,4 +91,14 @@ public class AutoCrafterListener implements Listener {
}
}
@ParametersAreNonnullByDefault
private boolean hasUnlockedRecipe(Player p, ItemStack item) {
for (Recipe recipe : Slimefun.getMinecraftRecipeService().getRecipesFor(item)) {
if (recipe instanceof Keyed && !p.hasDiscoveredRecipe(((Keyed) recipe).getKey())) {
return false;
}
}
return true;
}
}

View File

@ -288,6 +288,7 @@ public final class ResearchSetup {
register("ingredients_and_cheese", 276, "Slimefun Cuisine", 5, SlimefunItems.SALT, SlimefunItems.WHEAT_FLOUR, SlimefunItems.HEAVY_CREAM, SlimefunItems.CHEESE, SlimefunItems.BUTTER);
register("medium_tier_auto_enchanting", 277, "Fast Automatic Enchanting and Disenchanting", 48, SlimefunItems.AUTO_ENCHANTER_2, SlimefunItems.AUTO_DISENCHANTER_2);
register("portable_teleporter", 278, "Teleportation from Anywhere", 42, SlimefunItems.PORTABLE_TELEPORTER);
register("trident", 279, "Trident", 20, new ItemStack(Material.TRIDENT));
}
@ParametersAreNonnullByDefault

View File

@ -2022,6 +2022,10 @@ public final class SlimefunItemSetup {
new ItemStack[] {SlimefunItems.FLASK_OF_KNOWLEDGE, SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.FLASK_OF_KNOWLEDGE, SlimefunItems.ELYTRA_SCALE, new ItemStack(Material.ELYTRA), SlimefunItems.ELYTRA_SCALE, SlimefunItems.FLASK_OF_KNOWLEDGE, SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.FLASK_OF_KNOWLEDGE})
.register(plugin);
new VanillaItem(categories.magicalGadgets, new ItemStack(Material.TRIDENT), "TRIDENT", RecipeType.ANCIENT_ALTAR,
new ItemStack[] { new ItemStack(Material.NAUTILUS_SHELL), SlimefunItems.REINFORCED_ALLOY_INGOT, new ItemStack(Material.NAUTILUS_SHELL), SlimefunItems.STAFF_WATER, new ItemStack(Material.DIAMOND_SWORD), SlimefunItems.STAFF_WATER, SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.NETHER_STAR), SlimefunItems.MAGIC_LUMP_3})
.register(plugin);
new VanillaItem(categories.magicalGadgets, new ItemStack(Material.TOTEM_OF_UNDYING), "TOTEM_OF_UNDYING", RecipeType.ANCIENT_ALTAR,
new ItemStack[] {SlimefunItems.ESSENCE_OF_AFTERLIFE, new ItemStack(Material.EMERALD_BLOCK), SlimefunItems.ESSENCE_OF_AFTERLIFE, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.COMMON_TALISMAN, SlimefunItems.MAGIC_LUMP_3, SlimefunItems.ESSENCE_OF_AFTERLIFE, new ItemStack(Material.EMERALD_BLOCK), SlimefunItems.ESSENCE_OF_AFTERLIFE})
.register(plugin);

View File

@ -8,6 +8,7 @@ import java.util.Optional;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import org.apache.commons.lang.Validate;
import org.bukkit.ChatColor;
@ -27,7 +28,9 @@ import org.bukkit.persistence.PersistentDataType;
import io.github.thebusybiscuit.cscorelib2.item.ImmutableItemMeta;
import io.github.thebusybiscuit.cscorelib2.skull.SkullItem;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.events.SlimefunItemSpawnEvent;
import io.github.thebusybiscuit.slimefun4.api.exceptions.PrematureCodeException;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSpawnReason;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
import io.github.thebusybiscuit.slimefun4.core.attributes.Radioactive;
@ -403,4 +406,57 @@ public final class SlimefunUtils {
}
}
/**
* Helper method to spawn an {@link ItemStack}.
* This method automatically calls a {@link SlimefunItemSpawnEvent} to allow
* other plugins to catch the item being dropped.
*
* @param loc
* The {@link Location} where to drop the item
* @param item
* The {@link ItemStack} to drop
* @param reason
* The {@link ItemSpawnReason} why the item is being dropped
* @param addRandomOffset
* Whether a random offset should be added (see {@link World#dropItemNaturally(Location, ItemStack)})
*
* @return The dropped {@link Item} (or null if the {@link SlimefunItemSpawnEvent} was cancelled)
*/
@ParametersAreNonnullByDefault
public static @Nullable Item spawnItem(Location loc, ItemStack item, ItemSpawnReason reason, boolean addRandomOffset) {
SlimefunItemSpawnEvent event = new SlimefunItemSpawnEvent(loc, item, reason);
Slimefun.instance().getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
World world = event.getLocation().getWorld();
if (addRandomOffset) {
return world.dropItemNaturally(event.getLocation(), event.getItemStack());
} else {
return world.dropItem(event.getLocation(), event.getItemStack());
}
} else {
return null;
}
}
/**
* Helper method to spawn an {@link ItemStack}.
* This method automatically calls a {@link SlimefunItemSpawnEvent} to allow
* other plugins to catch the item being dropped.
*
* @param loc
* The {@link Location} where to drop the item
* @param item
* The {@link ItemStack} to drop
* @param reason
* The {@link ItemSpawnReason} why the item is being dropped
*
* @return The dropped {@link Item} (or null if the {@link SlimefunItemSpawnEvent} was cancelled)
*/
@ParametersAreNonnullByDefault
public static @Nullable Item spawnItem(Location loc, ItemStack item, ItemSpawnReason reason) {
return spawnItem(loc, item, reason, false);
}
}

View File

@ -151,6 +151,9 @@ messages:
select: 'Dieses Rezept auswählen'
temporarily-disabled: '&eDieser Auto-Crafter wurde vorübergehend deaktiviert. Du kannst ihn jederzeit wieder aktivieren!'
re-enabled: '&eDieser Auto-Crafter wurde reaktiviert!'
recipe-unavailable: |
&cDieses Item ist entweder auf deinem Server deaktiviert oder du hast es noch nicht freigeschaltet.
&7Versuche das Item herzustellen, wenn du dies noch nicht getan hast, um das Rezept freizuschalten.
tooltips:
enabled:
- '&cDieses Rezept ist momentan deaktiviert'

View File

@ -211,6 +211,7 @@ slimefun:
better_heated_pressure_chamber: Unter Druck
elytra: Gleitflügel
special_elytras: Verzauberte Gleitflügel
trident: Dreizack
electric_crucible: Elektrischer Schmelztiegel
better_electric_crucibles: Verbesserter Schmelztiegel
advanced_electric_smeltery: Verbesserter elektrischer Schmelzofen
@ -256,3 +257,4 @@ slimefun:
improved_generators: Verbesserte Generatoren
ingredients_and_cheese: Eine Basis für jede Küche
medium_tier_auto_enchanting: Schnelle Verzauberungsmaschinen
portable_teleporter: Ein handlicher Teleporter

View File

@ -174,6 +174,9 @@ messages:
select: 'Select this recipe'
temporarily-disabled: '&eThis Auto-Crafter was temporarily disabled. You can re-enable it at any time!'
re-enabled: '&eThis Auto-Crafter was re-enabled!'
recipe-unavailable: |
&cThis item is either disabled on your server, or you have not unlocked it yet.
&7Try crafting the item if you have not done this before to unlock the recipe.
tooltips:
enabled:

View File

@ -210,6 +210,7 @@ slimefun:
better_heated_pressure_chamber: Upgraded Heated Pressure Chamber
elytra: Elytras
special_elytras: Special Elytras
trident: Trident
electric_crucible: Electrified Crucible
better_electric_crucibles: Hot Crucibles
advanced_electric_smeltery: Advanced Electric Smeltery

View File

@ -152,6 +152,9 @@ messages:
select: 'Sélectionner cette recette'
temporarily-disabled: '&eCet Auto-Crafter a été temporairement désactivé. Vous pouvez le réactiver à tout moment !'
re-enabled: '&eCet Auto-Crafteur a été réactivé !'
recipe-unavailable: |
&cCet objet est soit désactivé sur votre serveur, soit vous ne l'avez pas encore débloqué.
&7Essayez de fabriquer l'objet si vous ne l'avez pas fait avant pour déverrouiller la recette.
tooltips:
enabled:
- '&aCette recette est actuellement activée'

View File

@ -211,6 +211,7 @@ slimefun:
better_heated_pressure_chamber: Chambre sous pression chauffée améliorée
elytra: Élytres
special_elytras: Élytres spéciales
trident: Trident
electric_crucible: Creuset électrique
better_electric_crucibles: Creusets chauffés
advanced_electric_smeltery: Fonderie électrique avancée

View File

@ -152,6 +152,9 @@ messages:
select: 'Válaszd ki ezt a receptet'
temporarily-disabled: '&eEz az Autómatikus Barkácsoló ideiglenesen ki van kapcsolva. Bármikor bekapcsolhatod!'
re-enabled: '&eAutómata barkácsoló visszakapcsolva!'
recipe-unavailable: |
&cEz a tárgy vagy ki van kapcsolva a szerveren, vagy még nem oldottad fel.
&7Próbáld meg elkészíteni a tárgyat, ha még nem tetted volna, hogy felold a receptet.
tooltips:
enabled:
- '&aEz a recept jelenleg be van kapcsolva'

View File

@ -211,6 +211,7 @@ slimefun:
better_heated_pressure_chamber: Továbbfejlesztett fűtött nyomáskamra
elytra: Kitinszárnyak
special_elytras: Speciális kitinszárnyak
trident: Szigony
electric_crucible: Elektromos olvasztótégely
better_electric_crucibles: Forró olvasztótégelyek
advanced_electric_smeltery: Fejlett elektromos olvasztómű

View File

@ -211,6 +211,7 @@ slimefun:
better_heated_pressure_chamber: 更好的加热压力舱
elytra: 鞘翅
special_elytras: 特殊鞘翅
trident: 三叉戟
electric_crucible: 电力坩埚
better_electric_crucibles: 更好的坩埚
advanced_electric_smeltery: 高级电力冶炼机