1
mirror of https://github.com/StarWishsama/Slimefun4.git synced 2024-09-19 19:25:48 +00:00
This commit is contained in:
TheBusyBiscuit 2020-12-01 16:12:57 +01:00
parent ac7bb44d98
commit 5d0ed3570d
6 changed files with 163 additions and 69 deletions

View File

@ -84,6 +84,7 @@
* Fixed #2576
* Fixed #2496
* Fixed #2585
* Fixed #2583
## Release Candidate 17 (17 Oct 2020)

View File

@ -0,0 +1,113 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.blocks;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.apache.commons.lang.Validate;
import org.bukkit.ChatColor;
import org.bukkit.block.BlockState;
import org.bukkit.block.CreatureSpawner;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BlockStateMeta;
import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.slimefun4.utils.ChatUtils;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/**
* This is a parent class for the {@link BrokenSpawner} and {@link RepairedSpawner}
* to provide some utility methods.
*
* @author TheBusyBiscuit
*
* @see BrokenSpawner
* @see RepairedSpawner
*
*/
public abstract class AbstractMonsterSpawner extends SlimefunItem {
@ParametersAreNonnullByDefault
AbstractMonsterSpawner(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
}
/**
* This method tries to obtain an {@link EntityType} from a given {@link ItemStack}.
* The provided {@link ItemStack} must be a {@link RepairedSpawner} item.
*
* @param item
* The {@link ItemStack} to extract the {@link EntityType} from
*
* @return An {@link Optional} describing the result
*/
@Nonnull
public Optional<EntityType> getEntityType(@Nonnull ItemStack item) {
Validate.notNull(item, "The Item cannot be null");
ItemMeta meta = item.getItemMeta();
// We may want to update this in the future to also make use of the BlockStateMeta
for (String line : meta.getLore()) {
if (ChatColor.stripColor(line).startsWith("Type: ") && !line.contains("<Type>")) {
EntityType type = EntityType.valueOf(ChatColor.stripColor(line).replace("Type: ", "").replace(' ', '_').toUpperCase(Locale.ROOT));
return Optional.of(type);
}
}
return Optional.empty();
}
/**
* This method returns a finished {@link ItemStack} of this {@link SlimefunItem}, modified
* to hold and represent the given {@link EntityType}.
* It updates the lore and {@link BlockStateMeta} to reflect the specified {@link EntityType}.
*
* @param type
* The {@link EntityType} to apply
*
* @return An {@link ItemStack} for this {@link SlimefunItem} holding that {@link EntityType}
*/
@Nonnull
public ItemStack getItemForEntityType(@Nonnull EntityType type) {
Validate.notNull(type, "The EntityType cannot be null");
ItemStack item = getItem().clone();
ItemMeta meta = item.getItemMeta();
// Fixes #2583 - Proper NBT handling of Spawners
if (meta instanceof BlockStateMeta) {
BlockStateMeta stateMeta = (BlockStateMeta) meta;
BlockState state = stateMeta.getBlockState();
if (state instanceof CreatureSpawner) {
((CreatureSpawner) state).setSpawnedType(type);
}
stateMeta.setBlockState(state);
}
// Setting the lore to indicate the Type visually
List<String> lore = meta.getLore();
for (int i = 0; i < lore.size(); i++) {
if (lore.get(i).contains("<Type>")) {
lore.set(i, lore.get(i).replace("<Type>", ChatUtils.humanize(type.name())));
break;
}
}
meta.setLore(lore);
item.setItemMeta(meta);
return item;
}
}

View File

