Brewery/src/com/dre/brewery/listeners/InventoryListener.java

503 lines
16 KiB
Java
Raw Normal View History

2013-05-09 21:47:58 +02:00
package com.dre.brewery.listeners;
import com.dre.brewery.BPlayer;
import com.dre.brewery.BRecipe;
import com.dre.brewery.Barrel;
import com.dre.brewery.Brew;
import com.dre.brewery.MCBarrel;
import com.dre.brewery.P;
import com.dre.brewery.integration.LogBlockBarrel;
import org.bukkit.Bukkit;
import org.bukkit.Material;
2019-08-17 21:00:15 +02:00
import org.bukkit.Sound;
import org.bukkit.SoundCategory;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.BrewingStand;
import org.bukkit.entity.HumanEntity;
2013-05-09 21:47:58 +02:00
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.BrewEvent;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.inventory.InventoryPickupItemEvent;
import org.bukkit.event.inventory.InventoryType;
2013-05-09 21:47:58 +02:00
import org.bukkit.inventory.BrewerInventory;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemFlag;
2013-05-09 21:47:58 +02:00
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.scheduler.BukkitRunnable;
2013-05-09 21:47:58 +02:00
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
2016-05-30 23:13:31 +02:00
import java.util.List;
import java.util.UUID;
2013-05-09 21:47:58 +02:00
/**
* Updated for 1.9 to replicate the "Brewing" process for distilling.
* Because of how metadata has changed, the brewer no longer triggers as previously described.
2016-04-23 17:45:01 +02:00
* So, I've added some event tracking and manual forcing of the brewing "animation" if the
* set of ingredients in the brewer can be distilled.
* Nothing here should interfere with vanilla brewing.
2016-04-23 17:45:01 +02:00
*
* @author ProgrammerDan (1.9 distillation update only)
*/
2013-05-09 21:47:58 +02:00
public class InventoryListener implements Listener {
2016-04-23 17:45:01 +02:00
/* === Recreating manually the prior BrewEvent behavior. === */
2016-05-27 19:31:05 +02:00
private HashSet<UUID> trackedBrewmen = new HashSet<>();
private HashMap<Block, Integer> trackedBrewers = new HashMap<>();
private static final int DISTILLTIME = 400;
2016-04-23 17:45:01 +02:00
/**
* Start tracking distillation for a person when they open the brewer window.
* @param event
*/
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBrewerOpen(InventoryOpenEvent event) {
if (!P.use1_9) return;
HumanEntity player = event.getPlayer();
Inventory inv = event.getInventory();
if (player == null || !(inv instanceof BrewerInventory)) return;
2016-04-23 17:45:01 +02:00
P.p.debugLog("Starting brew inventory tracking");
trackedBrewmen.add(player.getUniqueId());
}
2016-04-23 17:45:01 +02:00
/**
* Stop tracking distillation for a person when they close the brewer window.
* @param event
*/
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBrewerClose(InventoryCloseEvent event) {
if (!P.use1_9) return;
HumanEntity player = event.getPlayer();
Inventory inv = event.getInventory();
if (player == null || !(inv instanceof BrewerInventory)) return;
2016-04-23 17:45:01 +02:00
P.p.debugLog("Stopping brew inventory tracking");
trackedBrewmen.remove(player.getUniqueId());
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBrewerDrag(InventoryDragEvent event) {
if (!P.use1_9) return;
// Workaround the Drag event when only clicking a slot
if (event.getInventory() instanceof BrewerInventory) {
onBrewerClick(new InventoryClickEvent(event.getView(), InventoryType.SlotType.CONTAINER, 0, ClickType.LEFT, InventoryAction.PLACE_ALL));
}
}
/**
* Clicking can either start or stop the new brew distillation tracking.
* Note that server restart will halt any ongoing brewing processes and
* they will _not_ restart until a new click event.
2016-04-23 17:45:01 +02:00
*
* @param event the Click event.
*/
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBrewerClick(InventoryClickEvent event) {
if (!P.use1_9) return;
HumanEntity player = event.getWhoClicked();
Inventory inv = event.getInventory();
if (player == null || !(inv instanceof BrewerInventory)) return;
2016-04-23 17:45:01 +02:00
UUID puid = player.getUniqueId();
if (!trackedBrewmen.contains(puid)) return;
2016-04-23 17:45:01 +02:00
if (InventoryType.BREWING != inv.getType()) return;
2016-04-23 17:45:01 +02:00
if (event.getAction() == InventoryAction.NOTHING) return; // Ignore clicks that do nothing
BrewerInventory brewer = (BrewerInventory) inv;
final Block brewery = brewer.getHolder().getBlock();
2016-04-23 17:45:01 +02:00
// If we were already tracking the brewer, cancel any ongoing event due to the click.
Integer curTask = trackedBrewers.get(brewery);
if (curTask != null) {
Bukkit.getScheduler().cancelTask(curTask); // cancel prior
brewer.getHolder().setBrewingTime(0); // Fixes brewing continuing without fuel for normal potions
brewer.getHolder().update();
}
final int fuel = brewer.getHolder().getFuelLevel();
2016-04-23 17:45:01 +02:00
// Now check if we should bother to track it.
trackedBrewers.put(brewery, new BukkitRunnable() {
private int runTime = -1;
private int brewTime = -1;
@Override
public void run() {
BlockState now = brewery.getState();
if (now instanceof BrewingStand) {
BrewingStand stand = (BrewingStand) now;
if (brewTime == -1) { // only check at the beginning (and end) for distillables
switch (hasCustom(stand.getInventory())) {
case 1:
// Custom potion but not for distilling. Stop any brewing and cancel this task
if (stand.getBrewingTime() > 0) {
2018-10-31 22:25:32 +01:00
if (P.use1_11) {
// The trick below doesnt work in 1.11, but we dont need it anymore
// This should only happen with older Brews that have been made with the old Potion Color System
stand.setBrewingTime(Short.MAX_VALUE);
} else {
// Brewing time is sent and stored as short
// This sends a negative short value to the Client
// In the client the Brewer will look like it is not doing anything
stand.setBrewingTime(Short.MAX_VALUE << 1);
}
stand.setFuelLevel(fuel);
stand.update();
}
case 0:
// No custom potion, cancel and ignore
this.cancel();
trackedBrewers.remove(brewery);
P.p.debugLog("nothing to distill");
return;
default:
runTime = getLongestDistillTime(stand.getInventory());
brewTime = runTime;
2016-06-29 23:30:17 +02:00
P.p.debugLog("using brewtime: " + runTime);
2016-04-23 17:45:01 +02:00
}
}
brewTime--; // count down.
stand.setBrewingTime((int) ((float) brewTime / ((float) runTime / (float) DISTILLTIME)) + 1);
2016-04-23 17:45:01 +02:00
if (brewTime <= 1) { // Done!
stand.setBrewingTime(0);
stand.update();
2016-04-23 17:45:01 +02:00
BrewerInventory brewer = stand.getInventory();
if (!runDistill(brewer)) {
this.cancel();
trackedBrewers.remove(brewery);
P.p.debugLog("All done distilling");
} else {
brewTime = -1; // go again.
2016-04-23 17:45:01 +02:00
P.p.debugLog("Can distill more! Continuing.");
}
} else {
stand.update();
}
} else {
this.cancel();
trackedBrewers.remove(brewery);
P.p.debugLog("The block was replaced; not a brewing stand.");
}
}
}.runTaskTimer(P.p, 2L, 1L).getTaskId());
}
2016-04-23 17:45:01 +02:00
// Returns a Brew or null for every Slot in the BrewerInventory
private Brew[] getDistillContents(BrewerInventory inv) {
ItemStack item;
Brew[] contents = new Brew[3];
for (int slot = 0; slot < 3; slot++) {
item = inv.getItem(slot);
if (item != null) {
2016-06-16 22:13:21 +02:00
if (item.getType() == Material.POTION) {
if (item.hasItemMeta()) {
Brew pot = Brew.get(item);
if (pot != null && (!distill || pot.canDistill())) { // need at least one distillable potion.
return true;
}
}
}
}
}
return customFound;
}
2016-04-23 17:45:01 +02:00
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
2013-05-09 21:47:58 +02:00
public void onBrew(BrewEvent event) {
if (P.use1_9) {
if (hasCustom(event.getContents()) != 0) {
event.setCancelled(true);
}
return;
}
2016-04-23 17:45:01 +02:00
if (runDistill(event.getContents())) {
event.setCancelled(true);
}
}
private boolean runDistill(BrewerInventory inv) {
2013-05-09 21:47:58 +02:00
boolean custom = false;
2016-06-16 22:13:21 +02:00
Boolean[] contents = new Boolean[3];
while (slot < 3) {
item = inv.getItem(slot);
contents[slot] = false;
if (item != null) {
if (item.getType() == Material.POTION) {
if (item.hasItemMeta()) {
Brew brew = Brew.get(item);
if (brew != null) {
// has custom potion in "slot"
if (brew.canDistill()) {
// is further distillable
contents[slot] = true;
custom = true;
}
}
}
}
2013-05-09 21:47:58 +02:00
}
}
if (custom) {
Brew.distillAll(inv, contents);
2016-04-23 17:45:01 +02:00
return true;
2013-05-09 21:47:58 +02:00
}
2016-04-23 17:45:01 +02:00
return false;
2013-05-09 21:47:58 +02:00
}
private int getLongestDistillTime(BrewerInventory inv) {
int bestTime = 0;
2016-06-29 23:30:17 +02:00
int time;
Brew[] contents = getDistillContents(inv);
for (int slot = 0; slot < 3; slot++) {
if (contents[slot] == null) continue;
time = contents[slot].getDistillTimeNextRun();
if (time == 0) {
// Undefined Potion needs 40 seconds
time = 800;
}
if (time > bestTime) {
bestTime = time;
}
}
if (bestTime > 0) {
return bestTime;
}
return 800;
}
2016-05-18 22:31:32 +02:00
// Clicked a Brew somewhere, do some updating
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = false)
public void onInventoryClickLow(InventoryClickEvent event) {
if (event.getCurrentItem() != null && event.getCurrentItem().getType().equals(Material.POTION)) {
ItemStack item = event.getCurrentItem();
if (item.hasItemMeta()) {
PotionMeta potion = ((PotionMeta) item.getItemMeta());
2016-05-18 22:31:32 +02:00
Brew brew = Brew.get(potion);
if (brew != null) {
// convert potions from 1.8 to 1.9 for color and to remove effect descriptions
if (P.use1_9 && !potion.hasItemFlag(ItemFlag.HIDE_POTION_EFFECTS)) {
BRecipe recipe = brew.getCurrentRecipe();
if (recipe != null) {
2016-06-28 16:31:57 +02:00
Brew.removeEffects(potion);
2019-03-05 20:55:52 +01:00
Brew.PotionColor.fromString(recipe.getColor()).colorBrew(potion, item, brew.canDistill());
item.setItemMeta(potion);
}
}
2016-06-16 22:13:21 +02:00
P.p.log(brew.toString());
2016-06-17 00:04:41 +02:00
P.p.log(potion.getLore().get(0).replaceAll("§", ""));
P.p.log("similar to beispiel? " + BRecipe.get("Beispiel").createBrew(10).isSimilar(brew));
2016-06-16 22:13:21 +02:00
//brew.touch();
2016-05-28 18:47:51 +02:00
2016-06-16 22:13:21 +02:00
/*try {
2016-06-13 23:26:10 +02:00
DataInputStream in = new DataInputStream(new Base91DecoderStream(new LoreLoadStream(potion)));
brew.testLoad(in);
2016-06-16 22:13:21 +02:00
*//*if (in.readByte() == 27 && in.skip(48) > 0) {
in.mark(100);
if (in.readUTF().equals("TESTHalloª∆Ω") && in.readInt() == 34834 && in.skip(4) > 0 && in.readLong() == Long.MAX_VALUE) {
in.reset();
if (in.readUTF().equals("TESTHalloª∆Ω")) {
P.p.log("true");
} else {
P.p.log("false3");
}
} else {
P.p.log("false2");
}
2016-05-28 18:47:51 +02:00
} else {
P.p.log("false1");
2016-06-16 22:13:21 +02:00
}*//*
2016-05-28 18:47:51 +02:00
in.close();
2016-06-13 23:26:10 +02:00
} catch (IllegalArgumentException argExc) {
P.p.log("No Data in Lore");
2016-05-28 18:47:51 +02:00
try {
2016-05-28 18:47:51 +02:00
2016-06-13 23:26:10 +02:00
DataOutputStream out = new DataOutputStream(new Base91EncoderStream(new LoreSaveStream(potion, 2)));
brew.testStore(out);
2016-05-28 18:47:51 +02:00
2016-06-16 22:13:21 +02:00
*//*out.writeByte(27);
out.writeLong(1111); //skip
out.writeLong(1111); //skip
out.writeLong(1111); //skip
out.writeLong(1111); //skip
out.writeLong(1111); //skip
out.writeLong(1111); //skip
out.writeUTF("TESTHalloª∆Ω");
out.writeInt(34834);
out.writeInt(6436); //skip
2016-06-16 22:13:21 +02:00
out.writeLong(Long.MAX_VALUE);*//*
2016-05-28 18:47:51 +02:00
out.close();
2016-06-16 22:13:21 +02:00
*//*StringBuilder b = new StringBuilder();
2016-05-30 23:13:31 +02:00
for (char c : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!$%&()*+,-./:;<=>?@[]^_`{|}~\"".toCharArray()) {
b.append('§').append(c);
}
List<String> lore = potion.getLore();
lore.add(b.toString());
2016-06-16 22:13:21 +02:00
potion.setLore(lore);*//*
item.setItemMeta(potion);
} catch (IOException h) {
h.printStackTrace();
}
2016-05-28 18:47:51 +02:00
2016-06-13 23:26:10 +02:00
} catch (IOException e) {
e.printStackTrace();
2016-06-16 22:13:21 +02:00
}*/
}
}
}
}
// convert to non colored Lore when taking out of Barrel/Brewer
2014-04-09 00:35:08 +02:00
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onInventoryClick(InventoryClickEvent event) {
if (event.getInventory().getType() == InventoryType.BREWING) {
if (event.getSlot() > 2) {
return;
}
2019-08-18 22:45:12 +02:00
} else if (!(event.getInventory().getHolder() instanceof Barrel) && !(P.use1_14 && event.getInventory().getHolder() instanceof org.bukkit.block.Barrel)) {
2013-08-30 21:19:49 +02:00
return;
}
ItemStack item = event.getCurrentItem();
if (item != null) {
2014-05-19 15:17:55 +02:00
if (item.getType() == Material.POTION) {
if (item.hasItemMeta()) {
PotionMeta meta = (PotionMeta) item.getItemMeta();
Brew brew = Brew.get(meta);
if (brew != null) {
2013-08-30 21:19:49 +02:00
if (Brew.hasColorLore(meta)) {
brew.convertLore(meta, false);
item.setItemMeta(meta);
}
}
}
}
}
}
2016-04-23 17:45:01 +02:00
// Check if the player tries to add more than the allowed amount of brews into an mc-barrel
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onInventoryClickMCBarrel(InventoryClickEvent event) {
if (!P.use1_14) return;
if (event.getInventory().getType() != InventoryType.BARREL) return;
Inventory inv = event.getInventory();
for (MCBarrel barrel : MCBarrel.openBarrels) {
if (barrel.getInventory().equals(inv)) {
barrel.clickInv(event);
return;
}
}
MCBarrel barrel = new MCBarrel(inv);
MCBarrel.openBarrels.add(barrel);
barrel.clickInv(event);
}
//public static boolean opening = false;
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
2019-08-17 12:07:57 +02:00
public void onInventoryOpen(InventoryOpenEvent event) {
if (!P.use1_14) return;
/*Barrel x = null;
if (event.getInventory().getHolder() instanceof Barrel) {
x = ((Barrel) event.getInventory().getHolder());
}
if (!opening) {
opening = true;
Barrel finalBarrel = x;
P.p.getServer().getScheduler().scheduleSyncDelayedTask(P.p, () -> {finalBarrel.remove(null, null); opening = false;}, 100);
}*/
// Check for MC Barrel
2019-08-17 12:07:57 +02:00
if (event.getInventory().getType() == InventoryType.BARREL) {
Inventory inv = event.getInventory();
for (MCBarrel barrel : MCBarrel.openBarrels) {
if (barrel.getInventory().equals(inv)) {
barrel.open();
return;
2019-08-17 12:07:57 +02:00
}
}
MCBarrel barrel = new MCBarrel(inv);
MCBarrel.openBarrels.add(barrel);
barrel.open();
2019-08-17 12:07:57 +02:00
}
}
// block the pickup of items where getPickupDelay is > 1000 (puke)
2014-02-16 17:11:02 +01:00
@EventHandler(ignoreCancelled = true)
public void onInventoryPickupItem(InventoryPickupItemEvent event){
if (event.getItem().getPickupDelay() > 1000 && event.getItem().getItemStack().getType() == BPlayer.pukeItem) {
event.setCancelled(true);
}
}
2014-04-09 00:35:08 +02:00
@EventHandler
public void onInventoryClose(InventoryCloseEvent event) {
if (P.p.useLB) {
2015-01-10 00:15:13 +01:00
if (event.getInventory().getHolder() instanceof Barrel) {
try {
LogBlockBarrel.closeBarrel(event.getPlayer(), event.getInventory());
} catch (Exception e) {
P.p.errorLog("Failed to Log Barrel to LogBlock!");
P.p.errorLog("Brewery was tested with version 1.94 of LogBlock!");
2015-01-10 00:15:13 +01:00
e.printStackTrace();
2014-04-09 00:35:08 +02:00
}
}
}
if (!P.use1_14) return;
2019-08-17 21:00:15 +02:00
// Barrel Closing Sound
if (event.getInventory().getHolder() instanceof Barrel) {
Barrel barrel = ((Barrel) event.getInventory().getHolder());
float randPitch = (float) (Math.random() * 0.1);
if (barrel.isLarge()) {
barrel.getSpigot().getWorld().playSound(barrel.getSpigot().getLocation(), Sound.BLOCK_BARREL_CLOSE, SoundCategory.BLOCKS, 0.5f, 0.5f + randPitch);
barrel.getSpigot().getWorld().playSound(barrel.getSpigot().getLocation(), Sound.ITEM_BUCKET_EMPTY, SoundCategory.BLOCKS, 0.2f, 0.6f + randPitch);
} else {
barrel.getSpigot().getWorld().playSound(barrel.getSpigot().getLocation(), Sound.BLOCK_BARREL_CLOSE, SoundCategory.BLOCKS, 0.5f, 0.8f + randPitch);
}
}
// Check for MC Barrel
if (event.getInventory().getType() == InventoryType.BARREL) {
Inventory inv = event.getInventory();
for (Iterator<MCBarrel> iter = MCBarrel.openBarrels.iterator(); iter.hasNext(); ) {
MCBarrel barrel = iter.next();
if (barrel.getInventory().equals(inv)) {
barrel.close();
if (inv.getViewers().size() == 1) {
// Last viewer, remove Barrel from List of open Barrels
iter.remove();
}
return;
}
}
new MCBarrel(inv).close();
}
2014-04-09 00:35:08 +02:00
}
2013-05-09 21:47:58 +02:00
}