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

[CI skip] More refactoring and overall API improvements

This commit is contained in:
TheBusyBiscuit 2020-04-09 14:22:30 +02:00
parent 8f698bebee
commit 911f8aeceb
7 changed files with 132 additions and 156 deletions

View File

@ -64,6 +64,8 @@
* Split whitelist.yml up into individual /world-settings/worldname.yml files
* Performance improvements
* Slimefun Guide runs much faster now and can better deal with many Categories and items
* Lots of API improvements
* Faulty addons are now identified more easily and will no longer break Slimefun's main content this quickly
#### Fixes
* Fixed error message when clicking empty slots in the Slimefun Guide

View File

@ -1,5 +1,8 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Effect;
import org.bukkit.GameMode;
import org.bukkit.Material;
@ -10,141 +13,73 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.collections.RandomizedSet;
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
import io.github.thebusybiscuit.cscorelib2.scheduling.TaskQueue;
import io.github.thebusybiscuit.slimefun4.implementation.items.tools.GoldPan;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Lists.Categories;
import me.mrCookieSlime.Slimefun.Lists.SlimefunItems;
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.multiblocks.MultiBlockMachine;
import me.mrCookieSlime.Slimefun.api.Slimefun;
public class AutomatedPanningMachine extends MultiBlockMachine {
private final RandomizedSet<ItemStack> randomizer = new RandomizedSet<>();
private int weights;
private final RandomizedSet<ItemStack> randomizerNether = new RandomizedSet<>();
private int weightsNether;
public AutomatedPanningMachine() {
super(
Categories.MACHINES_1,
SlimefunItems.AUTOMATED_PANNING_MACHINE,
new ItemStack[] {
null, null, null,
null, new ItemStack(Material.OAK_TRAPDOOR), null,
null, new ItemStack(Material.CAULDRON), null
},
new ItemStack[] {
new ItemStack(Material.GRAVEL), new ItemStack(Material.FLINT),
new ItemStack(Material.GRAVEL), SlimefunItems.SIFTED_ORE,
new ItemStack(Material.GRAVEL), new ItemStack(Material.CLAY_BALL),
new ItemStack(Material.GRAVEL), new ItemStack(Material.IRON_NUGGET),
new ItemStack(Material.SOUL_SAND), new ItemStack(Material.QUARTZ),
new ItemStack(Material.SOUL_SAND), new ItemStack(Material.GOLD_NUGGET),
new ItemStack(Material.SOUL_SAND), new ItemStack(Material.NETHER_WART),
new ItemStack(Material.SOUL_SAND), new ItemStack(Material.BLAZE_POWDER),
new ItemStack(Material.SOUL_SAND), new ItemStack(Material.GLOWSTONE_DUST),
new ItemStack(Material.SOUL_SAND), new ItemStack(Material.GHAST_TEAR)
},
BlockFace.SELF
);
}
@Override
public void postRegister() {
super.postRegister();
String goldPan = "GOLD_PAN";
String netherGoldPan = "NETHER_GOLD_PAN";
add(false, SlimefunItems.SIFTED_ORE, (int) Slimefun.getItemValue(goldPan, "chance.SIFTED_ORE"));
add(false, new ItemStack(Material.CLAY_BALL), (int) Slimefun.getItemValue(goldPan, "chance.CLAY"));
add(false, new ItemStack(Material.FLINT), (int) Slimefun.getItemValue(goldPan, "chance.FLINT"));
add(false, new ItemStack(Material.IRON_NUGGET), (int) Slimefun.getItemValue(goldPan, "chance.IRON_NUGGET"));
private final GoldPan goldPan = (GoldPan) SlimefunItems.GOLD_PAN.getItem();
private final GoldPan netherGoldPan = (GoldPan) SlimefunItems.NETHER_GOLD_PAN.getItem();
if (weights < 100) {
add(false, new ItemStack(Material.AIR), 100 - weights);
}
add(true, new ItemStack(Material.QUARTZ), (int) Slimefun.getItemValue(netherGoldPan, "chance.QUARTZ"));
add(true, new ItemStack(Material.GOLD_NUGGET), (int) Slimefun.getItemValue(netherGoldPan, "chance.GOLD_NUGGET"));
add(true, new ItemStack(Material.NETHER_WART), (int) Slimefun.getItemValue(netherGoldPan, "chance.NETHER_WART"));
add(true, new ItemStack(Material.BLAZE_POWDER), (int) Slimefun.getItemValue(netherGoldPan, "chance.BLAZE_POWDER"));
add(true, new ItemStack(Material.GLOWSTONE_DUST), (int) Slimefun.getItemValue(netherGoldPan, "chance.GLOWSTONE_DUST"));
add(true, new ItemStack(Material.GHAST_TEAR), (int) Slimefun.getItemValue(netherGoldPan, "chance.GHAST_TEAR"));
public AutomatedPanningMachine() {
super(Categories.MACHINES_1, SlimefunItems.AUTOMATED_PANNING_MACHINE, new ItemStack[] { null, null, null, null, new ItemStack(Material.OAK_TRAPDOOR), null, null, new ItemStack(Material.CAULDRON), null }, new ItemStack[0], BlockFace.SELF);
}
if (weightsNether < 100) {
add(true, new ItemStack(Material.AIR), 100 - weightsNether);
}
}
private void add(boolean nether, ItemStack item, int chance) {
if (nether) {
randomizerNether.add(item, chance);
weightsNether += chance;
}
else {
randomizer.add(item, chance);
weights += chance;
}
}
@Override
public void onInteract(Player p, Block b) {
ItemStack input = p.getInventory().getItemInMainHand();
if (SlimefunUtils.isItemSimilar(input, new ItemStack(Material.GRAVEL), true) || SlimefunUtils.isItemSimilar(input, new ItemStack(Material.SOUL_SAND), true)) {
Material block = input.getType();
if (p.getGameMode() != GameMode.CREATIVE) {
ItemUtils.consumeItem(input, false);
}
ItemStack output = getRandomDrop(block);
TaskQueue queue = new TaskQueue();
queue.thenRepeatEvery(20, 5, () ->
b.getWorld().playEffect(b.getRelative(BlockFace.DOWN).getLocation(), Effect.STEP_SOUND, block)
);
queue.thenRun(20, () -> {
if (output.getType() != Material.AIR) {
Inventory outputChest = findOutputChest(b.getRelative(BlockFace.DOWN), output);
if (outputChest != null) {
outputChest.addItem(output.clone());
}
else {
b.getWorld().dropItemNaturally(b.getLocation(), output.clone());
}
p.getWorld().playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1F, 1F);
}
else {
p.getWorld().playSound(p.getLocation(), Sound.ENTITY_ARMOR_STAND_BREAK, 1F, 1F);
}
});
queue.execute(SlimefunPlugin.instance);
}
else {
SlimefunPlugin.getLocal().sendMessage(p, "machines.wrong-item", true);
}
}
@Override
public List<ItemStack> getDisplayRecipes() {
List<ItemStack> recipes = new ArrayList<>();
private ItemStack getRandomDrop(Material input) {
if (input == Material.GRAVEL) {
return randomizer.getRandom();
}
else if (input == Material.SOUL_SAND) {
return randomizerNether.getRandom();
}
return new ItemStack(Material.AIR);
}
recipes.addAll(goldPan.getDisplayRecipes());
recipes.addAll(netherGoldPan.getDisplayRecipes());
return recipes;
}
@Override
public void onInteract(Player p, Block b) {
ItemStack input = p.getInventory().getItemInMainHand();
if (SlimefunUtils.isItemSimilar(input, new ItemStack(Material.GRAVEL), true) || SlimefunUtils.isItemSimilar(input, new ItemStack(Material.SOUL_SAND), true)) {
Material material = input.getType();
if (p.getGameMode() != GameMode.CREATIVE) {
ItemUtils.consumeItem(input, false);
}
ItemStack output = material == Material.GRAVEL ? goldPan.getRandomOutput() : netherGoldPan.getRandomOutput();
TaskQueue queue = new TaskQueue();
queue.thenRepeatEvery(20, 5, () -> b.getWorld().playEffect(b.getRelative(BlockFace.DOWN).getLocation(), Effect.STEP_SOUND, material));
queue.thenRun(20, () -> {
if (output.getType() != Material.AIR) {
Inventory outputChest = findOutputChest(b.getRelative(BlockFace.DOWN), output);
if (outputChest != null) {
outputChest.addItem(output.clone());
}
else {
b.getWorld().dropItemNaturally(b.getLocation(), output.clone());
}
p.getWorld().playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1F, 1F);
}
else {
p.getWorld().playSound(p.getLocation(), Sound.ENTITY_ARMOR_STAND_BREAK, 1F, 1F);
}
});
queue.execute(SlimefunPlugin.instance);
}
else {
SlimefunPlugin.getLocal().sendMessage(p, "machines.wrong-item", true);
}
}
}