@ -1,7 +1,13 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.blocks;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent;
import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable;
import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
@ -17,10 +23,18 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
* @see RepairedSpawner
*
*/
public class BrokenSpawner extends UnplaceableBlock {
public class BrokenSpawner extends AbstractMonsterSpawner implements NotPlaceable {
@ParametersAreNonnullByDefault
public BrokenSpawner(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
addItemHandler(onRightClick());
}
@Nonnull
private ItemUseHandler onRightClick() {
return PlayerRightClickEvent::cancel;
}
}

View File

@ -2,20 +2,17 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.blocks;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Locale;
import java.util.Optional;
import org.bukkit.ChatColor;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Material;
import org.bukkit.block.CreatureSpawner;
import org.bukkit.entity.EntityType;
import org.bukkit.event.block.BlockEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.slimefun4.api.events.BlockPlacerPlaceEvent;
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
@ -28,15 +25,13 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
* @see BrokenSpawner
*
*/
public class RepairedSpawner extends SimpleSlimefunItem<BlockPlaceHandler> {
public class RepairedSpawner extends AbstractMonsterSpawner {
@ParametersAreNonnullByDefault
public RepairedSpawner(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
}
@Override
public BlockPlaceHandler getItemHandler() {
return new BlockPlaceHandler(true) {
addItemHandler(new BlockPlaceHandler(true) {
@Override
public void onPlayerPlace(BlockPlaceEvent e) {
@ -48,42 +43,25 @@ public class RepairedSpawner extends SimpleSlimefunItem<BlockPlaceHandler> {
onPlace(e.getItemStack(), e);
}
@ParametersAreNonnullByDefault
private void onPlace(ItemStack item, BlockEvent e) {
Optional<EntityType> entity = getEntityType(item);
if (entity.isPresent() && e.getBlock().getType() == Material.SPAWNER) {
CreatureSpawner spawner = (CreatureSpawner) e.getBlock().getState();
spawner.setSpawnedType(entity.get());
spawner.update(true, false);
if (e.getBlock().getType() == Material.SPAWNER) {
getEntityType(item).ifPresent(entity -> {
CreatureSpawner spawner = (CreatureSpawner) e.getBlock().getState();
spawner.setSpawnedType(entity);
spawner.update(true, false);
});
}
}
};
}
/**
* This method tries to obtain an {@link EntityType} from a given {@link ItemStack}.
* The provided {@link ItemStack} must be a {@link RepairedSpawner} item.
*
* @param item
* The {@link ItemStack} to extract the {@link EntityType} from
*
* @return An {@link Optional} describing the result
*/
public Optional<EntityType> getEntityType(ItemStack item) {
for (String line : item.getItemMeta().getLore()) {
if (ChatColor.stripColor(line).startsWith("Type: ") && !line.contains("<Type>")) {
EntityType type = EntityType.valueOf(ChatColor.stripColor(line).replace("Type: ", "").replace(' ', '_').toUpperCase(Locale.ROOT));
return Optional.of(type);
}
}
return Optional.empty();
});
}
@Override
public Collection<ItemStack> getDrops() {
// There should be no drops by default since drops are handled by the
// Pickaxe of Containment exclusively.
/**
* There should be no drops by default since drops are handled
* by the Pickaxe of Containment exclusively.
*/
return new ArrayList<>();
}

View File

@ -1,6 +1,6 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.tools;
import java.util.List;
import javax.annotation.Nonnull;
import org.bukkit.Material;
import org.bukkit.block.Block;
@ -8,14 +8,13 @@ import org.bukkit.block.BlockState;
import org.bukkit.block.CreatureSpawner;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems;
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
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.ChatUtils;
import io.papermc.lib.PaperLib;
import me.mrCookieSlime.Slimefun.Lists.RecipeType;
import me.mrCookieSlime.Slimefun.Objects.Category;
@ -54,33 +53,25 @@ public class PickaxeOfContainment extends SimpleSlimefunItem<ToolUseHandler> {
};
}
private ItemStack breakSpawner(Block b) {
// If the spawner's BlockStorage has BlockInfo, then it's not a vanilla spawner and
// should not give a broken spawner.
ItemStack spawner = SlimefunItems.BROKEN_SPAWNER.clone();
@Nonnull
private ItemStack breakSpawner(@Nonnull Block b) {
AbstractMonsterSpawner spawner;
/**
* If the spawner's BlockStorage has BlockInfo, then it's not a vanilla spawner
* and should not give a broken spawner but a repaired one instead.
*/
if (BlockStorage.hasBlockInfo(b)) {
spawner = SlimefunItems.REPAIRED_SPAWNER.clone();
spawner = (AbstractMonsterSpawner) SlimefunItems.REPAIRED_SPAWNER.getItem();
} else {
spawner = (AbstractMonsterSpawner) SlimefunItems.BROKEN_SPAWNER.getItem();
}
ItemMeta im = spawner.getItemMeta();
List<String> lore = im.getLore();
BlockState state = PaperLib.getBlockState(b, false).getState();
if (state instanceof CreatureSpawner) {
EntityType entityType = ((CreatureSpawner) state).getSpawnedType();
for (int i = 0; i < lore.size(); i++) {
if (lore.get(i).contains("<Type>")) {
lore.set(i, lore.get(i).replace("<Type>", ChatUtils.humanize(entityType.name())));
break;
}
}
im.setLore(lore);
spawner.setItemMeta(im);
return spawner;
return spawner.getItemForEntityType(entityType);
}
return new ItemStack(Material.SPAWNER);

View File

@ -1,7 +1,6 @@
package io.github.thebusybiscuit.slimefun4.implementation.listeners;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
@ -17,6 +16,7 @@ import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.event.Event.Result;
@ -25,7 +25,6 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
@ -36,6 +35,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AltarRecipe;
import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientAltar;
import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientPedestal;
import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.RepairedSpawner;
import io.github.thebusybiscuit.slimefun4.implementation.tasks.AncientAltarTask;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
@ -312,11 +312,8 @@ public class AncientAltarListener implements Listener {
return Optional.empty();
}
ItemStack spawner = SlimefunItems.REPAIRED_SPAWNER.clone();
ItemMeta im = spawner.getItemMeta();
im.setLore(Arrays.asList(wrapper.getItemMeta().getLore().get(0)));
spawner.setItemMeta(im);
return Optional.of(spawner);
RepairedSpawner spawner = (RepairedSpawner) SlimefunItems.REPAIRED_SPAWNER.getItem();
return Optional.of(spawner.getItemForEntityType(spawner.getEntityType(wrapper).orElse(EntityType.PIG)));
}
return checkRecipe(wrapper, items);