feat: add RedstoneJukebox event listener to control jukebox playback with redstone power

This commit is contained in:
Your Name
2025-03-15 13:12:55 +01:00
parent dd4a653f93
commit e6dda78955
4 changed files with 159 additions and 422 deletions

View File

@@ -1,7 +1,7 @@
ALLGEMEIN: recipes die custom items beinhalten werden nicht im crafting angezeigt (allgm. Bukkit problem)
INFO: CustomItemIcon count: 22
BUG: Autocrafter nicht von seite möglich
IDEA: schere verschiedene versionen pferde/mule/cats/schafe/Axolotl/tropical etc?
TO RELEASE: waterbottle + sponge = empty bottle
TO RELEASE: waterbottle + sponge = empty bottle -> Warum nochmal?
TO RELEASE: Autocrafter

View File

@@ -487,6 +487,7 @@ public class App extends JavaPlugin {
pM.registerEvents(new ArmoredElytra(), this);
pM.registerEvents(new ShulkerPreview(), this);
pM.registerEvents(new BetterTotems(), this);
pM.registerEvents(new RedstoneJukebox(), this);
getCommand("test").setExecutor(new EnvironmentExCommands());
getCommand("y").setExecutor(new EnvironmentExCommands());
getCommand("n").setExecutor(new EnvironmentExCommands());

View File

@@ -1,456 +1,140 @@
package de.hessj.environmentex;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.Chest;
import org.bukkit.block.Hopper;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Dispenser;
import org.bukkit.block.data.Directional;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Item;
import org.bukkit.entity.ItemFrame;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.inventory.InventoryMoveItemEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.event.block.BlockDispenseEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Recipe;
import org.bukkit.inventory.RecipeChoice;
import org.bukkit.inventory.ShapedRecipe;
import org.bukkit.inventory.ShapelessRecipe;
import org.bukkit.inventory.RecipeChoice.MaterialChoice;
import org.bukkit.inventory.meta.FireworkMeta;
import org.bukkit.util.Vector;
public class AutoCrafter implements Listener {
@EventHandler
public void onHopperTick(InventoryMoveItemEvent e) {
if (e.getDestination().getHolder() instanceof Hopper) {
Block hopper = ((Hopper) e.getDestination().getHolder()).getBlock();
Directional d = (Directional) hopper.getState().getBlockData();
World w = hopper.getWorld();
Block workbench = null;
switch (d.getFacing()) {
case DOWN:
workbench = w.getBlockAt(hopper.getLocation().getBlockX(), hopper.getLocation().getBlockY() - 1,
hopper.getLocation().getBlockZ());
break;
case EAST:
workbench = w.getBlockAt(hopper.getLocation().getBlockX() + 1, hopper.getLocation().getBlockY(),
hopper.getLocation().getBlockZ());
break;
case NORTH:
workbench = w.getBlockAt(hopper.getLocation().getBlockX(), hopper.getLocation().getBlockY(),
hopper.getLocation().getBlockZ() - 1);
break;
case SOUTH:
workbench = w.getBlockAt(hopper.getLocation().getBlockX(), hopper.getLocation().getBlockY(),
hopper.getLocation().getBlockZ() + 1);
break;
case WEST:
workbench = w.getBlockAt(hopper.getLocation().getBlockX() - 1, hopper.getLocation().getBlockY(),
hopper.getLocation().getBlockZ());
break;
default:
break;
}
if (workbench != null && workbench.getType() == Material.CRAFTING_TABLE) {
e.setCancelled(true);
if ((w.getBlockAt(workbench.getLocation().getBlockX(), workbench.getLocation().getBlockY() - 1,
workbench.getLocation().getBlockZ()).getType() == Material.HOPPER)) {
ItemStack desiredItem = null;
for (Entity ent : w.getNearbyEntities(workbench.getLocation(), 2, 2, 2)) {
if (ent instanceof ItemFrame) {
desiredItem = ((ItemFrame) ent).getItem();
break;
}
}
if (desiredItem != null) {
Location chestLoc = workbench.getLocation();
chestLoc = new Location(chestLoc.getWorld(), chestLoc.getX(), chestLoc.getY() + 2,
chestLoc.getZ());
Chest input = (Chest) w.getBlockAt(chestLoc).getState();
Hopper output = (Hopper) w
.getBlockAt(workbench.getLocation().getBlockX(),
workbench.getLocation().getBlockY() - 1, workbench.getLocation().getBlockZ())
.getState();
Recipe r = (Recipe) Bukkit.getServer().getRecipe(desiredItem.getType().getKey());
final ItemStack dItem = desiredItem;
Bukkit.getScheduler().scheduleSyncDelayedTask(App.main, new Runnable() {
@Override
public void run() {
HashMap<RecipeChoice, Integer> ingredients = new HashMap<RecipeChoice, Integer>();
HashMap<Material, Integer> helper = new HashMap<Material, Integer>();
int reqItemsCount = 0;
if (r instanceof ShapelessRecipe) {
ShapelessRecipe slr = (ShapelessRecipe) r;
for (RecipeChoice rC : slr.getChoiceList()) {
if (rC != null) {
if (ingredients.keySet().contains(rC)) {
ingredients.put(rC, ingredients.get(rC) + 1);
} else {
ingredients.put(rC, 1);
}
}
}
for (Map.Entry<RecipeChoice, Integer> entry : ingredients.entrySet()) {
RecipeChoice rrC = entry.getKey();
Integer amount = entry.getValue();
MaterialChoice mmC = (MaterialChoice) rrC;
for (Material maat : mmC.getChoices()) {
ItemStack is = new ItemStack(maat);
if (((InventoryHolder) input).getInventory().containsAtLeast(is, amount)) {
reqItemsCount++;
helper.put(maat, amount);
break;
} else {
}
}
}
Integer bottleCount = 0;
if (reqItemsCount == ingredients.size()) {
if (output.getInventory().firstEmpty() == -1) {
return;
}
for (Map.Entry<Material, Integer> entry : helper.entrySet()) {
ItemStack is = new ItemStack(entry.getKey(), entry.getValue());
if (isInBottle(is)) {
bottleCount = entry.getValue();
}
((InventoryHolder) input).getInventory().removeItem(is);
}
final Integer fBottleCount = bottleCount;
Bukkit.getScheduler().runTaskLater(App.main, new Runnable() {
@Override
public void run() {
Boolean madeItem = false;
if (output.getInventory().firstEmpty() != -1) {
for(int i = 0; i < slr.getResult().getAmount(); i++){
output.getInventory().addItem(dItem);
}
madeItem = true;
}
if (output.getInventory().firstEmpty() != -1 && fBottleCount != 0) {// wenn
// dItem
// in
// bottle
// add
// bottle
output.getInventory().addItem(
new ItemStack(Material.GLASS_BOTTLE, fBottleCount));
} else if (output.getInventory().firstEmpty() == -1 && madeItem == true
&& fBottleCount != 0) {// wenn dItem in bottle add bottle
output.getWorld().dropItemNaturally(output.getLocation(),
new ItemStack(Material.GLASS_BOTTLE, fBottleCount));
}
}
}, 5L);
}
reqItemsCount = 0;
helper = new HashMap<Material, Integer>();
ingredients = new HashMap<RecipeChoice, Integer>();
bottleCount = 0;
}
else if (r instanceof ShapedRecipe) {
ShapedRecipe sr = (ShapedRecipe) r;
for (RecipeChoice rC : sr.getChoiceMap().values()) {
if (rC != null) {
if (ingredients.keySet().contains(rC)) {
ingredients.put(rC, ingredients.get(rC) + 1);
} else {
ingredients.put(rC, 1);
}
}
}
for (Map.Entry<RecipeChoice, Integer> entry : ingredients.entrySet()) {
RecipeChoice rrC = entry.getKey();
Integer amount = entry.getValue();
MaterialChoice mmC = (MaterialChoice) rrC;
for (Material maat : mmC.getChoices()) {
ItemStack is = new ItemStack(maat);
if (((InventoryHolder) input).getInventory().containsAtLeast(is, amount)) {
reqItemsCount++;
helper.put(maat, amount);
break;
} else {
}
}
}
Integer bottleCount = 0;
if (reqItemsCount == ingredients.size()) {
if (output.getInventory().firstEmpty() == -1) {
return;
}
for (Map.Entry<Material, Integer> entry : helper.entrySet()) {
ItemStack is = new ItemStack(entry.getKey(), entry.getValue());
if (isInBottle(is)) {
bottleCount = entry.getValue();
}
((InventoryHolder) input).getInventory().removeItem(is);
}
final Integer fBottleCount = bottleCount;
Bukkit.getScheduler().runTaskLater(App.main, new Runnable() {
@Override
public void run() {
Boolean madeItem = false;
if (output.getInventory().firstEmpty() != -1) {
for(int i = 0; i < sr.getResult().getAmount(); i++){
output.getInventory().addItem(dItem);
}
madeItem = true;
}
if (output.getInventory().firstEmpty() != -1 && fBottleCount != 0) {// wenn
// dItem
// in
// bottle
// add
// bottle
output.getInventory().addItem(
new ItemStack(Material.GLASS_BOTTLE, fBottleCount));
} else if (output.getInventory().firstEmpty() == -1 && madeItem == true
&& fBottleCount != 0) {// wenn dItem in bottle add bottle
output.getWorld().dropItemNaturally(output.getLocation(),
new ItemStack(Material.GLASS_BOTTLE, fBottleCount));
}
}
}, 5L);
}
reqItemsCount = 0;
helper = new HashMap<Material, Integer>();
ingredients = new HashMap<RecipeChoice, Integer>();
bottleCount = 0;
}
else {
if (r != null && r.getResult().getType() != Material.FIREWORK_ROCKET) {
App.main.log("NOT CRAFTABLE!!!!!!!!!!!" + r.getResult());
}
else if (r != null && r.getResult().getType() == Material.FIREWORK_ROCKET) {
ItemStack firework = dItem;
FireworkMeta metaData = (FireworkMeta) firework.getItemMeta();
Integer duration = metaData.getPower();
if (((InventoryHolder) input).getInventory()
.containsAtLeast(new ItemStack(Material.PAPER), 1)
&& ((InventoryHolder) input).getInventory()
.containsAtLeast(new ItemStack(Material.GUNPOWDER), duration)) {
helper.put(Material.PAPER, 1);
helper.put(Material.GUNPOWDER, duration);
}
if (helper.size() == 2) {
if (output.getInventory().firstEmpty() == -1) {
return;
}
for (Map.Entry<Material, Integer> entry : helper.entrySet()) {
ItemStack is = new ItemStack(entry.getKey(), entry.getValue());
((InventoryHolder) input).getInventory().removeItem(is);
}
Bukkit.getScheduler().runTaskLater(App.main, new Runnable() {
@Override
public void run() {
if (output.getInventory().firstEmpty() != -1) {
output.getInventory().addItem(dItem);
}
if (output.getInventory().firstEmpty() != -1) {
output.getInventory().addItem(dItem);
}
if (output.getInventory().firstEmpty() != -1) {
output.getInventory().addItem(dItem);
}
}
}, 5L);
}
reqItemsCount = 0;
helper = new HashMap<Material, Integer>();
}
}
}
}, 5L);
}
}
private Recipe findRecipe(Material output) {
for (Recipe recipe : Bukkit.getServer().getRecipesFor(new ItemStack(output))) {
if (recipe.getResult().getType() == output) {
return recipe;
}
}
}
private Boolean isInBottle(ItemStack is) {
if (is.getType() == Material.HONEY_BOTTLE) {
return true;
}
return false;
return null;
}
@EventHandler
public void onInteract(PlayerInteractEvent e) {
if (e.getAction() != Action.RIGHT_CLICK_BLOCK) {
private void onThrow(BlockDispenseEvent event) {
if (event.getBlock().getType() != Material.DISPENSER) {
return;
}
if (e.getPlayer().isSneaking() == true
&& e.getPlayer().getInventory().getItemInMainHand().getType() != Material.AIR
&& e.getPlayer().getInventory().getItemInMainHand().getType().isBlock() == true) {
Dispenser dispenser = (Dispenser) event.getBlock().getState();
BlockFace facing = ((Directional) dispenser.getBlockData()).getFacing();
Inventory tempInventory = dispenser.getInventory();
tempInventory.addItem(event.getItem());
Collection<ItemFrame> frames = event.getBlock().getLocation().getNearbyEntitiesByType(ItemFrame.class, 1.5);
if (frames.toArray().length == 0)
return;
for (ItemFrame frame : frames) {
if (frame.getItem().getType() == Material.AIR)
return;
event.setCancelled(true);
String outputItemName = frame.getItem().getType().name();
Recipe recipe = findRecipe(Material.matchMaterial(outputItemName));
if (recipe == null) {
return;
}
// Map to store the required materials and their counts
Map<Material, Integer> required = new HashMap<>();
// Collect required materials from the recipe
if (recipe instanceof ShapedRecipe) {
ShapedRecipe shapedRecipe = (ShapedRecipe) recipe;
shapedRecipe.getIngredientMap().values().forEach(item -> {
if (item != null) {
required.put(item.getType(), required.getOrDefault(item.getType(), 0) + 1);
}
});
} else if (recipe instanceof ShapelessRecipe) {
ShapelessRecipe shapelessRecipe = (ShapelessRecipe) recipe;
shapelessRecipe.getIngredientList().forEach(item -> {
required.put(item.getType(), required.getOrDefault(item.getType(), 0) + 1);
});
}
// Check if dispenser contains the required materials
if (!hasRequiredMaterials(tempInventory, required)) {
App.main.log("nut enuff");
return;
}
// Remove the required items from the dispenser inventory
for (Map.Entry<Material, Integer> entry : required.entrySet()) {
removeMaterialFromInventory(dispenser.getInventory(), entry.getKey(), entry.getValue());
}
// Drop the output item
Item droppedItem = event.getBlock().getWorld().dropItem(event.getBlock().getLocation().add(0.5, 0.5, 0.5),
new ItemStack(Material.DIAMOND));
Vector velocity = new Vector(facing.getModX(), facing.getModY(), facing.getModZ()).multiply(0.3); // Speed
droppedItem.setVelocity(velocity);
}
if (e.getPlayer().isSneaking() == true
&& e.getPlayer().getInventory().getItemInOffHand().getType() != Material.AIR
&& e.getPlayer().getInventory().getItemInOffHand().getType().isBlock() == true) {
return;
}
// Method to check if the dispenser contains enough materials
private boolean hasRequiredMaterials(Inventory inventory, Map<Material, Integer> required) {
// Go through each required material and check if there's enough
for (Map.Entry<Material, Integer> entry : required.entrySet()) {
int materialCount = countMaterialInInventory(inventory, entry.getKey());
if (materialCount < entry.getValue()) {
// Log the shortage for debugging purposes
App.main.log("Not enough " + entry.getKey() + ": required " + entry.getValue() + " but found " + materialCount);
return false;
}
}
return true;
}
Block b = e.getClickedBlock();
if (b.getType() == Material.HOPPER) {
// Method to count materials in the inventory
private int countMaterialInInventory(Inventory inventory, Material material) {
int count = 0;
for (int i = 0; i < inventory.getSize(); i++) {
if (inventory.getItem(i) != null && inventory.getItem(i).getType() == material) {
count += inventory.getItem(i).getAmount();
}
}
return count;
}
Block workbench = b.getWorld().getBlockAt(b.getLocation().getBlockX(), b.getLocation().getBlockY() - 1,
b.getLocation().getBlockZ());
Block output = b.getWorld().getBlockAt(b.getLocation().getBlockX(), b.getLocation().getBlockY() - 2,
b.getLocation().getBlockZ());
Block workbench1 = b.getWorld().getBlockAt(b.getLocation().getBlockX(), b.getLocation().getBlockY() + 1,
b.getLocation().getBlockZ());
Block input = b.getWorld().getBlockAt(b.getLocation().getBlockX(), b.getLocation().getBlockY() + 2,
b.getLocation().getBlockZ());
Block input1 = b.getWorld().getBlockAt(b.getLocation().getBlockX() + 1,
b.getLocation().getBlockY(), b.getLocation().getBlockZ());
Block input2 = b.getWorld().getBlockAt(b.getLocation().getBlockX() - 1,
b.getLocation().getBlockY(), b.getLocation().getBlockZ());
Block input3 = b.getWorld().getBlockAt(b.getLocation().getBlockX(),
b.getLocation().getBlockY(), b.getLocation().getBlockZ() + 1);
Block input4 = b.getWorld().getBlockAt(b.getLocation().getBlockX(),
b.getLocation().getBlockY(), b.getLocation().getBlockZ() - 1);
boolean wb = false;
for (Entity ent : workbench.getWorld().getNearbyEntities(workbench.getLocation(), 2, 2, 2)) {
if (ent instanceof ItemFrame) {
wb = true;
// Method to remove specific material from the inventory
private void removeMaterialFromInventory(Inventory inventory, Material material, int amount) {
for (int i = 0; i < inventory.getSize(); i++) {
if (inventory.getItem(i) != null && inventory.getItem(i).getType() == material) {
int currentAmount = inventory.getItem(i).getAmount();
if (currentAmount <= amount) {
amount -= currentAmount;
inventory.clear(i); // Remove all of this item
} else {
inventory.getItem(i).setAmount(currentAmount - amount);
break; // Stop once we've removed the required amount
}
if (amount <= 0) {
break;
}
}
boolean wb1 = false;
for (Entity ent : workbench1.getWorld().getNearbyEntities(workbench1.getLocation(), 2, 2, 2)) {
if (ent instanceof ItemFrame) {
wb1 = true;
break;
}
}
if (workbench.getType() == Material.CRAFTING_TABLE && output.getType() == Material.HOPPER && wb == true
|| workbench1.getType() == Material.CRAFTING_TABLE && input.getType() == Material.HOPPER
&& wb1 == true) {
e.setCancelled(true);
}
if (e.getClickedBlock().getType() == Material.HOPPER && (input1.getType() == Material.CRAFTING_TABLE
|| input2.getType() == Material.CRAFTING_TABLE || input3.getType() == Material.CRAFTING_TABLE
|| input4.getType() == Material.CRAFTING_TABLE)) {
boolean isAttached = false;
for (Entity ent : input1.getWorld().getNearbyEntities(workbench1.getLocation(), 2, 2, 2)) {
if (ent instanceof ItemFrame) {
isAttached = true;
break;
}
}
for (Entity ent : input2.getWorld().getNearbyEntities(workbench1.getLocation(), 2, 2, 2)) {
if (ent instanceof ItemFrame) {
isAttached = true;
break;
}
}
for (Entity ent : input3.getWorld().getNearbyEntities(workbench1.getLocation(), 2, 2, 2)) {
if (ent instanceof ItemFrame) {
isAttached = true;
break;
}
}
for (Entity ent : input4.getWorld().getNearbyEntities(workbench1.getLocation(), 2, 2, 2)) {
if (ent instanceof ItemFrame) {
isAttached = true;
break;
}
}
if (isAttached) {
e.setCancelled(true);
}
}
}
}
}

View File

@@ -0,0 +1,52 @@
package de.hessj.environmentex;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.Jukebox;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockRedstoneEvent;
public class RedstoneJukebox implements Listener {
@EventHandler
public void onRedstonePower(BlockRedstoneEvent event) {
Block block = event.getBlock();
if (block == null || getNearbyJukebox(block) == null) {
return;
}
Jukebox jukebox = (Jukebox) (block.getType() == Material.JUKEBOX ? block.getState()
: getNearbyJukebox(block).getState());
if (event.getNewCurrent() > 0) {
if (!jukebox.isPlaying() && jukebox.hasRecord()) {
jukebox.startPlaying();
} else if (jukebox.isPlaying() && jukebox.hasRecord()) {
jukebox.stopPlaying();
}
}
}
private Block getNearbyJukebox(Block block) {
Block[] distantNeighbors = {
block.getRelative(2, 0, 0),
block.getRelative(-2, 0, 0),
block.getRelative(0, 0, 2),
block.getRelative(0, 0, -2),
block.getRelative(0, 2, 0),
block.getRelative(0, -2, 0)
};
for (Block neighbor : distantNeighbors) {
if (neighbor.getType() == Material.JUKEBOX) {
Block between = block.getRelative((neighbor.getX() - block.getX()) / 2,
(neighbor.getY() - block.getY()) / 2, (neighbor.getZ() - block.getZ()) / 2);
if (between.getType() == Material.AIR) {
return neighbor;
}
}
}
return null;
}
}