View File

@ -91,6 +91,7 @@ public class ExplosivePickaxe extends SimpleSlimefunItem<BlockBreakHandler> impl
for (ItemStack drop : b.getDrops(getItem())) {
b.getWorld().dropItemNaturally(b.getLocation(), (b.getType().toString().endsWith("_ORE") && b.getType() != Material.IRON_ORE && b.getType() != Material.GOLD_ORE) ? new CustomItem(drop, fortune) : drop);
}
b.setType(Material.AIR);
}
@ -103,7 +104,9 @@ public class ExplosivePickaxe extends SimpleSlimefunItem<BlockBreakHandler> impl
return true;
}
else return false;
else {
return false;
}
}
};
}

View File

@ -81,6 +81,10 @@ public class GoldPan extends SimpleSlimefunItem<ItemUseHandler> implements Recip
randomizer.add(new ItemStack(Material.AIR), 100 - randomizer.sumWeights());
}
}
public ItemStack getRandomOutput() {
return randomizer.getRandom();
}
@Override
public String getLabelLocalPath() {
@ -96,7 +100,7 @@ public class GoldPan extends SimpleSlimefunItem<ItemUseHandler> implements Recip
Block b = block.get();
if (b.getType() == getInput() && SlimefunPlugin.getProtectionManager().hasPermission(e.getPlayer(), b.getLocation(), ProtectableAction.BREAK_BLOCK)) {
ItemStack output = randomizer.getRandom();
ItemStack output = getRandomOutput();
b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, b.getType());
b.setType(Material.AIR);
@ -125,11 +129,11 @@ public class GoldPan extends SimpleSlimefunItem<ItemUseHandler> implements Recip
return recipes;
}
class GoldPanDrop extends ItemSetting<Integer> {
public class GoldPanDrop extends ItemSetting<Integer> {
private final ItemStack output;
public GoldPanDrop(String key, int defaultValue, ItemStack output) {
protected GoldPanDrop(String key, int defaultValue, ItemStack output) {
super(key, defaultValue);
this.output = output;

View File

@ -34,9 +34,9 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
*/
public class Category implements Keyed {
protected final List<SlimefunItem> items = new ArrayList<>();
protected final NamespacedKey key;
protected final ItemStack item;
protected final List<SlimefunItem> items;
protected final int tier;
/**
@ -73,8 +73,6 @@ public class Category implements Keyed {
meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
this.item.setItemMeta(meta);
this.items = new ArrayList<>();
this.tier = tier;
}
@ -105,6 +103,16 @@ public class Category implements Keyed {
items.add(item);
}
/**
* Removes the given {@link SlimefunItem} from this {@link Category}.
*
* @param item
* the {@link SlimefunItem} that should be removed from this {@link Category}
*/
public void remove(SlimefunItem item) {
items.remove(item);
}
/**
* This method returns a localized display item of this {@link Category}
* for the specified {@link Player}.

View File

@ -31,5 +31,5 @@ public enum ItemState {
* This {@link SlimefunItem} has fallen back to its vanilla behavior, because it is disabled and an instance of
* {@link VanillaItem}.
*/
VANILLA
VANILLA_FALLBACK
}

View File

@ -103,6 +103,7 @@ public class SlimefunItem implements Placeable {
public SlimefunItem(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) {
Validate.notNull(category, "'category' is not allowed to be null!");
Validate.notNull(item, "'item' is not allowed to be null!");
Validate.notNull(recipeType, "'recipeType' is not allowed to be null!");
this.category = category;
this.item = item;
@ -248,40 +249,32 @@ public class SlimefunItem implements Placeable {
*
* @return Whether this {@link SlimefunItem} is hidden.
*/
public boolean isHidden() {
public final boolean isHidden() {
return hidden;
}
public void setHidden(boolean hidden) {
this.hidden = hidden;
if (state == ItemState.ENABLED) {
if (hidden) {
category.remove(this);
}
else {
category.add(this);
}
}
}
/**
* This method returns whether this {@link SlimefunItem} was added by an addon.
*
* @return Whether this {@link SlimefunItem} was added by an addon.
*/
public boolean isAddonItem() {
public final boolean isAddonItem() {
return !(addon instanceof SlimefunPlugin);
}
/**
* This method returns the {@link SlimefunAddon} that registered this
* {@link SlimefunItem}. If this Item is from Slimefun itself, the current
* instance of {@link SlimefunPlugin} will be returned.
* Use an instanceof check or {@link SlimefunItem#isAddonItem()} to account for that.
*
* @return The {@link SlimefunAddon} that registered this {@link SlimefunItem}
*/
public SlimefunAddon getAddon() {
return addon;
}
public BlockTicker getBlockTicker() {
return blockTicker;
}
// We should maybe refactor this and move it to a subclass
public GeneratorTicker getEnergyTicker() {
return generatorTicker;
}
/**
* This method returns whether this {@link SlimefunItem} is disabled.
*
@ -296,6 +289,32 @@ public class SlimefunItem implements Placeable {
return state != ItemState.ENABLED;
}
/**
* This method returns the {@link SlimefunAddon} that registered this
* {@link SlimefunItem}. If this Item is from Slimefun itself, the current
* instance of {@link SlimefunPlugin} will be returned.
* Use an instanceof check or {@link SlimefunItem#isAddonItem()} to account for that.
*
* @return The {@link SlimefunAddon} that registered this {@link SlimefunItem}
*/
public SlimefunAddon getAddon() {
if (addon == null) {
error("getAddon() cannot be called before registering the item", new UnregisteredItemException(this));
return null;
}
return addon;
}
public BlockTicker getBlockTicker() {
return blockTicker;
}
// We should maybe refactor this and move it to a subclass
public GeneratorTicker getEnergyTicker() {
return generatorTicker;
}
/**
* This method registers this {@link SlimefunItem}.
* Always call this method after your {@link SlimefunItem} has been initialized.
@ -374,7 +393,7 @@ public class SlimefunItem implements Placeable {
loadItemHandlers();
}
else if (this instanceof VanillaItem) {
state = ItemState.VANILLA;
state = ItemState.VANILLA_FALLBACK;
}
else {
state = ItemState.DISABLED;
@ -382,7 +401,7 @@ public class SlimefunItem implements Placeable {
postRegister();
if (SlimefunPlugin.getRegistry().isAutoLoadingEnabled()) {
if (SlimefunPlugin.getRegistry().isAutoLoadingEnabled() && state == ItemState.ENABLED) {
info("Item was registered during runtime.");
load();
}
@ -436,11 +455,16 @@ public class SlimefunItem implements Placeable {
}
public void setRecipeType(RecipeType type) {
Validate.notNull(type, "'recipeType' is not allowed to be null!");
this.recipeType = type;
}
public void setCategory(Category category) {
Validate.notNull(category, "'category' is not allowed to be null!");
this.category.remove(this);
category.add(this);
this.category = category;
}