Brewery/src/com/dre/brewery/BCauldron.java

370 lines
11 KiB
Java
Raw Normal View History

package com.dre.brewery;
2016-07-09 00:01:31 +02:00
import com.dre.brewery.api.events.IngedientAddEvent;
import com.dre.brewery.recipe.BCauldronRecipe;
import com.dre.brewery.recipe.RecipeItem;
2019-10-16 20:07:09 +02:00
import com.dre.brewery.utility.BUtil;
import com.dre.brewery.utility.LegacyUtil;
import org.bukkit.Effect;
import org.bukkit.Material;
import org.bukkit.block.Block;
2013-04-28 23:57:41 +02:00
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Levelled;
2013-04-30 21:41:16 +02:00
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
2019-10-16 17:21:04 +02:00
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
2019-11-08 16:22:58 +01:00
import org.jetbrains.annotations.Nullable;
2019-11-08 16:22:58 +01:00
import java.util.HashMap;
2019-10-16 17:21:04 +02:00
import java.util.HashSet;
2019-11-08 16:22:58 +01:00
import java.util.Map;
2019-10-16 17:21:04 +02:00
import java.util.Set;
import java.util.UUID;
public class BCauldron {
public static final byte EMPTY = 0, SOME = 1, FULL = 2;
private static Set<UUID> plInteracted = new HashSet<>(); // Interact Event helper
2019-11-08 16:22:58 +01:00
public static Map<Block, BCauldron> bcauldrons = new HashMap<>(); // All active cauldrons. Mapped to their block for fast retrieve
2013-09-04 23:32:09 +02:00
private BIngredients ingredients = new BIngredients();
2016-07-09 00:01:31 +02:00
private final Block block;
private int state = 0;
private boolean changed = false;
2016-07-09 00:01:31 +02:00
public BCauldron(Block block) {
this.block = block;
}
// loading from file
public BCauldron(Block block, BIngredients ingredients, int state) {
2013-04-30 21:41:16 +02:00
this.block = block;
this.state = state;
this.ingredients = ingredients;
}
public void onUpdate() {
// Check if fire still alive
if (!BUtil.isChunkLoaded(block) || LegacyUtil.isFireForCauldron(block.getRelative(BlockFace.DOWN))) {
// add a minute to cooking time
2013-04-28 23:57:41 +02:00
state++;
if (changed) {
ingredients = ingredients.copy();
changed = false;
2013-09-04 23:32:09 +02:00
}
2013-04-28 23:57:41 +02:00
}
}
// add an ingredient to the cauldron
public void add(ItemStack ingredient, RecipeItem rItem) {
2016-07-09 00:01:31 +02:00
if (ingredient == null || ingredient.getType() == Material.AIR) return;
if (changed) {
ingredients = ingredients.copy();
changed = false;
2013-09-04 23:32:09 +02:00
}
ingredients.add(ingredient, rItem);
block.getWorld().playEffect(block.getLocation(), Effect.EXTINGUISH, 0);
if (state > 0) {
state--;
}
}
/**
* Get the Block that this BCauldron represents
*/
public Block getBlock() {
return block;
}
/**
* Get the State (Time in Minutes) that this Cauldron currently has
*/
public int getState() {
return state;
}
2013-07-27 17:31:42 +02:00
// get cauldron by Block
2019-11-08 16:22:58 +01:00
@Nullable
2013-07-27 17:31:42 +02:00
public static BCauldron get(Block block) {
2019-11-08 16:22:58 +01:00
return bcauldrons.get(block);
2013-07-27 17:31:42 +02:00
}
// get cauldron from block and add given ingredient
2016-07-09 00:01:31 +02:00
// Calls the IngredientAddEvent and may be cancelled or changed
public static boolean ingredientAdd(Block block, ItemStack ingredient, Player player) {
// if not empty
if (LegacyUtil.getFillLevel(block) != EMPTY) {
2016-07-09 00:01:31 +02:00
if (!BCauldronRecipe.acceptedMaterials.contains(ingredient.getType()) && !ingredient.hasItemMeta()) {
// Extremely fast way to check for most items
return false;
}
// If the Item is on the list, or customized, we have to do more checks
RecipeItem rItem = RecipeItem.getMatchingRecipeItem(ingredient, false);
if (rItem == null) {
return false;
}
2019-11-08 16:22:58 +01:00
BCauldron bcauldron = get(block);
if (bcauldron == null) {
bcauldron = new BCauldron(block);
BCauldron.bcauldrons.put(block, bcauldron);
2019-11-08 16:22:58 +01:00
}
IngedientAddEvent event = new IngedientAddEvent(player, block, bcauldron, ingredient.clone(), rItem);
2016-07-09 00:01:31 +02:00
P.p.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
bcauldron.add(event.getIngredient(), event.getRecipeItem());
2019-11-08 16:22:58 +01:00
//P.p.debugLog("Cauldron add: t2 " + ((t2 - t1) / 1000) + " t3: " + ((t3 - t2) / 1000) + " t4: " + ((t4 - t3) / 1000) + " t5: " + ((t5 - t4) / 1000) + "µs");
return event.willTakeItem();
2013-07-27 17:31:42 +02:00
} else {
2016-07-09 00:01:31 +02:00
return false;
}
}
return false;
}
// fills players bottle with cooked brew
2019-10-16 17:21:04 +02:00
public boolean fill(Player player, Block block) {
if (!player.hasPermission("brewery.cauldron.fill")) {
P.p.msg(player, P.p.languageReader.get("Perms_NoCauldronFill"));
return true;
}
ItemStack potion = ingredients.cook(state);
if (potion == null) return false;
if (P.use1_13) {
BlockData data = block.getBlockData();
Levelled cauldron = ((Levelled) data);
if (cauldron.getLevel() <= 0) {
2019-11-08 16:22:58 +01:00
bcauldrons.remove(block);
2019-10-16 17:21:04 +02:00
return false;
2014-05-07 02:37:28 +02:00
}
2019-10-16 17:21:04 +02:00
cauldron.setLevel(cauldron.getLevel() - 1);
// Update the new Level to the Block
// We have to use the BlockData variable "data" here instead of the casted "cauldron"
// otherwise < 1.13 crashes on plugin load for not finding the BlockData Class
block.setBlockData(data);
2013-07-27 17:31:42 +02:00
2019-10-16 17:21:04 +02:00
if (cauldron.getLevel() <= 0) {
2019-11-08 16:22:58 +01:00
bcauldrons.remove(block);
2019-10-16 17:21:04 +02:00
} else {
changed = true;
2019-10-16 17:21:04 +02:00
}
2019-10-16 17:21:04 +02:00
} else {
byte data = block.getData();
if (data > 3) {
data = 3;
} else if (data <= 0) {
2019-11-08 16:22:58 +01:00
bcauldrons.remove(block);
2019-10-16 17:21:04 +02:00
return false;
}
data -= 1;
LegacyUtil.setData(block, data);
2019-10-16 17:21:04 +02:00
if (data == 0) {
2019-11-08 16:22:58 +01:00
bcauldrons.remove(block);
2019-10-16 17:21:04 +02:00
} else {
changed = true;
}
}
2019-10-16 17:21:04 +02:00
// Bukkit Bug, inventory not updating while in event so this
// will delay the give
// but could also just use deprecated updateInventory()
giveItem(player, potion);
// player.getInventory().addItem(potion);
// player.getInventory().updateInventory();
return true;
}
2013-07-27 17:31:42 +02:00
// prints the current cooking time to the player
public static void printTime(Player player, Block block) {
2014-05-07 02:37:28 +02:00
if (!player.hasPermission("brewery.cauldron.time")) {
P.p.msg(player, P.p.languageReader.get("Error_NoPermissions"));
return;
}
2013-07-27 17:31:42 +02:00
BCauldron bcauldron = get(block);
if (bcauldron != null) {
if (bcauldron.state > 1) {
P.p.msg(player, P.p.languageReader.get("Player_CauldronInfo1", "" + bcauldron.state));
2013-07-27 17:31:42 +02:00
} else {
P.p.msg(player, P.p.languageReader.get("Player_CauldronInfo2"));
2013-07-27 17:31:42 +02:00
}
}
}
2019-10-16 17:21:04 +02:00
public static void clickCauldron(PlayerInteractEvent event) {
Material materialInHand = event.getMaterial();
ItemStack item = event.getItem();
Player player = event.getPlayer();
Block clickedBlock = event.getClickedBlock();
assert clickedBlock != null;
2019-10-16 17:21:04 +02:00
if (materialInHand == null || materialInHand == Material.AIR || materialInHand == Material.BUCKET) {
return;
} else if (materialInHand == LegacyUtil.CLOCK) {
printTime(player, clickedBlock);
return;
// fill a glass bottle with potion
} else if (materialInHand == Material.GLASS_BOTTLE) {
assert item != null;
2019-10-16 17:21:04 +02:00
if (player.getInventory().firstEmpty() != -1 || item.getAmount() == 1) {
BCauldron bcauldron = get(clickedBlock);
if (bcauldron != null) {
if (bcauldron.fill(player, clickedBlock)) {
event.setCancelled(true);
if (player.hasPermission("brewery.cauldron.fill")) {
if (item.getAmount() > 1) {
item.setAmount(item.getAmount() - 1);
} else {
setItemInHand(event, Material.AIR, false);
}
}
}
}
} else {
event.setCancelled(true);
}
return;
// reset cauldron when refilling to prevent unlimited source of potions
} else if (materialInHand == Material.WATER_BUCKET) {
if (!P.use1_9) {
// We catch >=1.9 cases in the Cauldron Listener
if (LegacyUtil.getFillLevel(clickedBlock) == 1) {
// will only remove when existing
BCauldron.remove(clickedBlock);
}
}
return;
}
// Check if fire alive below cauldron when adding ingredients
Block down = clickedBlock.getRelative(BlockFace.DOWN);
if (LegacyUtil.isFireForCauldron(down)) {
event.setCancelled(true);
boolean handSwap = false;
// Interact event is called twice!!!?? in 1.9, once for each hand.
// Certain Items in Hand cause one of them to be cancelled or not called at all sometimes.
// We mark if a player had the event for the main hand
// If not, we handle the main hand in the event for the off hand
if (P.use1_9) {
if (event.getHand() == EquipmentSlot.HAND) {
final UUID id = player.getUniqueId();
plInteracted.add(id);
P.p.getServer().getScheduler().runTask(P.p, () -> plInteracted.remove(id));
2019-10-16 17:21:04 +02:00
} else if (event.getHand() == EquipmentSlot.OFF_HAND) {
if (!plInteracted.remove(player.getUniqueId())) {
item = player.getInventory().getItemInMainHand();
if (item != null && item.getType() != Material.AIR) {
materialInHand = item.getType();
handSwap = true;
} else {
item = event.getItem();
}
}
}
}
if (item == null) return;
if (!player.hasPermission("brewery.cauldron.insert")) {
P.p.msg(player, P.p.languageReader.get("Perms_NoCauldronInsert"));
return;
}
if (ingredientAdd(clickedBlock, item, player)) {
boolean isBucket = item.getType().equals(Material.WATER_BUCKET)
|| item.getType().equals(Material.LAVA_BUCKET)
|| item.getType().equals(Material.MILK_BUCKET);
if (item.getAmount() > 1) {
item.setAmount(item.getAmount() - 1);
if (isBucket) {
giveItem(player, new ItemStack(Material.BUCKET));
}
} else {
if (isBucket) {
setItemInHand(event, Material.BUCKET, handSwap);
} else {
setItemInHand(event, Material.AIR, handSwap);
2019-10-16 17:21:04 +02:00
}
}
}
}
}
@SuppressWarnings("deprecation")
public static void setItemInHand(PlayerInteractEvent event, Material mat, boolean swapped) {
if (P.use1_9) {
if ((event.getHand() == EquipmentSlot.OFF_HAND) != swapped) {
event.getPlayer().getInventory().setItemInOffHand(new ItemStack(mat));
} else {
event.getPlayer().getInventory().setItemInMainHand(new ItemStack(mat));
}
} else {
event.getPlayer().setItemInHand(new ItemStack(mat));
}
}
// reset to normal cauldron
2016-07-09 00:01:31 +02:00
public static boolean remove(Block block) {
if (LegacyUtil.getFillLevel(block) != EMPTY) {
2019-11-08 16:22:58 +01:00
return bcauldrons.remove(block) != null;
}
2016-07-09 00:01:31 +02:00
return false;
}
2013-08-14 20:08:55 +02:00
// unloads cauldrons that are in a unloading world
// as they were written to file just before, this is safe to do
2013-05-09 21:47:58 +02:00
public static void onUnload(String name) {
2019-11-08 16:22:58 +01:00
bcauldrons.keySet().removeIf(block -> block.getWorld().getName().equals(name));
2013-05-09 21:47:58 +02:00
}
2013-05-10 00:01:28 +02:00
public static void save(ConfigurationSection config, ConfigurationSection oldData) {
BUtil.createWorldSections(config);
2013-05-28 16:25:06 +02:00
if (!bcauldrons.isEmpty()) {
int id = 0;
2019-11-08 16:22:58 +01:00
for (BCauldron cauldron : bcauldrons.values()) {
2013-06-05 19:44:30 +02:00
String worldName = cauldron.block.getWorld().getName();
String prefix;
2013-06-05 19:44:30 +02:00
if (worldName.startsWith("DXL_")) {
prefix = BUtil.getDxlName(worldName) + "." + id;
2013-06-05 19:44:30 +02:00
} else {
prefix = cauldron.block.getWorld().getUID().toString() + "." + id;
}
2013-05-28 16:25:06 +02:00
config.set(prefix + ".block", cauldron.block.getX() + "/" + cauldron.block.getY() + "/" + cauldron.block.getZ());
if (cauldron.state != 0) {
2013-05-28 16:25:06 +02:00
config.set(prefix + ".state", cauldron.state);
}
2014-06-03 21:03:32 +02:00
config.set(prefix + ".ingredients", cauldron.ingredients.serializeIngredients());
2013-05-28 16:25:06 +02:00
id++;
2013-04-30 21:41:16 +02:00
}
}
2013-05-09 21:47:58 +02:00
// copy cauldrons that are not loaded
2013-05-10 00:01:28 +02:00
if (oldData != null){
for (String uuid : oldData.getKeys(false)) {
if (!config.contains(uuid)) {
config.set(uuid, oldData.get(uuid));
}
2013-05-09 21:47:58 +02:00
}
}
2013-04-30 21:41:16 +02:00
}
// bukkit bug not updating the inventory while executing event, have to
// schedule the give
public static void giveItem(final Player player, final ItemStack item) {
P.p.getServer().getScheduler().runTaskLater(P.p, () -> player.getInventory().addItem(item), 1L);
}
}