2013-04-19 16:35:08 +02:00
|
|
|
package com.dre.brewery;
|
|
|
|
|
2016-07-09 00:01:31 +02:00
|
|
|
import com.dre.brewery.api.events.IngedientAddEvent;
|
2020-04-08 13:12:33 +02:00
|
|
|
import com.dre.brewery.filedata.BConfig;
|
2019-11-06 19:44:52 +01:00
|
|
|
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;
|
2020-11-07 22:37:32 +01:00
|
|
|
import com.dre.brewery.utility.Tuple;
|
2020-11-11 17:34:15 +01:00
|
|
|
import org.bukkit.*;
|
2013-04-19 16:35:08 +02:00
|
|
|
import org.bukkit.block.Block;
|
2013-04-28 23:57:41 +02:00
|
|
|
import org.bukkit.block.BlockFace;
|
2019-10-12 13:52:55 +02:00
|
|
|
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;
|
2019-10-12 13:52:55 +02:00
|
|
|
import org.bukkit.entity.Player;
|
2019-10-16 17:21:04 +02:00
|
|
|
import org.bukkit.event.player.PlayerInteractEvent;
|
|
|
|
import org.bukkit.inventory.EquipmentSlot;
|
2019-10-12 13:52:55 +02:00
|
|
|
import org.bukkit.inventory.ItemStack;
|
2020-11-07 22:37:32 +01:00
|
|
|
import org.jetbrains.annotations.NotNull;
|
2019-11-08 16:22:58 +01:00
|
|
|
import org.jetbrains.annotations.Nullable;
|
2019-10-12 13:52:55 +02:00
|
|
|
|
2020-11-06 13:59:36 +01:00
|
|
|
import java.util.*;
|
2013-04-19 16:35:08 +02:00
|
|
|
|
|
|
|
public class BCauldron {
|
2019-10-12 13:52:55 +02:00
|
|
|
public static final byte EMPTY = 0, SOME = 1, FULL = 2;
|
2020-11-06 13:59:36 +01:00
|
|
|
public static final int PARTICLEPAUSE = 15;
|
|
|
|
public static Random particleRandom = new Random();
|
|
|
|
private static int particleCauldron;
|
|
|
|
private static int particleDelay;
|
2019-11-24 16:06:17 +01:00
|
|
|
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-04-19 16:35:08 +02:00
|
|
|
|
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;
|
2020-04-02 16:23:19 +02:00
|
|
|
private int state = 0;
|
2020-11-11 13:47:57 +01:00
|
|
|
private boolean changed = false; // Not really needed anymore
|
2020-11-07 22:37:32 +01:00
|
|
|
private Optional<BCauldronRecipe> particleRecipe; // null if we haven't checked, empty if there is none
|
|
|
|
private Color particleColor;
|
2020-11-06 13:59:36 +01:00
|
|
|
private Location particleLocation;
|
2013-04-19 16:35:08 +02:00
|
|
|
|
2016-07-09 00:01:31 +02:00
|
|
|
public BCauldron(Block block) {
|
2013-04-19 16:35:08 +02:00
|
|
|
this.block = block;
|
2020-11-07 22:37:32 +01:00
|
|
|
particleLocation = block.getLocation().add(0.5, 0.9, 0.5);
|
2013-04-19 16:35:08 +02:00
|
|
|
}
|
|
|
|
|
2013-05-03 16:08:05 +02:00
|
|
|
// 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;
|
2020-11-07 22:37:32 +01:00
|
|
|
particleLocation = block.getLocation().add(0.5, 0.9, 0.5);
|
2013-04-30 21:41:16 +02:00
|
|
|
}
|
|
|
|
|
2020-11-06 14:52:19 +01:00
|
|
|
/**
|
|
|
|
* Updates this Cauldron, increasing the cook time and checking for Heatsource
|
|
|
|
*
|
|
|
|
* @return false if Cauldron needs to be removed
|
|
|
|
*/
|
|
|
|
public boolean onUpdate() {
|
|
|
|
// add a minute to cooking time
|
|
|
|
if (!BUtil.isChunkLoaded(block)) {
|
|
|
|
increaseState();
|
|
|
|
} else {
|
|
|
|
if (block.getType() != Material.CAULDRON) {
|
|
|
|
// Catch any WorldEdit etc. removal
|
|
|
|
return false;
|
2013-09-04 23:32:09 +02:00
|
|
|
}
|
2020-11-06 14:52:19 +01:00
|
|
|
// Check if fire still alive
|
|
|
|
if (LegacyUtil.isCauldronHeatsource(block.getRelative(BlockFace.DOWN))) {
|
|
|
|
increaseState();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Will add a minute to the cooking time
|
|
|
|
*/
|
|
|
|
public void increaseState() {
|
|
|
|
state++;
|
|
|
|
if (changed) {
|
|
|
|
ingredients = ingredients.copy();
|
|
|
|
changed = false;
|
2013-04-28 23:57:41 +02:00
|
|
|
}
|
2020-11-07 22:37:32 +01:00
|
|
|
particleColor = null;
|
2013-04-19 16:35:08 +02:00
|
|
|
}
|
|
|
|
|
2013-05-03 16:08:05 +02:00
|
|
|
// add an ingredient to the cauldron
|
2019-11-06 19:44:52 +01:00
|
|
|
public void add(ItemStack ingredient, RecipeItem rItem) {
|
2016-07-09 00:01:31 +02:00
|
|
|
if (ingredient == null || ingredient.getType() == Material.AIR) return;
|
2019-11-06 19:44:52 +01:00
|
|
|
if (changed) {
|
|
|
|
ingredients = ingredients.copy();
|
|
|
|
changed = false;
|
2013-09-04 23:32:09 +02:00
|
|
|
}
|
2019-11-06 19:44:52 +01:00
|
|
|
|
2020-11-07 22:37:32 +01:00
|
|
|
particleRecipe = null;
|
|
|
|
particleColor = null;
|
2019-11-06 19:44:52 +01:00
|
|
|
ingredients.add(ingredient, rItem);
|
2013-05-03 16:08:05 +02:00
|
|
|
block.getWorld().playEffect(block.getLocation(), Effect.EXTINGUISH, 0);
|
2020-04-02 16:23:19 +02:00
|
|
|
if (state > 0) {
|
2013-04-19 16:35:08 +02:00
|
|
|
state--;
|
|
|
|
}
|
2020-11-06 13:59:36 +01:00
|
|
|
if (BConfig.enableCauldronParticles) {
|
2020-11-06 14:52:19 +01:00
|
|
|
// Few little sparks and lots of water splashes. Offset by 0.2 in x and z
|
2020-11-06 13:59:36 +01:00
|
|
|
block.getWorld().spawnParticle(Particle.SPELL_INSTANT, particleLocation,3, 0.2, 0, 0.2);
|
|
|
|
block.getWorld().spawnParticle(Particle.WATER_SPLASH, particleLocation, 10, 0.2, 0, 0.2);
|
|
|
|
}
|
2013-04-19 16:35:08 +02:00
|
|
|
}
|
|
|
|
|
2020-04-07 12:45:55 +02:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
}
|
|
|
|
|
2013-05-03 16:08:05 +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) {
|
2013-05-03 16:08:05 +02:00
|
|
|
// if not empty
|
2019-10-12 13:52:55 +02:00
|
|
|
if (LegacyUtil.getFillLevel(block) != EMPTY) {
|
2016-07-09 00:01:31 +02:00
|
|
|
|
2019-11-06 19:44:52 +01: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);
|
2020-04-07 12:45:55 +02:00
|
|
|
BCauldron.bcauldrons.put(block, bcauldron);
|
2019-11-08 16:22:58 +01:00
|
|
|
}
|
|
|
|
|
2019-11-06 19:44:52 +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()) {
|
2019-11-06 19:44:52 +01:00
|
|
|
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");
|
2019-10-12 13:52:55 +02:00
|
|
|
return event.willTakeItem();
|
2013-07-27 17:31:42 +02:00
|
|
|
} else {
|
2016-07-09 00:01:31 +02:00
|
|
|
return false;
|
2013-04-19 16:35:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-05-03 16:08:05 +02:00
|
|
|
// 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 {
|
2019-11-06 19:44:52 +01:00
|
|
|
changed = true;
|
2019-10-16 17:21:04 +02:00
|
|
|
}
|
2018-10-27 12:09:53 +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);
|
2018-10-27 12:09:53 +02:00
|
|
|
|
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 {
|
2019-11-06 19:44:52 +01:00
|
|
|
changed = true;
|
2013-04-19 16:35:08 +02:00
|
|
|
}
|
|
|
|
}
|
2020-11-11 17:34:15 +01:00
|
|
|
if (P.use1_9) {
|
|
|
|
block.getWorld().playSound(block.getLocation(), Sound.ITEM_BOTTLE_FILL, 1f, 1f);
|
|
|
|
}
|
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-04-19 16:35:08 +02:00
|
|
|
}
|
|
|
|
|
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) {
|
2013-10-15 18:14:11 +02:00
|
|
|
P.p.msg(player, P.p.languageReader.get("Player_CauldronInfo1", "" + bcauldron.state));
|
2013-07-27 17:31:42 +02:00
|
|
|
} else {
|
2013-10-15 18:14:11 +02:00
|
|
|
P.p.msg(player, P.p.languageReader.get("Player_CauldronInfo2"));
|
2013-07-27 17:31:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-06 13:59:36 +01:00
|
|
|
public void cookEffect() {
|
|
|
|
if (BUtil.isChunkLoaded(block) && LegacyUtil.isCauldronHeatsource(block.getRelative(BlockFace.DOWN))) {
|
2020-11-07 22:37:32 +01:00
|
|
|
if (particleRandom.nextFloat() > 0.85) {
|
|
|
|
// Dark pixely smoke cloud at 0.4 random in x and z
|
|
|
|
// 0 count enables direction, send to y = 1 with speed 0.09
|
|
|
|
block.getWorld().spawnParticle(Particle.SMOKE_LARGE, getRandParticleLoc(), 0, 0, 1, 0, 0.09);
|
2020-11-06 13:59:36 +01:00
|
|
|
}
|
|
|
|
if (particleRandom.nextFloat() > 0.2) {
|
2020-11-06 14:52:19 +01:00
|
|
|
// A Water Splash with 0.2 offset in x and z
|
2020-11-06 13:59:36 +01:00
|
|
|
block.getWorld().spawnParticle(Particle.WATER_SPLASH, particleLocation, 1, 0.2, 0, 0.2);
|
|
|
|
}
|
2020-11-07 22:37:32 +01:00
|
|
|
Color color = getParticleColor();
|
2020-11-06 14:52:19 +01:00
|
|
|
// Colorable spirally spell, 0 count enables color instead of the offset variables
|
|
|
|
// Configurable RGB color. 1025 seems to be the best for color brightness and upwards motion
|
2020-11-07 22:37:32 +01:00
|
|
|
block.getWorld().spawnParticle(Particle.SPELL_MOB, getRandParticleLoc(), 0,
|
|
|
|
((double) color.getRed()) / 255.0,
|
|
|
|
((double) color.getGreen()) / 255.0,
|
|
|
|
((double) color.getBlue()) / 255.0,
|
|
|
|
1025.0);
|
|
|
|
|
2020-11-08 00:59:52 +01:00
|
|
|
if (P.use1_13 && particleRandom.nextFloat() > 0.4) {
|
2020-11-07 22:37:32 +01:00
|
|
|
// Two hovering pixely dust clouds, a bit offset with DustOptions to give some color and size
|
|
|
|
block.getWorld().spawnParticle(Particle.REDSTONE, particleLocation, 2, 0.15, 0.2, 0.15, new Particle.DustOptions(color, 1.5f));
|
|
|
|
}
|
2020-11-06 13:59:36 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-06 14:52:19 +01:00
|
|
|
private Location getRandParticleLoc() {
|
|
|
|
return new Location(particleLocation.getWorld(),
|
|
|
|
particleLocation.getX() + (particleRandom.nextDouble() * 0.8) - 0.4,
|
|
|
|
particleLocation.getY(),
|
|
|
|
particleLocation.getZ() + (particleRandom.nextDouble() * 0.8) - 0.4);
|
2020-11-06 13:59:36 +01:00
|
|
|
}
|
|
|
|
|
2020-11-07 22:37:32 +01:00
|
|
|
/**
|
|
|
|
* Get or calculate the particle color from the current best Cauldron Recipe
|
|
|
|
* Also calculates the best Cauldron Recipe if not yet done
|
|
|
|
*
|
|
|
|
* @return the Particle Color, after potentially calculating it
|
|
|
|
*/
|
|
|
|
@NotNull
|
|
|
|
public Color getParticleColor() {
|
|
|
|
if (state < 1) {
|
|
|
|
return Color.fromRGB(153, 221, 255); // Bright Blue
|
|
|
|
}
|
|
|
|
if (particleColor != null) {
|
|
|
|
return particleColor;
|
|
|
|
}
|
|
|
|
if (particleRecipe == null) {
|
|
|
|
// Check for Cauldron Recipe
|
|
|
|
particleRecipe = Optional.ofNullable(ingredients.getCauldronRecipe());
|
|
|
|
}
|
|
|
|
|
|
|
|
List<Tuple<Integer, Color>> colorList = null;
|
|
|
|
if (particleRecipe.isPresent()) {
|
|
|
|
colorList = particleRecipe.get().getParticleColor();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (colorList == null || colorList.isEmpty()) {
|
|
|
|
// No color List configured, or no recipe found
|
|
|
|
colorList = new ArrayList<>(1);
|
|
|
|
colorList.add(new Tuple<>(10, Color.fromRGB(77, 166, 255))); // Dark Aqua kind of Blue
|
|
|
|
}
|
|
|
|
int index = 0;
|
|
|
|
while (index < colorList.size() - 1 && colorList.get(index).a() < state) {
|
|
|
|
// Find the first index where the colorList Minute is higher than the state
|
|
|
|
index++;
|
|
|
|
}
|
|
|
|
|
|
|
|
int minute = colorList.get(index).a();
|
|
|
|
if (minute > state) {
|
|
|
|
// going towards the minute
|
|
|
|
int prevPos;
|
|
|
|
Color prevColor;
|
|
|
|
if (index > 0) {
|
|
|
|
// has previous colours
|
|
|
|
prevPos = colorList.get(index - 1).a();
|
|
|
|
prevColor = colorList.get(index - 1).b();
|
|
|
|
} else {
|
|
|
|
prevPos = 0;
|
|
|
|
prevColor = Color.fromRGB(153, 221, 255); // Bright Blue
|
|
|
|
}
|
|
|
|
|
|
|
|
particleColor = BUtil.weightedMixColor(prevColor, prevPos, state, colorList.get(index).b(), minute);
|
|
|
|
} else if (minute == state) {
|
|
|
|
// reached the minute
|
|
|
|
particleColor = colorList.get(index).b();
|
|
|
|
} else {
|
|
|
|
// passed the last minute configured
|
|
|
|
if (index > 0) {
|
|
|
|
// We have more than one color, just use the last one
|
|
|
|
particleColor = colorList.get(index).b();
|
|
|
|
} else {
|
|
|
|
// Only have one color, go towards a Gray
|
|
|
|
Color nextColor = Color.fromRGB(138, 153, 168); // Dark Teal, Gray
|
|
|
|
int nextPos = (int) (minute * 2.6f);
|
|
|
|
|
|
|
|
if (nextPos <= state) {
|
|
|
|
// We are past the next color (Gray) as well, keep using it
|
|
|
|
particleColor = nextColor;
|
|
|
|
} else {
|
|
|
|
particleColor = BUtil.weightedMixColor(colorList.get(index).b(), minute, state, nextColor, nextPos);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//P.p.log("RGB: " + particleColor.getRed() + "|" + particleColor.getGreen() + "|" + particleColor.getBlue());
|
|
|
|
return particleColor;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void processNextCookEffects() {
|
2020-11-06 13:59:36 +01:00
|
|
|
if (!BConfig.enableCauldronParticles) return;
|
|
|
|
int size = bcauldrons.size();
|
|
|
|
if (size <= 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The Particle Delay is reduced every time, independent on how many cauldrons are processed
|
|
|
|
// If it did not reach zero as we process all cauldrons, skip some tasks
|
|
|
|
particleDelay--;
|
|
|
|
if (particleCauldron >= size) {
|
|
|
|
if (particleDelay <= 0) {
|
|
|
|
particleCauldron = 0;
|
|
|
|
particleDelay = PARTICLEPAUSE;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Decide how many cauldrons to process this time
|
|
|
|
int cauldronsToProcess;
|
|
|
|
if (size < PARTICLEPAUSE) {
|
|
|
|
cauldronsToProcess = 1;
|
|
|
|
} else {
|
|
|
|
cauldronsToProcess = (int) Math.ceil((float) size / (float) PARTICLEPAUSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
Iterator<BCauldron> cauldronsIter = bcauldrons.values().iterator();
|
|
|
|
int currentPos = 0;
|
|
|
|
for (; currentPos < particleCauldron; currentPos++) {
|
|
|
|
cauldronsIter.next();
|
|
|
|
}
|
|
|
|
|
|
|
|
while (cauldronsToProcess > 0) {
|
|
|
|
if (particleCauldron >= size) {
|
|
|
|
// We reached the end of the Cauldron list
|
|
|
|
if (particleDelay <= 0) {
|
|
|
|
// Processing all cauldrons took as long as the delay, start over right away
|
|
|
|
particleCauldron = 0;
|
|
|
|
particleDelay = PARTICLEPAUSE;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
cauldronsIter.next().cookEffect();
|
|
|
|
cauldronsToProcess--;
|
|
|
|
particleCauldron++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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();
|
2019-10-29 16:20:32 +01:00
|
|
|
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) {
|
2019-10-29 16:20:32 +01:00
|
|
|
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);
|
2020-11-06 13:59:36 +01:00
|
|
|
if (LegacyUtil.isCauldronHeatsource(down)) {
|
2019-10-16 17:21:04 +02:00
|
|
|
|
|
|
|
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);
|
2019-10-29 16:20:32 +01:00
|
|
|
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 {
|
2020-04-08 13:12:33 +02:00
|
|
|
item = BConfig.useOffhandForCauldron ? event.getItem() : null;
|
2019-10-16 17:21:04 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (item == null) return;
|
|
|
|
|
2019-11-06 19:44:52 +01:00
|
|
|
if (!player.hasPermission("brewery.cauldron.insert")) {
|
|
|
|
P.p.msg(player, P.p.languageReader.get("Perms_NoCauldronInsert"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (ingredientAdd(clickedBlock, item, player)) {
|
2020-04-13 13:52:57 +02:00
|
|
|
boolean isBucket = item.getType().name().endsWith("_BUCKET");
|
|
|
|
boolean isBottle = LegacyUtil.isBottle(item.getType());
|
2019-11-06 19:44:52 +01:00
|
|
|
if (item.getAmount() > 1) {
|
|
|
|
item.setAmount(item.getAmount() - 1);
|
2019-10-29 16:20:32 +01:00
|
|
|
|
2019-11-06 19:44:52 +01:00
|
|
|
if (isBucket) {
|
|
|
|
giveItem(player, new ItemStack(Material.BUCKET));
|
2020-04-13 13:52:57 +02:00
|
|
|
} else if (isBottle) {
|
|
|
|
giveItem(player, new ItemStack(Material.GLASS_BOTTLE));
|
2019-11-06 19:44:52 +01:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (isBucket) {
|
|
|
|
setItemInHand(event, Material.BUCKET, handSwap);
|
2020-04-13 13:52:57 +02:00
|
|
|
} else if (isBottle) {
|
|
|
|
setItemInHand(event, Material.GLASS_BOTTLE, handSwap);
|
2019-10-29 16:20:32 +01:00
|
|
|
} else {
|
2019-11-06 19:44:52 +01:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-07 22:37:32 +01:00
|
|
|
/**
|
|
|
|
* Recalculate the Cauldron Particle Recipe
|
|
|
|
*/
|
|
|
|
public static void reload() {
|
|
|
|
for (BCauldron cauldron : BCauldron.bcauldrons.values()) {
|
|
|
|
cauldron.particleRecipe = null;
|
|
|
|
cauldron.particleColor = null;
|
|
|
|
if (BConfig.enableCauldronParticles) {
|
|
|
|
if (BUtil.isChunkLoaded(cauldron.block) && LegacyUtil.isCauldronHeatsource(cauldron.block.getRelative(BlockFace.DOWN))) {
|
|
|
|
cauldron.getParticleColor();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-06 14:52:19 +01:00
|
|
|
/**
|
|
|
|
* reset to normal cauldron
|
|
|
|
*/
|
2016-07-09 00:01:31 +02:00
|
|
|
public static boolean remove(Block block) {
|
2020-11-06 14:52:19 +01:00
|
|
|
return bcauldrons.remove(block) != null;
|
2013-04-19 16:35:08 +02:00
|
|
|
}
|
|
|
|
|
2020-11-09 13:18:49 +01:00
|
|
|
/**
|
|
|
|
* Are any Cauldrons in that World
|
|
|
|
*/
|
|
|
|
public static boolean hasDataInWorld(String name) {
|
|
|
|
return bcauldrons.keySet().stream().anyMatch(block -> block.getWorld().getName().equals(name));
|
|
|
|
}
|
|
|
|
|
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) {
|
2019-10-12 13:52:55 +02:00
|
|
|
BUtil.createWorldSections(config);
|
2013-07-28 23:53:35 +02:00
|
|
|
|
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();
|
2014-04-08 16:11:20 +02:00
|
|
|
String prefix;
|
2013-06-05 19:44:30 +02:00
|
|
|
|
|
|
|
if (worldName.startsWith("DXL_")) {
|
2019-10-12 13:52:55 +02:00
|
|
|
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());
|
2020-04-02 16:23:19 +02:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2013-05-03 16:08:05 +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) {
|
2019-10-29 16:20:32 +01:00
|
|
|
P.p.getServer().getScheduler().runTaskLater(P.p, () -> player.getInventory().addItem(item), 1L);
|
2013-04-19 16:35:08 +02:00
|
|
|
}
|
|
|
|
|
2018-10-27 12:09:53 +02:00
|
|
|
}
|