mirror of
https://github.com/DieReicheErethons/Brewery.git
synced 2024-11-22 11:35:16 +01:00
Rewrite of the Custom item into RecipeItem
and Ingredient with subclasses Implemented adding custom items to Ingredients Added support for plugin-items
This commit is contained in:
parent
d0263c611c
commit
7f2f9d75dd
16
pom.xml
16
pom.xml
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
<build>
|
<build>
|
||||||
<sourceDirectory>src</sourceDirectory>
|
<sourceDirectory>src</sourceDirectory>
|
||||||
|
<testSourceDirectory>test</testSourceDirectory>
|
||||||
|
|
||||||
<resources>
|
<resources>
|
||||||
<!-- Static resources -->
|
<!-- Static resources -->
|
||||||
@ -87,7 +88,7 @@
|
|||||||
<url>http://maven.sk89q.com/repo/</url>
|
<url>http://maven.sk89q.com/repo/</url>
|
||||||
</repository>
|
</repository>
|
||||||
<repository>
|
<repository>
|
||||||
<!-- GriefPrevention -->
|
<!-- GriefPrevention, SlimeFun -->
|
||||||
<id>jitpack.io</id>
|
<id>jitpack.io</id>
|
||||||
<url>https://jitpack.io</url>
|
<url>https://jitpack.io</url>
|
||||||
</repository>
|
</repository>
|
||||||
@ -226,6 +227,19 @@
|
|||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.TheBusyBiscuit</groupId>
|
||||||
|
<artifactId>Slimefun4</artifactId>
|
||||||
|
<version>4bb9abd247</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<!-- Contains proprietary api that we use for integration -->
|
||||||
|
<groupId>com.dre</groupId>
|
||||||
|
<artifactId>ExtPluginBridge</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.bstats</groupId>
|
<groupId>org.bstats</groupId>
|
||||||
<artifactId>bstats-bukkit</artifactId>
|
<artifactId>bstats-bukkit</artifactId>
|
||||||
|
@ -192,6 +192,8 @@ cauldron:
|
|||||||
# Halte ein Item in der Hand und benutze /brew ItemName um dessen Material herauszufinden und für ein Rezept zu benutzen
|
# Halte ein Item in der Hand und benutze /brew ItemName um dessen Material herauszufinden und für ein Rezept zu benutzen
|
||||||
# (Item-ids anstatt Material können in Bukkit nicht mehr benutzt werden)
|
# (Item-ids anstatt Material können in Bukkit nicht mehr benutzt werden)
|
||||||
# Eine Liste von allen Materialien kann hier gefunden werden: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html
|
# Eine Liste von allen Materialien kann hier gefunden werden: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html
|
||||||
|
# Plugin Items mit 'Plugin:Id' (Im Moment ExoticGarden, Slimefun, MMOItems, Brewery)
|
||||||
|
# Oder ein oben definiertes Custom Item
|
||||||
# cookingtime: Zeit in Echtminuten die die Zutaten kochen müssen
|
# cookingtime: Zeit in Echtminuten die die Zutaten kochen müssen
|
||||||
# distillruns: Wie oft destilliert werden muss für vollen Alkoholgehalt (0=ohne Destillieren)
|
# distillruns: Wie oft destilliert werden muss für vollen Alkoholgehalt (0=ohne Destillieren)
|
||||||
# distilltime: Wie lange (in sekunden) ein Destillations-Durchlauf braucht (0=Standard Zeit von 40 sek) MC Standard wäre 20 sek
|
# distilltime: Wie lange (in sekunden) ein Destillations-Durchlauf braucht (0=Standard Zeit von 40 sek) MC Standard wäre 20 sek
|
||||||
@ -219,8 +221,8 @@ recipes:
|
|||||||
- Diamond/1
|
- Diamond/1
|
||||||
- Spruce_Planks/8
|
- Spruce_Planks/8
|
||||||
- Bedrock/1
|
- Bedrock/1
|
||||||
# - Brewery:Weißbier/2
|
- Brewery:Weißbier/2
|
||||||
# - ExoticGarden:Grape/3
|
# - ExoticGarden:Grape/3
|
||||||
- bsp-item/1
|
- bsp-item/1
|
||||||
cookingtime: 3
|
cookingtime: 3
|
||||||
distillruns: 2
|
distillruns: 2
|
||||||
|
@ -193,6 +193,8 @@ cauldron:
|
|||||||
# With an item in your hand, use /brew ItemName to get its material for use in a recipe
|
# With an item in your hand, use /brew ItemName to get its material for use in a recipe
|
||||||
# (Item-ids instead of material are not supported by bukkit anymore and will not work)
|
# (Item-ids instead of material are not supported by bukkit anymore and will not work)
|
||||||
# A list of materials can be found here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html
|
# A list of materials can be found here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html
|
||||||
|
# Plugin items with 'plugin:id' (Currently supporting ExoticGarden, Slimefun, MMOItems, Brewery)
|
||||||
|
# Or a custom item defined above
|
||||||
# cookingtime: Time in real minutes ingredients have to boil
|
# cookingtime: Time in real minutes ingredients have to boil
|
||||||
# distillruns: How often it has to be distilled for full alcohol (0=without distilling)
|
# distillruns: How often it has to be distilled for full alcohol (0=without distilling)
|
||||||
# distilltime: How long (in seconds) one distill-run takes (0=Default time of 40 sec) MC Default would be 20 sec
|
# distilltime: How long (in seconds) one distill-run takes (0=Default time of 40 sec) MC Default would be 20 sec
|
||||||
@ -220,6 +222,8 @@ recipes:
|
|||||||
- Diamond/1
|
- Diamond/1
|
||||||
- Spruce_Planks/8
|
- Spruce_Planks/8
|
||||||
- Bedrock/1
|
- Bedrock/1
|
||||||
|
- Brewery:Wheatbeer/2
|
||||||
|
# - ExoticGarden:Grape/3
|
||||||
cookingtime: 3
|
cookingtime: 3
|
||||||
distillruns: 2
|
distillruns: 2
|
||||||
distilltime: 60
|
distilltime: 60
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package com.dre.brewery;
|
package com.dre.brewery;
|
||||||
|
|
||||||
import com.dre.brewery.api.events.IngedientAddEvent;
|
import com.dre.brewery.api.events.IngedientAddEvent;
|
||||||
|
import com.dre.brewery.recipe.BCauldronRecipe;
|
||||||
|
import com.dre.brewery.recipe.RecipeItem;
|
||||||
import com.dre.brewery.utility.BUtil;
|
import com.dre.brewery.utility.BUtil;
|
||||||
import com.dre.brewery.utility.LegacyUtil;
|
import com.dre.brewery.utility.LegacyUtil;
|
||||||
import org.bukkit.Effect;
|
import org.bukkit.Effect;
|
||||||
@ -28,7 +30,7 @@ public class BCauldron {
|
|||||||
private BIngredients ingredients = new BIngredients();
|
private BIngredients ingredients = new BIngredients();
|
||||||
private final Block block;
|
private final Block block;
|
||||||
private int state = 1;
|
private int state = 1;
|
||||||
private boolean someRemoved = false;
|
private boolean changed = false;
|
||||||
|
|
||||||
public BCauldron(Block block) {
|
public BCauldron(Block block) {
|
||||||
this.block = block;
|
this.block = block;
|
||||||
@ -48,22 +50,22 @@ public class BCauldron {
|
|||||||
if (!BUtil.isChunkLoaded(block) || LegacyUtil.isFireForCauldron(block.getRelative(BlockFace.DOWN))) {
|
if (!BUtil.isChunkLoaded(block) || LegacyUtil.isFireForCauldron(block.getRelative(BlockFace.DOWN))) {
|
||||||
// add a minute to cooking time
|
// add a minute to cooking time
|
||||||
state++;
|
state++;
|
||||||
if (someRemoved) {
|
if (changed) {
|
||||||
ingredients = ingredients.clone();
|
ingredients = ingredients.copy();
|
||||||
someRemoved = false;
|
changed = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add an ingredient to the cauldron
|
// add an ingredient to the cauldron
|
||||||
public void add(ItemStack ingredient) {
|
public void add(ItemStack ingredient, RecipeItem rItem) {
|
||||||
if (ingredient == null || ingredient.getType() == Material.AIR) return;
|
if (ingredient == null || ingredient.getType() == Material.AIR) return;
|
||||||
if (someRemoved) { // TODO no need to clone
|
if (changed) {
|
||||||
ingredients = ingredients.clone();
|
ingredients = ingredients.copy();
|
||||||
someRemoved = false;
|
changed = false;
|
||||||
}
|
}
|
||||||
ingredient = new ItemStack(ingredient.getType(), 1, ingredient.getDurability());
|
|
||||||
ingredients.add(ingredient);
|
ingredients.add(ingredient, rItem);
|
||||||
block.getWorld().playEffect(block.getLocation(), Effect.EXTINGUISH, 0);
|
block.getWorld().playEffect(block.getLocation(), Effect.EXTINGUISH, 0);
|
||||||
if (state > 1) {
|
if (state > 1) {
|
||||||
state--;
|
state--;
|
||||||
@ -90,10 +92,20 @@ public class BCauldron {
|
|||||||
bcauldron = new BCauldron(block);
|
bcauldron = new BCauldron(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
IngedientAddEvent event = new IngedientAddEvent(player, block, bcauldron, ingredient);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
IngedientAddEvent event = new IngedientAddEvent(player, block, bcauldron, ingredient.clone(), rItem);
|
||||||
P.p.getServer().getPluginManager().callEvent(event);
|
P.p.getServer().getPluginManager().callEvent(event);
|
||||||
if (!event.isCancelled()) {
|
if (!event.isCancelled()) {
|
||||||
bcauldron.add(event.getIngredient());
|
bcauldron.add(event.getIngredient(), event.getRecipeItem());
|
||||||
return event.willTakeItem();
|
return event.willTakeItem();
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -127,7 +139,7 @@ public class BCauldron {
|
|||||||
if (cauldron.getLevel() <= 0) {
|
if (cauldron.getLevel() <= 0) {
|
||||||
bcauldrons.remove(this);
|
bcauldrons.remove(this);
|
||||||
} else {
|
} else {
|
||||||
someRemoved = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -144,7 +156,7 @@ public class BCauldron {
|
|||||||
if (data == 0) {
|
if (data == 0) {
|
||||||
bcauldrons.remove(this);
|
bcauldrons.remove(this);
|
||||||
} else {
|
} else {
|
||||||
someRemoved = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Bukkit Bug, inventory not updating while in event so this
|
// Bukkit Bug, inventory not updating while in event so this
|
||||||
@ -250,30 +262,25 @@ public class BCauldron {
|
|||||||
}
|
}
|
||||||
if (item == null) return;
|
if (item == null) return;
|
||||||
|
|
||||||
// add ingredient to cauldron that meet the previous conditions
|
if (!player.hasPermission("brewery.cauldron.insert")) {
|
||||||
if (BCauldronRecipe.acceptedMaterials.contains(materialInHand)) {
|
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 (!player.hasPermission("brewery.cauldron.insert")) {
|
if (isBucket) {
|
||||||
P.p.msg(player, P.p.languageReader.get("Perms_NoCauldronInsert"));
|
giveItem(player, new ItemStack(Material.BUCKET));
|
||||||
return;
|
}
|
||||||
}
|
} else {
|
||||||
|
if (isBucket) {
|
||||||
if (ingredientAdd(clickedBlock, item, player)) {
|
setItemInHand(event, Material.BUCKET, handSwap);
|
||||||
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 {
|
} else {
|
||||||
if (isBucket) {
|
setItemInHand(event, Material.AIR, handSwap);
|
||||||
setItemInHand(event, Material.BUCKET, handSwap);
|
|
||||||
} else {
|
|
||||||
setItemInHand(event, Material.AIR, handSwap);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,13 @@
|
|||||||
package com.dre.brewery;
|
package com.dre.brewery;
|
||||||
|
|
||||||
import com.dre.brewery.api.events.brew.BrewModifyEvent;
|
import com.dre.brewery.api.events.brew.BrewModifyEvent;
|
||||||
|
import com.dre.brewery.lore.Base91EncoderStream;
|
||||||
import com.dre.brewery.lore.BrewLore;
|
import com.dre.brewery.lore.BrewLore;
|
||||||
|
import com.dre.brewery.recipe.BCauldronRecipe;
|
||||||
|
import com.dre.brewery.recipe.BRecipe;
|
||||||
|
import com.dre.brewery.recipe.Ingredient;
|
||||||
|
import com.dre.brewery.recipe.ItemLoader;
|
||||||
|
import com.dre.brewery.recipe.RecipeItem;
|
||||||
import com.dre.brewery.utility.PotionColor;
|
import com.dre.brewery.utility.PotionColor;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
@ -9,19 +15,18 @@ import org.bukkit.inventory.ItemStack;
|
|||||||
import org.bukkit.inventory.meta.PotionMeta;
|
import org.bukkit.inventory.meta.PotionMeta;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class BIngredients {
|
public class BIngredients {
|
||||||
private static int lastId = 0;
|
private static int lastId = 0; // Legacy
|
||||||
|
|
||||||
private int id; // Legacy
|
private int id; // Legacy
|
||||||
private List<ItemStack> ingredients = new ArrayList<>();
|
private List<Ingredient> ingredients = new ArrayList<>();
|
||||||
private int cookedTime;
|
private int cookedTime;
|
||||||
|
|
||||||
// Represents ingredients in Cauldron, Brew
|
// Represents ingredients in Cauldron, Brew
|
||||||
@ -32,7 +37,7 @@ public class BIngredients {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load from File
|
// Load from File
|
||||||
public BIngredients(List<ItemStack> ingredients, int cookedTime) {
|
public BIngredients(List<Ingredient> ingredients, int cookedTime) {
|
||||||
this.ingredients = ingredients;
|
this.ingredients = ingredients;
|
||||||
this.cookedTime = cookedTime;
|
this.cookedTime = cookedTime;
|
||||||
//this.id = lastId;
|
//this.id = lastId;
|
||||||
@ -40,7 +45,7 @@ public class BIngredients {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load from legacy Brew section
|
// Load from legacy Brew section
|
||||||
public BIngredients(List<ItemStack> ingredients, int cookedTime, boolean legacy) {
|
public BIngredients(List<Ingredient> ingredients, int cookedTime, boolean legacy) {
|
||||||
this(ingredients, cookedTime);
|
this(ingredients, cookedTime);
|
||||||
if (legacy) {
|
if (legacy) {
|
||||||
this.id = lastId;
|
this.id = lastId;
|
||||||
@ -48,15 +53,32 @@ public class BIngredients {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add an ingredient to this
|
// Force add an ingredient to this
|
||||||
|
// Will not check if item is acceptable
|
||||||
public void add(ItemStack ingredient) {
|
public void add(ItemStack ingredient) {
|
||||||
for (ItemStack item : ingredients) {
|
for (Ingredient existing : ingredients) {
|
||||||
if (item.isSimilar(ingredient)) {
|
if (existing.matches(ingredient)) {
|
||||||
item.setAmount(item.getAmount() + ingredient.getAmount());
|
existing.setAmount(existing.getAmount() + 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ingredients.add(ingredient);
|
|
||||||
|
Ingredient ing = RecipeItem.getMatchingRecipeItem(ingredient, true).toIngredient(ingredient);
|
||||||
|
ing.setAmount(1);
|
||||||
|
ingredients.add(ing);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add an ingredient to this with corresponding RecipeItem
|
||||||
|
public void add(ItemStack ingredient, RecipeItem rItem) {
|
||||||
|
Ingredient ingredientItem = rItem.toIngredient(ingredient);
|
||||||
|
for (Ingredient existing : ingredients) {
|
||||||
|
if (existing.isSimilar(ingredientItem)) {
|
||||||
|
existing.setAmount(existing.getAmount() + 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ingredientItem.setAmount(1);
|
||||||
|
ingredients.add(ingredientItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns an Potion item with cooked ingredients
|
// returns an Potion item with cooked ingredients
|
||||||
@ -140,8 +162,8 @@ public class BIngredients {
|
|||||||
// returns amount of ingredients
|
// returns amount of ingredients
|
||||||
public int getIngredientsCount() {
|
public int getIngredientsCount() {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (ItemStack item : ingredients) {
|
for (Ingredient ing : ingredients) {
|
||||||
count += item.getAmount();
|
count += ing.getAmount();
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
@ -265,7 +287,7 @@ public class BIngredients {
|
|||||||
// when ingredients are not complete
|
// when ingredients are not complete
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
for (ItemStack ingredient : ingredients) {
|
for (Ingredient ingredient : ingredients) {
|
||||||
int amountInRecipe = recipe.amountOf(ingredient);
|
int amountInRecipe = recipe.amountOf(ingredient);
|
||||||
count = ingredient.getAmount();
|
count = ingredient.getAmount();
|
||||||
if (amountInRecipe == 0) {
|
if (amountInRecipe == 0) {
|
||||||
@ -346,12 +368,7 @@ public class BIngredients {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Creates a copy ingredients
|
// Creates a copy ingredients
|
||||||
@Override
|
public BIngredients copy() {
|
||||||
public BIngredients clone() {
|
|
||||||
try {
|
|
||||||
super.clone();
|
|
||||||
} catch (CloneNotSupportedException ignored) {
|
|
||||||
}
|
|
||||||
BIngredients copy = new BIngredients();
|
BIngredients copy = new BIngredients();
|
||||||
copy.ingredients.addAll(ingredients);
|
copy.ingredients.addAll(ingredients);
|
||||||
copy.cookedTime = cookedTime;
|
copy.cookedTime = cookedTime;
|
||||||
@ -399,21 +416,25 @@ public class BIngredients {
|
|||||||
public void save(DataOutputStream out) throws IOException {
|
public void save(DataOutputStream out) throws IOException {
|
||||||
out.writeInt(cookedTime);
|
out.writeInt(cookedTime);
|
||||||
out.writeByte(ingredients.size());
|
out.writeByte(ingredients.size());
|
||||||
for (ItemStack item : ingredients) {
|
for (Ingredient ing : ingredients) {
|
||||||
out.writeUTF(item.getType().name());
|
ing.saveTo(out);
|
||||||
out.writeShort(item.getAmount());
|
out.writeShort(Math.min(ing.getAmount(), Short.MAX_VALUE));
|
||||||
out.writeShort(item.getDurability());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BIngredients load(DataInputStream in) throws IOException {
|
public static BIngredients load(DataInputStream in, short dataVersion) throws IOException {
|
||||||
int cookedTime = in.readInt();
|
int cookedTime = in.readInt();
|
||||||
byte size = in.readByte();
|
byte size = in.readByte();
|
||||||
List<ItemStack> ing = new ArrayList<>(size);
|
List<Ingredient> ing = new ArrayList<>(size);
|
||||||
for (; size > 0; size--) {
|
for (; size > 0; size--) {
|
||||||
Material mat = Material.getMaterial(in.readUTF());
|
ItemLoader itemLoader = new ItemLoader(dataVersion, in, in.readUTF());
|
||||||
if (mat != null) {
|
if (Ingredient.LOADERS.containsKey(itemLoader.getSaveID())) {
|
||||||
ing.add(new ItemStack(mat, in.readShort(), in.readShort()));
|
Ingredient loaded = Ingredient.LOADERS.get(itemLoader.getSaveID()).apply(itemLoader);
|
||||||
|
int amount = in.readShort();
|
||||||
|
if (loaded != null) {
|
||||||
|
loaded.setAmount(amount);
|
||||||
|
ing.add(loaded);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new BIngredients(ing, cookedTime);
|
return new BIngredients(ing, cookedTime);
|
||||||
@ -421,8 +442,7 @@ public class BIngredients {
|
|||||||
|
|
||||||
// saves data into main Ingredient section. Returns the save id
|
// saves data into main Ingredient section. Returns the save id
|
||||||
// Only needed for legacy potions
|
// Only needed for legacy potions
|
||||||
@Deprecated
|
public int saveLegacy(ConfigurationSection config) {
|
||||||
public int save(ConfigurationSection config) {
|
|
||||||
String path = "Ingredients." + id;
|
String path = "Ingredients." + id;
|
||||||
if (cookedTime != 0) {
|
if (cookedTime != 0) {
|
||||||
config.set(path + ".cookedTime", cookedTime);
|
config.set(path + ".cookedTime", cookedTime);
|
||||||
@ -432,13 +452,26 @@ public class BIngredients {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//convert the ingredient Material to String
|
//convert the ingredient Material to String
|
||||||
public Map<String, Integer> serializeIngredients() {
|
/*public Map<String, Integer> serializeIngredients() {
|
||||||
Map<String, Integer> mats = new HashMap<>();
|
Map<String, Integer> mats = new HashMap<>();
|
||||||
for (ItemStack item : ingredients) {
|
for (ItemStack item : ingredients) {
|
||||||
String mat = item.getType().name() + "," + item.getDurability();
|
String mat = item.getType().name() + "," + item.getDurability();
|
||||||
mats.put(mat, item.getAmount());
|
mats.put(mat, item.getAmount());
|
||||||
}
|
}
|
||||||
return mats;
|
return mats;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// Serialize Ingredients to String for storing in yml, ie for Cauldrons
|
||||||
|
public String serializeIngredients() {
|
||||||
|
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
|
||||||
|
try (DataOutputStream out = new DataOutputStream(new Base91EncoderStream(byteStream))) {
|
||||||
|
out.writeByte(Brew.SAVE_VER);
|
||||||
|
save(out);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return byteStream.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import com.dre.brewery.api.events.PlayerPukeEvent;
|
|||||||
import com.dre.brewery.api.events.PlayerPushEvent;
|
import com.dre.brewery.api.events.PlayerPushEvent;
|
||||||
import com.dre.brewery.api.events.brew.BrewDrinkEvent;
|
import com.dre.brewery.api.events.brew.BrewDrinkEvent;
|
||||||
import com.dre.brewery.filedata.BConfig;
|
import com.dre.brewery.filedata.BConfig;
|
||||||
|
import com.dre.brewery.recipe.BEffect;
|
||||||
import com.dre.brewery.utility.BUtil;
|
import com.dre.brewery.utility.BUtil;
|
||||||
import org.apache.commons.lang.mutable.MutableInt;
|
import org.apache.commons.lang.mutable.MutableInt;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
|
@ -5,7 +5,7 @@ import com.dre.brewery.api.events.barrel.BarrelCreateEvent;
|
|||||||
import com.dre.brewery.api.events.barrel.BarrelDestroyEvent;
|
import com.dre.brewery.api.events.barrel.BarrelDestroyEvent;
|
||||||
import com.dre.brewery.api.events.barrel.BarrelRemoveEvent;
|
import com.dre.brewery.api.events.barrel.BarrelRemoveEvent;
|
||||||
import com.dre.brewery.filedata.BConfig;
|
import com.dre.brewery.filedata.BConfig;
|
||||||
import com.dre.brewery.integration.LogBlockBarrel;
|
import com.dre.brewery.integration.barrel.LogBlockBarrel;
|
||||||
import com.dre.brewery.lore.BrewLore;
|
import com.dre.brewery.lore.BrewLore;
|
||||||
import com.dre.brewery.utility.BUtil;
|
import com.dre.brewery.utility.BUtil;
|
||||||
import com.dre.brewery.utility.BoundingBox;
|
import com.dre.brewery.utility.BoundingBox;
|
||||||
|
@ -4,6 +4,8 @@ import com.dre.brewery.api.events.brew.BrewModifyEvent;
|
|||||||
import com.dre.brewery.filedata.BConfig;
|
import com.dre.brewery.filedata.BConfig;
|
||||||
import com.dre.brewery.filedata.ConfigUpdater;
|
import com.dre.brewery.filedata.ConfigUpdater;
|
||||||
import com.dre.brewery.lore.*;
|
import com.dre.brewery.lore.*;
|
||||||
|
import com.dre.brewery.recipe.BEffect;
|
||||||
|
import com.dre.brewery.recipe.BRecipe;
|
||||||
import com.dre.brewery.utility.PotionColor;
|
import com.dre.brewery.utility.PotionColor;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
@ -26,6 +28,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
public class Brew {
|
public class Brew {
|
||||||
// represents the liquid in the brewed Potions
|
// represents the liquid in the brewed Potions
|
||||||
|
public static final byte SAVE_VER = 1;
|
||||||
private static long saveSeed;
|
private static long saveSeed;
|
||||||
private static List<Long> prevSaveSeeds = new ArrayList<>(); // Save Seeds that have been used in the past, stored to decode brews made at that time
|
private static List<Long> prevSaveSeeds = new ArrayList<>(); // Save Seeds that have been used in the past, stored to decode brews made at that time
|
||||||
public static Map<Integer, Brew> legacyPotions = new HashMap<>();
|
public static Map<Integer, Brew> legacyPotions = new HashMap<>();
|
||||||
@ -207,10 +210,10 @@ public class Brew {
|
|||||||
if (!immutable) {
|
if (!immutable) {
|
||||||
this.quality = calcQuality();
|
this.quality = calcQuality();
|
||||||
}
|
}
|
||||||
P.p.log("Brew was made from Recipe: '" + name + "' which could not be found. '" + currentRecipe.getRecipeName() + "' used instead!");
|
P.p.log("A Brew was made from Recipe: '" + name + "' which could not be found. '" + currentRecipe.getRecipeName() + "' used instead!");
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
P.p.errorLog("Brew was made from Recipe: '" + name + "' which could not be found!");
|
P.p.errorLog("A Brew was made from Recipe: '" + name + "' which could not be found!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -570,7 +573,9 @@ public class Brew {
|
|||||||
recipe.getColor().colorBrew(potionMeta, item, canDistill());
|
recipe.getColor().colorBrew(potionMeta, item, canDistill());
|
||||||
} else {
|
} else {
|
||||||
quality = 0;
|
quality = 0;
|
||||||
|
lore.convertLore(false);
|
||||||
lore.removeEffects();
|
lore.removeEffects();
|
||||||
|
currentRecipe = null;
|
||||||
potionMeta.setDisplayName(P.p.color("&f" + P.p.languageReader.get("Brew_BadPotion")));
|
potionMeta.setDisplayName(P.p.color("&f" + P.p.languageReader.get("Brew_BadPotion")));
|
||||||
PotionColor.GREY.colorBrew(potionMeta, item, canDistill());
|
PotionColor.GREY.colorBrew(potionMeta, item, canDistill());
|
||||||
}
|
}
|
||||||
@ -714,7 +719,7 @@ public class Brew {
|
|||||||
case 1:
|
case 1:
|
||||||
|
|
||||||
unscrambler.start();
|
unscrambler.start();
|
||||||
brew.loadFromStream(in);
|
brew.loadFromStream(in, ver);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -748,7 +753,7 @@ public class Brew {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadFromStream(DataInputStream in) throws IOException {
|
private void loadFromStream(DataInputStream in, byte dataVersion) throws IOException {
|
||||||
quality = in.readByte();
|
quality = in.readByte();
|
||||||
int bools = in.readUnsignedByte();
|
int bools = in.readUnsignedByte();
|
||||||
if ((bools & 1) != 0) {
|
if ((bools & 1) != 0) {
|
||||||
@ -767,7 +772,7 @@ public class Brew {
|
|||||||
unlabeled = (bools & 16) != 0;
|
unlabeled = (bools & 16) != 0;
|
||||||
//persistent = (bools & 32) != 0;
|
//persistent = (bools & 32) != 0;
|
||||||
immutable = (bools & 32) != 0;
|
immutable = (bools & 32) != 0;
|
||||||
ingredients = BIngredients.load(in);
|
ingredients = BIngredients.load(in, dataVersion);
|
||||||
setRecipeFromString(recipe);
|
setRecipeFromString(recipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -782,7 +787,7 @@ public class Brew {
|
|||||||
XORScrambleStream scrambler = new XORScrambleStream(itemSaveStream, saveSeed);
|
XORScrambleStream scrambler = new XORScrambleStream(itemSaveStream, saveSeed);
|
||||||
try (DataOutputStream out = new DataOutputStream(scrambler)) {
|
try (DataOutputStream out = new DataOutputStream(scrambler)) {
|
||||||
out.writeByte(86); // Parity/sanity
|
out.writeByte(86); // Parity/sanity
|
||||||
out.writeByte(1); // Version
|
out.writeByte(SAVE_VER); // Version
|
||||||
if (BConfig.enableEncode) {
|
if (BConfig.enableEncode) {
|
||||||
scrambler.start();
|
scrambler.start();
|
||||||
} else {
|
} else {
|
||||||
@ -890,6 +895,7 @@ public class Brew {
|
|||||||
public void convertPre19(ItemStack item) {
|
public void convertPre19(ItemStack item) {
|
||||||
removeLegacy(item);
|
removeLegacy(item);
|
||||||
PotionMeta potionMeta = ((PotionMeta) item.getItemMeta());
|
PotionMeta potionMeta = ((PotionMeta) item.getItemMeta());
|
||||||
|
assert potionMeta != null;
|
||||||
if (hasRecipe()) {
|
if (hasRecipe()) {
|
||||||
BrewLore lore = new BrewLore(this, potionMeta);
|
BrewLore lore = new BrewLore(this, potionMeta);
|
||||||
lore.removeEffects();
|
lore.removeEffects();
|
||||||
@ -905,8 +911,7 @@ public class Brew {
|
|||||||
|
|
||||||
// Saves all data
|
// Saves all data
|
||||||
// Legacy method to save to data file
|
// Legacy method to save to data file
|
||||||
@Deprecated
|
public static void saveLegacy(ConfigurationSection config) {
|
||||||
public static void save(ConfigurationSection config) {
|
|
||||||
for (Map.Entry<Integer, Brew> entry : legacyPotions.entrySet()) {
|
for (Map.Entry<Integer, Brew> entry : legacyPotions.entrySet()) {
|
||||||
int uid = entry.getKey();
|
int uid = entry.getKey();
|
||||||
Brew brew = entry.getValue();
|
Brew brew = entry.getValue();
|
||||||
@ -940,7 +945,7 @@ public class Brew {
|
|||||||
idConfig.set("lastUpdate", brew.lastUpdate);
|
idConfig.set("lastUpdate", brew.lastUpdate);
|
||||||
}
|
}
|
||||||
// save the ingredients
|
// save the ingredients
|
||||||
idConfig.set("ingId", brew.ingredients.save(config.getParent()));
|
idConfig.set("ingId", brew.ingredients.saveLegacy(config.getParent()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,8 +6,10 @@ import com.dre.brewery.filedata.DataSave;
|
|||||||
import com.dre.brewery.filedata.LanguageReader;
|
import com.dre.brewery.filedata.LanguageReader;
|
||||||
import com.dre.brewery.filedata.UpdateChecker;
|
import com.dre.brewery.filedata.UpdateChecker;
|
||||||
import com.dre.brewery.integration.IntegrationListener;
|
import com.dre.brewery.integration.IntegrationListener;
|
||||||
import com.dre.brewery.integration.LogBlockBarrel;
|
import com.dre.brewery.integration.barrel.LogBlockBarrel;
|
||||||
import com.dre.brewery.listeners.*;
|
import com.dre.brewery.listeners.*;
|
||||||
|
import com.dre.brewery.recipe.BCauldronRecipe;
|
||||||
|
import com.dre.brewery.recipe.BRecipe;
|
||||||
import com.dre.brewery.utility.BUtil;
|
import com.dre.brewery.utility.BUtil;
|
||||||
import com.dre.brewery.utility.LegacyUtil;
|
import com.dre.brewery.utility.LegacyUtil;
|
||||||
import org.apache.commons.lang.math.NumberUtils;
|
import org.apache.commons.lang.math.NumberUtils;
|
||||||
@ -442,8 +444,12 @@ public class P extends JavaPlugin {
|
|||||||
BCauldron.bcauldrons.clear();
|
BCauldron.bcauldrons.clear();
|
||||||
BRecipe.recipes.clear();
|
BRecipe.recipes.clear();
|
||||||
BCauldronRecipe.acceptedMaterials.clear();
|
BCauldronRecipe.acceptedMaterials.clear();
|
||||||
|
BCauldronRecipe.acceptedCustom.clear();
|
||||||
|
BCauldronRecipe.acceptedSimple.clear();
|
||||||
BCauldronRecipe.recipes.clear();
|
BCauldronRecipe.recipes.clear();
|
||||||
BConfig.customItems.clear();
|
BConfig.customItems.clear();
|
||||||
|
BConfig.hasSlimefun = null;
|
||||||
|
BConfig.hasMMOItems = null;
|
||||||
BPlayer.clear();
|
BPlayer.clear();
|
||||||
Brew.legacyPotions.clear();
|
Brew.legacyPotions.clear();
|
||||||
Wakeup.wakeups.clear();
|
Wakeup.wakeups.clear();
|
||||||
@ -461,8 +467,12 @@ public class P extends JavaPlugin {
|
|||||||
// clear all existent config Data
|
// clear all existent config Data
|
||||||
BRecipe.recipes.clear();
|
BRecipe.recipes.clear();
|
||||||
BCauldronRecipe.acceptedMaterials.clear();
|
BCauldronRecipe.acceptedMaterials.clear();
|
||||||
|
BCauldronRecipe.acceptedCustom.clear();
|
||||||
|
BCauldronRecipe.acceptedSimple.clear();
|
||||||
BCauldronRecipe.recipes.clear();
|
BCauldronRecipe.recipes.clear();
|
||||||
BConfig.customItems.clear();
|
BConfig.customItems.clear();
|
||||||
|
BConfig.hasSlimefun = null;
|
||||||
|
BConfig.hasMMOItems = null;
|
||||||
DistortChat.words.clear();
|
DistortChat.words.clear();
|
||||||
DistortChat.ignoreText.clear();
|
DistortChat.ignoreText.clear();
|
||||||
DistortChat.commands = null;
|
DistortChat.commands = null;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package com.dre.brewery.api;
|
package com.dre.brewery.api;
|
||||||
|
|
||||||
import com.dre.brewery.BCauldron;
|
import com.dre.brewery.BCauldron;
|
||||||
import com.dre.brewery.BRecipe;
|
import com.dre.brewery.recipe.BRecipe;
|
||||||
import com.dre.brewery.Barrel;
|
import com.dre.brewery.Barrel;
|
||||||
import com.dre.brewery.Brew;
|
import com.dre.brewery.Brew;
|
||||||
import org.apache.commons.lang.NotImplementedException;
|
import org.apache.commons.lang.NotImplementedException;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.dre.brewery.api.events;
|
package com.dre.brewery.api.events;
|
||||||
|
|
||||||
import com.dre.brewery.BCauldron;
|
import com.dre.brewery.BCauldron;
|
||||||
|
import com.dre.brewery.recipe.RecipeItem;
|
||||||
import com.dre.brewery.utility.LegacyUtil;
|
import com.dre.brewery.utility.LegacyUtil;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
@ -21,14 +22,16 @@ public class IngedientAddEvent extends PlayerEvent implements Cancellable {
|
|||||||
private final Block block;
|
private final Block block;
|
||||||
private final BCauldron cauldron;
|
private final BCauldron cauldron;
|
||||||
private ItemStack ingredient;
|
private ItemStack ingredient;
|
||||||
|
private RecipeItem rItem;
|
||||||
private boolean cancelled;
|
private boolean cancelled;
|
||||||
private boolean takeItem = true;
|
private boolean takeItem = true;
|
||||||
|
|
||||||
public IngedientAddEvent(Player who, Block block, BCauldron bCauldron, ItemStack ingredient) {
|
public IngedientAddEvent(Player who, Block block, BCauldron bCauldron, ItemStack ingredient, RecipeItem rItem) {
|
||||||
super(who);
|
super(who);
|
||||||
this.block = block;
|
this.block = block;
|
||||||
cauldron = bCauldron;
|
cauldron = bCauldron;
|
||||||
this.ingredient = ingredient.clone();
|
this.rItem = rItem;
|
||||||
|
this.ingredient = ingredient;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Block getBlock() {
|
public Block getBlock() {
|
||||||
@ -39,6 +42,15 @@ public class IngedientAddEvent extends PlayerEvent implements Cancellable {
|
|||||||
return cauldron;
|
return cauldron;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Recipe item that matches the ingredient.
|
||||||
|
* This might not be the only recipe item that will match the ingredient
|
||||||
|
* Will be recalculated if the Ingredient is changed with the setIngredient Method
|
||||||
|
*/
|
||||||
|
public RecipeItem getRecipeItem() {
|
||||||
|
return rItem;
|
||||||
|
}
|
||||||
|
|
||||||
// Get the item currently being added to the cauldron by the player
|
// Get the item currently being added to the cauldron by the player
|
||||||
// Can be changed directly (mutable) or with the setter Method
|
// Can be changed directly (mutable) or with the setter Method
|
||||||
// The amount is ignored and always one added
|
// The amount is ignored and always one added
|
||||||
@ -49,8 +61,11 @@ public class IngedientAddEvent extends PlayerEvent implements Cancellable {
|
|||||||
// Set the ingredient added to the cauldron to something else
|
// Set the ingredient added to the cauldron to something else
|
||||||
// Will always be accepted, even when not in a recipe or the cooked list
|
// Will always be accepted, even when not in a recipe or the cooked list
|
||||||
// The amount is ignored and always one added
|
// The amount is ignored and always one added
|
||||||
|
// This also recalculates the recipeItem!
|
||||||
public void setIngredient(ItemStack ingredient) {
|
public void setIngredient(ItemStack ingredient) {
|
||||||
this.ingredient = ingredient;
|
this.ingredient = ingredient;
|
||||||
|
// The Ingredient has been changed. Recalculate RecipeItem!
|
||||||
|
rItem = RecipeItem.getMatchingRecipeItem(ingredient, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the amount of the item in the players hand should be decreased
|
// If the amount of the item in the players hand should be decreased
|
||||||
|
@ -1,18 +1,29 @@
|
|||||||
package com.dre.brewery.filedata;
|
package com.dre.brewery.filedata;
|
||||||
|
|
||||||
import com.dre.brewery.*;
|
import com.dre.brewery.Brew;
|
||||||
import com.dre.brewery.integration.WGBarrel;
|
import com.dre.brewery.DistortChat;
|
||||||
import com.dre.brewery.integration.WGBarrel5;
|
import com.dre.brewery.MCBarrel;
|
||||||
import com.dre.brewery.integration.WGBarrel6;
|
import com.dre.brewery.P;
|
||||||
import com.dre.brewery.integration.WGBarrel7;
|
import com.dre.brewery.integration.barrel.WGBarrel;
|
||||||
|
import com.dre.brewery.integration.barrel.WGBarrel5;
|
||||||
|
import com.dre.brewery.integration.barrel.WGBarrel6;
|
||||||
|
import com.dre.brewery.integration.barrel.WGBarrel7;
|
||||||
|
import com.dre.brewery.integration.item.BreweryPluginItem;
|
||||||
|
import com.dre.brewery.integration.item.MMOItemsPluginItem;
|
||||||
|
import com.dre.brewery.integration.item.SlimefunPluginItem;
|
||||||
|
import com.dre.brewery.recipe.BCauldronRecipe;
|
||||||
|
import com.dre.brewery.recipe.BRecipe;
|
||||||
|
import com.dre.brewery.recipe.PluginItem;
|
||||||
|
import com.dre.brewery.recipe.RecipeItem;
|
||||||
import com.dre.brewery.utility.BUtil;
|
import com.dre.brewery.utility.BUtil;
|
||||||
import com.dre.brewery.utility.CustomItem;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.bukkit.plugin.PluginManager;
|
import org.bukkit.plugin.PluginManager;
|
||||||
|
|
||||||
@ -38,6 +49,8 @@ public class BConfig {
|
|||||||
public static boolean useGP; //GriefPrevention
|
public static boolean useGP; //GriefPrevention
|
||||||
public static boolean hasVault; // Vault
|
public static boolean hasVault; // Vault
|
||||||
public static boolean useCitadel; // CivCraft/DevotedMC Citadel
|
public static boolean useCitadel; // CivCraft/DevotedMC Citadel
|
||||||
|
public static Boolean hasSlimefun = null; // Slimefun ; Null if not checked
|
||||||
|
public static Boolean hasMMOItems = null; // MMOItems ; Null if not checked
|
||||||
|
|
||||||
// Barrel
|
// Barrel
|
||||||
public static boolean openEverywhere;
|
public static boolean openEverywhere;
|
||||||
@ -61,7 +74,7 @@ public class BConfig {
|
|||||||
public static boolean alwaysShowAlc; // Always show alc%
|
public static boolean alwaysShowAlc; // Always show alc%
|
||||||
|
|
||||||
//Item
|
//Item
|
||||||
public static List<CustomItem> customItems = new ArrayList<>();
|
public static List<RecipeItem> customItems = new ArrayList<>();
|
||||||
|
|
||||||
public static P p = P.p;
|
public static P p = P.p;
|
||||||
|
|
||||||
@ -189,12 +202,18 @@ public class BConfig {
|
|||||||
|
|
||||||
Brew.loadSeed(config, file);
|
Brew.loadSeed(config, file);
|
||||||
|
|
||||||
|
PluginItem.registerForConfig("brewery", BreweryPluginItem::new);
|
||||||
|
PluginItem.registerForConfig("mmoitems", MMOItemsPluginItem::new);
|
||||||
|
PluginItem.registerForConfig("slimefun", SlimefunPluginItem::new);
|
||||||
|
PluginItem.registerForConfig("exoticgarden", SlimefunPluginItem::new);
|
||||||
|
|
||||||
// Loading custom items
|
// Loading custom items
|
||||||
ConfigurationSection configSection = config.getConfigurationSection("customItems");
|
ConfigurationSection configSection = config.getConfigurationSection("customItems");
|
||||||
if (configSection != null) {
|
if (configSection != null) {
|
||||||
for (String custId : configSection.getKeys(false)) {
|
for (String custId : configSection.getKeys(false)) {
|
||||||
CustomItem custom = CustomItem.fromConfig(configSection, custId);
|
RecipeItem custom = RecipeItem.fromConfigCustom(configSection, custId);
|
||||||
if (custom != null) {
|
if (custom != null) {
|
||||||
|
custom.makeImmutable();
|
||||||
customItems.add(custom);
|
customItems.add(custom);
|
||||||
} else {
|
} else {
|
||||||
p.errorLog("Loading the Custom Item with id: '" + custId + "' failed!");
|
p.errorLog("Loading the Custom Item with id: '" + custId + "' failed!");
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
package com.dre.brewery.filedata;
|
package com.dre.brewery.filedata;
|
||||||
|
|
||||||
import com.dre.brewery.*;
|
import com.dre.brewery.*;
|
||||||
|
import com.dre.brewery.lore.Base91DecoderStream;
|
||||||
|
import com.dre.brewery.recipe.CustomItem;
|
||||||
|
import com.dre.brewery.recipe.Ingredient;
|
||||||
|
import com.dre.brewery.recipe.PluginItem;
|
||||||
|
import com.dre.brewery.recipe.SimpleItem;
|
||||||
import com.dre.brewery.utility.BUtil;
|
import com.dre.brewery.utility.BUtil;
|
||||||
import com.dre.brewery.utility.BoundingBox;
|
import com.dre.brewery.utility.BoundingBox;
|
||||||
import org.apache.commons.lang.ArrayUtils;
|
import org.apache.commons.lang.ArrayUtils;
|
||||||
@ -12,14 +17,12 @@ import org.bukkit.block.Block;
|
|||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.DataInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class BData {
|
public class BData {
|
||||||
|
|
||||||
@ -47,18 +50,30 @@ public class BData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Register Item Loaders
|
||||||
|
CustomItem.registerItemLoader();
|
||||||
|
SimpleItem.registerItemLoader();
|
||||||
|
PluginItem.registerItemLoader();
|
||||||
|
|
||||||
// loading Ingredients into ingMap
|
// loading Ingredients into ingMap
|
||||||
|
// Only for Legacy Brews
|
||||||
Map<String, BIngredients> ingMap = new HashMap<>();
|
Map<String, BIngredients> ingMap = new HashMap<>();
|
||||||
ConfigurationSection section = data.getConfigurationSection("Ingredients");
|
ConfigurationSection section = data.getConfigurationSection("Ingredients");
|
||||||
if (section != null) {
|
if (section != null) {
|
||||||
for (String id : section.getKeys(false)) {
|
for (String id : section.getKeys(false)) {
|
||||||
ConfigurationSection matSection = section.getConfigurationSection(id + ".mats");
|
if (section.isConfigurationSection(id + ".mats")) {
|
||||||
if (matSection != null) {
|
// Old way of saving
|
||||||
// matSection has all the materials + amount as Integers
|
ConfigurationSection matSection = section.getConfigurationSection(id + ".mats");
|
||||||
ArrayList<ItemStack> ingredients = deserializeIngredients(matSection);
|
if (matSection != null) {
|
||||||
ingMap.put(id, new BIngredients(ingredients, section.getInt(id + ".cookedTime", 0), true));
|
// matSection has all the materials + amount as Integers
|
||||||
|
List<Ingredient> ingredients = oldDeserializeIngredients(matSection);
|
||||||
|
ingMap.put(id, new BIngredients(ingredients, section.getInt(id + ".cookedTime", 0), true));
|
||||||
|
} else {
|
||||||
|
P.p.errorLog("Ingredient id: '" + id + "' incomplete in data.yml");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
P.p.errorLog("Ingredient id: '" + id + "' incomplete in data.yml");
|
// New way of saving ingredients
|
||||||
|
ingMap.put(id, deserializeIngredients(section.getString(id + ".mats")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,9 +125,9 @@ public class BData {
|
|||||||
|
|
||||||
for (World world : P.p.getServer().getWorlds()) {
|
for (World world : P.p.getServer().getWorlds()) {
|
||||||
if (world.getName().startsWith("DXL_")) {
|
if (world.getName().startsWith("DXL_")) {
|
||||||
loadWorldData(BUtil.getDxlName(world.getName()), world);
|
loadWorldData(BUtil.getDxlName(world.getName()), world, data);
|
||||||
} else {
|
} else {
|
||||||
loadWorldData(world.getUID().toString(), world);
|
loadWorldData(world.getUID().toString(), world, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,8 +136,19 @@ public class BData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ArrayList<ItemStack> deserializeIngredients(ConfigurationSection matSection) {
|
public static BIngredients deserializeIngredients(String mat) {
|
||||||
ArrayList<ItemStack> ingredients = new ArrayList<>();
|
try (DataInputStream in = new DataInputStream(new Base91DecoderStream(new ByteArrayInputStream(mat.getBytes())))) {
|
||||||
|
byte ver = in.readByte();
|
||||||
|
return BIngredients.load(in, ver);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return new BIngredients();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loading from the old way of saving ingredients
|
||||||
|
public static List<Ingredient> oldDeserializeIngredients(ConfigurationSection matSection) {
|
||||||
|
List<Ingredient> ingredients = new ArrayList<>();
|
||||||
for (String mat : matSection.getKeys(false)) {
|
for (String mat : matSection.getKeys(false)) {
|
||||||
String[] matSplit = mat.split(",");
|
String[] matSplit = mat.split(",");
|
||||||
Material m = Material.getMaterial(matSplit[0]);
|
Material m = Material.getMaterial(matSplit[0]);
|
||||||
@ -135,10 +161,13 @@ public class BData {
|
|||||||
P.p.debugLog("converting Data Material from " + matSplit[0] + " to " + m);
|
P.p.debugLog("converting Data Material from " + matSplit[0] + " to " + m);
|
||||||
}
|
}
|
||||||
if (m == null) continue;
|
if (m == null) continue;
|
||||||
ItemStack item = new ItemStack(m, matSection.getInt(mat));
|
SimpleItem item;
|
||||||
if (matSplit.length == 2) {
|
if (matSplit.length == 2) {
|
||||||
item.setDurability((short) P.p.parseInt(matSplit[1]));
|
item = new SimpleItem(m, (short) P.p.parseInt(matSplit[1]));
|
||||||
|
} else {
|
||||||
|
item = new SimpleItem(m);
|
||||||
}
|
}
|
||||||
|
item.setAmount(matSection.getInt(mat));
|
||||||
ingredients.add(item);
|
ingredients.add(item);
|
||||||
}
|
}
|
||||||
return ingredients;
|
return ingredients;
|
||||||
@ -156,134 +185,146 @@ public class BData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// loads BIngredients from an ingredient section
|
// loads BIngredients from an ingredient section
|
||||||
public static BIngredients loadIngredients(ConfigurationSection section) {
|
public static BIngredients loadCauldronIng(ConfigurationSection section, String path) {
|
||||||
if (section != null) {
|
if (section.isConfigurationSection(path)) {
|
||||||
return new BIngredients(deserializeIngredients(section), 0);
|
// Old way of saving
|
||||||
|
ConfigurationSection matSection = section.getConfigurationSection(path);
|
||||||
|
if (matSection != null) {
|
||||||
|
// matSection has all the materials + amount as Integers
|
||||||
|
return new BIngredients(oldDeserializeIngredients(section), 0);
|
||||||
|
} else {
|
||||||
|
P.p.errorLog("Cauldron is missing Ingredient Section");
|
||||||
|
return new BIngredients();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
P.p.errorLog("Cauldron is missing Ingredient Section");
|
// New way of saving ingredients
|
||||||
|
return deserializeIngredients(section.getString(path));
|
||||||
}
|
}
|
||||||
return new BIngredients();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// load Block locations of given world
|
// load Block locations of given world
|
||||||
public static void loadWorldData(String uuid, World world) {
|
public static void loadWorldData(String uuid, World world, FileConfiguration data) {
|
||||||
|
|
||||||
File file = new File(P.p.getDataFolder(), "data.yml");
|
if (data == null) {
|
||||||
if (file.exists()) {
|
File file = new File(P.p.getDataFolder(), "data.yml");
|
||||||
|
if (file.exists()) {
|
||||||
FileConfiguration data = YamlConfiguration.loadConfiguration(file);
|
data = YamlConfiguration.loadConfiguration(file);
|
||||||
|
} else {
|
||||||
// loading BCauldron
|
return;
|
||||||
if (data.contains("BCauldron." + uuid)) {
|
|
||||||
ConfigurationSection section = data.getConfigurationSection("BCauldron." + uuid);
|
|
||||||
for (String cauldron : section.getKeys(false)) {
|
|
||||||
// block is splitted into x/y/z
|
|
||||||
String block = section.getString(cauldron + ".block");
|
|
||||||
if (block != null) {
|
|
||||||
String[] splitted = block.split("/");
|
|
||||||
if (splitted.length == 3) {
|
|
||||||
|
|
||||||
Block worldBlock = world.getBlockAt(P.p.parseInt(splitted[0]), P.p.parseInt(splitted[1]), P.p.parseInt(splitted[2]));
|
|
||||||
BIngredients ingredients = loadIngredients(section.getConfigurationSection(cauldron + ".ingredients"));
|
|
||||||
int state = section.getInt(cauldron + ".state", 1);
|
|
||||||
|
|
||||||
new BCauldron(worldBlock, ingredients, state);
|
|
||||||
} else {
|
|
||||||
P.p.errorLog("Incomplete Block-Data in data.yml: " + section.getCurrentPath() + "." + cauldron);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
P.p.errorLog("Missing Block-Data in data.yml: " + section.getCurrentPath() + "." + cauldron);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// loading Barrel
|
|
||||||
if (data.contains("Barrel." + uuid)) {
|
|
||||||
ConfigurationSection section = data.getConfigurationSection("Barrel." + uuid);
|
|
||||||
for (String barrel : section.getKeys(false)) {
|
|
||||||
// block spigot is splitted into x/y/z
|
|
||||||
String spigot = section.getString(barrel + ".spigot");
|
|
||||||
if (spigot != null) {
|
|
||||||
String[] splitted = spigot.split("/");
|
|
||||||
if (splitted.length == 3) {
|
|
||||||
|
|
||||||
// load itemStacks from invSection
|
|
||||||
ConfigurationSection invSection = section.getConfigurationSection(barrel + ".inv");
|
|
||||||
Block block = world.getBlockAt(P.p.parseInt(splitted[0]), P.p.parseInt(splitted[1]), P.p.parseInt(splitted[2]));
|
|
||||||
float time = (float) section.getDouble(barrel + ".time", 0.0);
|
|
||||||
byte sign = (byte) section.getInt(barrel + ".sign", 0);
|
|
||||||
|
|
||||||
BoundingBox box = null;
|
|
||||||
if (section.contains(barrel + ".bounds")) {
|
|
||||||
String[] bds = section.getString(barrel + ".bounds", "").split(",");
|
|
||||||
if (bds.length == 6) {
|
|
||||||
box = new BoundingBox(P.p.parseInt(bds[0]), P.p.parseInt(bds[1]), P.p.parseInt(bds[2]), P.p.parseInt(bds[3]), P.p.parseInt(bds[4]), P.p.parseInt(bds[5]));
|
|
||||||
}
|
|
||||||
} else if (section.contains(barrel + ".st")) {
|
|
||||||
// Convert from Stair and Wood Locations to BoundingBox
|
|
||||||
String[] st = section.getString(barrel + ".st", "").split(",");
|
|
||||||
String[] wo = section.getString(barrel + ".wo", "").split(",");
|
|
||||||
int woLength = wo.length;
|
|
||||||
if (woLength <= 1) {
|
|
||||||
woLength = 0;
|
|
||||||
}
|
|
||||||
String[] points = new String[st.length + woLength];
|
|
||||||
System.arraycopy(st, 0, points, 0, st.length);
|
|
||||||
if (woLength > 1) {
|
|
||||||
System.arraycopy(wo, 0, points, st.length, woLength);
|
|
||||||
}
|
|
||||||
int[] locs = ArrayUtils.toPrimitive(Arrays.stream(points).map(s -> P.p.parseInt(s)).toArray(Integer[]::new));
|
|
||||||
box = BoundingBox.fromPoints(locs);
|
|
||||||
}
|
|
||||||
|
|
||||||
Barrel b;
|
|
||||||
if (invSection != null) {
|
|
||||||
b = new Barrel(block, sign, box, invSection.getValues(true), time);
|
|
||||||
} else {
|
|
||||||
// Barrel has no inventory
|
|
||||||
b = new Barrel(block, sign, box, null, time);
|
|
||||||
}
|
|
||||||
|
|
||||||
// In case Barrel Block locations were missing and could not be recreated: do not add the barrel
|
|
||||||
if (b.getBody().getBounds() != null) {
|
|
||||||
Barrel.barrels.add(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
P.p.errorLog("Incomplete Block-Data in data.yml: " + section.getCurrentPath() + "." + barrel);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
P.p.errorLog("Missing Block-Data in data.yml: " + section.getCurrentPath() + "." + barrel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// loading Wakeup
|
|
||||||
if (data.contains("Wakeup." + uuid)) {
|
|
||||||
ConfigurationSection section = data.getConfigurationSection("Wakeup." + uuid);
|
|
||||||
for (String wakeup : section.getKeys(false)) {
|
|
||||||
// loc of wakeup is splitted into x/y/z/pitch/yaw
|
|
||||||
String loc = section.getString(wakeup);
|
|
||||||
if (loc != null) {
|
|
||||||
String[] splitted = loc.split("/");
|
|
||||||
if (splitted.length == 5) {
|
|
||||||
|
|
||||||
double x = NumberUtils.toDouble(splitted[0]);
|
|
||||||
double y = NumberUtils.toDouble(splitted[1]);
|
|
||||||
double z = NumberUtils.toDouble(splitted[2]);
|
|
||||||
float pitch = NumberUtils.toFloat(splitted[3]);
|
|
||||||
float yaw = NumberUtils.toFloat(splitted[4]);
|
|
||||||
Location location = new Location(world, x, y, z, yaw, pitch);
|
|
||||||
|
|
||||||
Wakeup.wakeups.add(new Wakeup(location));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
P.p.errorLog("Incomplete Location-Data in data.yml: " + section.getCurrentPath() + "." + wakeup);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// loading BCauldron
|
||||||
|
if (data.contains("BCauldron." + uuid)) {
|
||||||
|
ConfigurationSection section = data.getConfigurationSection("BCauldron." + uuid);
|
||||||
|
for (String cauldron : section.getKeys(false)) {
|
||||||
|
// block is splitted into x/y/z
|
||||||
|
String block = section.getString(cauldron + ".block");
|
||||||
|
if (block != null) {
|
||||||
|
String[] splitted = block.split("/");
|
||||||
|
if (splitted.length == 3) {
|
||||||
|
|
||||||
|
Block worldBlock = world.getBlockAt(P.p.parseInt(splitted[0]), P.p.parseInt(splitted[1]), P.p.parseInt(splitted[2]));
|
||||||
|
BIngredients ingredients = loadCauldronIng(section, cauldron + ".ingredients");
|
||||||
|
int state = section.getInt(cauldron + ".state", 1);
|
||||||
|
|
||||||
|
new BCauldron(worldBlock, ingredients, state);
|
||||||
|
} else {
|
||||||
|
P.p.errorLog("Incomplete Block-Data in data.yml: " + section.getCurrentPath() + "." + cauldron);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
P.p.errorLog("Missing Block-Data in data.yml: " + section.getCurrentPath() + "." + cauldron);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// loading Barrel
|
||||||
|
if (data.contains("Barrel." + uuid)) {
|
||||||
|
ConfigurationSection section = data.getConfigurationSection("Barrel." + uuid);
|
||||||
|
for (String barrel : section.getKeys(false)) {
|
||||||
|
// block spigot is splitted into x/y/z
|
||||||
|
String spigot = section.getString(barrel + ".spigot");
|
||||||
|
if (spigot != null) {
|
||||||
|
String[] splitted = spigot.split("/");
|
||||||
|
if (splitted.length == 3) {
|
||||||
|
|
||||||
|
// load itemStacks from invSection
|
||||||
|
ConfigurationSection invSection = section.getConfigurationSection(barrel + ".inv");
|
||||||
|
Block block = world.getBlockAt(P.p.parseInt(splitted[0]), P.p.parseInt(splitted[1]), P.p.parseInt(splitted[2]));
|
||||||
|
float time = (float) section.getDouble(barrel + ".time", 0.0);
|
||||||
|
byte sign = (byte) section.getInt(barrel + ".sign", 0);
|
||||||
|
|
||||||
|
BoundingBox box = null;
|
||||||
|
if (section.contains(barrel + ".bounds")) {
|
||||||
|
String[] bds = section.getString(barrel + ".bounds", "").split(",");
|
||||||
|
if (bds.length == 6) {
|
||||||
|
box = new BoundingBox(P.p.parseInt(bds[0]), P.p.parseInt(bds[1]), P.p.parseInt(bds[2]), P.p.parseInt(bds[3]), P.p.parseInt(bds[4]), P.p.parseInt(bds[5]));
|
||||||
|
}
|
||||||
|
} else if (section.contains(barrel + ".st")) {
|
||||||
|
// Convert from Stair and Wood Locations to BoundingBox
|
||||||
|
String[] st = section.getString(barrel + ".st", "").split(",");
|
||||||
|
String[] wo = section.getString(barrel + ".wo", "").split(",");
|
||||||
|
int woLength = wo.length;
|
||||||
|
if (woLength <= 1) {
|
||||||
|
woLength = 0;
|
||||||
|
}
|
||||||
|
String[] points = new String[st.length + woLength];
|
||||||
|
System.arraycopy(st, 0, points, 0, st.length);
|
||||||
|
if (woLength > 1) {
|
||||||
|
System.arraycopy(wo, 0, points, st.length, woLength);
|
||||||
|
}
|
||||||
|
int[] locs = ArrayUtils.toPrimitive(Arrays.stream(points).map(s -> P.p.parseInt(s)).toArray(Integer[]::new));
|
||||||
|
box = BoundingBox.fromPoints(locs);
|
||||||
|
}
|
||||||
|
|
||||||
|
Barrel b;
|
||||||
|
if (invSection != null) {
|
||||||
|
b = new Barrel(block, sign, box, invSection.getValues(true), time);
|
||||||
|
} else {
|
||||||
|
// Barrel has no inventory
|
||||||
|
b = new Barrel(block, sign, box, null, time);
|
||||||
|
}
|
||||||
|
|
||||||
|
// In case Barrel Block locations were missing and could not be recreated: do not add the barrel
|
||||||
|
|
||||||
|
if (b.getBody().getBounds() != null) {
|
||||||
|
Barrel.barrels.add(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
P.p.errorLog("Incomplete Block-Data in data.yml: " + section.getCurrentPath() + "." + barrel);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
P.p.errorLog("Missing Block-Data in data.yml: " + section.getCurrentPath() + "." + barrel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// loading Wakeup
|
||||||
|
if (data.contains("Wakeup." + uuid)) {
|
||||||
|
ConfigurationSection section = data.getConfigurationSection("Wakeup." + uuid);
|
||||||
|
for (String wakeup : section.getKeys(false)) {
|
||||||
|
// loc of wakeup is splitted into x/y/z/pitch/yaw
|
||||||
|
String loc = section.getString(wakeup);
|
||||||
|
if (loc != null) {
|
||||||
|
String[] splitted = loc.split("/");
|
||||||
|
if (splitted.length == 5) {
|
||||||
|
|
||||||
|
double x = NumberUtils.toDouble(splitted[0]);
|
||||||
|
double y = NumberUtils.toDouble(splitted[1]);
|
||||||
|
double z = NumberUtils.toDouble(splitted[2]);
|
||||||
|
float pitch = NumberUtils.toFloat(splitted[3]);
|
||||||
|
float yaw = NumberUtils.toFloat(splitted[4]);
|
||||||
|
Location location = new Location(world, x, y, z, yaw, pitch);
|
||||||
|
|
||||||
|
Wakeup.wakeups.add(new Wakeup(location));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
P.p.errorLog("Incomplete Location-Data in data.yml: " + section.getCurrentPath() + "." + wakeup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ public class DataSave extends BukkitRunnable {
|
|||||||
Brew.writePrevSeeds(configFile);
|
Brew.writePrevSeeds(configFile);
|
||||||
|
|
||||||
if (!Brew.legacyPotions.isEmpty()) {
|
if (!Brew.legacyPotions.isEmpty()) {
|
||||||
Brew.save(configFile.createSection("Brew"));
|
Brew.saveLegacy(configFile.createSection("Brew"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!BCauldron.bcauldrons.isEmpty() || oldData.contains("BCauldron")) {
|
if (!BCauldron.bcauldrons.isEmpty() || oldData.contains("BCauldron")) {
|
||||||
|
@ -1,18 +1,30 @@
|
|||||||
package com.dre.brewery.integration;
|
package com.dre.brewery.integration;
|
||||||
|
|
||||||
import com.dre.brewery.Barrel;
|
import com.dre.brewery.Barrel;
|
||||||
import com.dre.brewery.utility.LegacyUtil;
|
|
||||||
import com.dre.brewery.P;
|
import com.dre.brewery.P;
|
||||||
import com.dre.brewery.api.events.barrel.BarrelAccessEvent;
|
import com.dre.brewery.api.events.barrel.BarrelAccessEvent;
|
||||||
import com.dre.brewery.api.events.barrel.BarrelDestroyEvent;
|
import com.dre.brewery.api.events.barrel.BarrelDestroyEvent;
|
||||||
import com.dre.brewery.api.events.barrel.BarrelRemoveEvent;
|
import com.dre.brewery.api.events.barrel.BarrelRemoveEvent;
|
||||||
import com.dre.brewery.filedata.BConfig;
|
import com.dre.brewery.filedata.BConfig;
|
||||||
|
import com.dre.brewery.integration.barrel.GriefPreventionBarrel;
|
||||||
|
import com.dre.brewery.integration.barrel.LWCBarrel;
|
||||||
|
import com.dre.brewery.integration.barrel.LogBlockBarrel;
|
||||||
|
import com.dre.brewery.integration.item.MMOItemsPluginItem;
|
||||||
|
import com.dre.brewery.recipe.BCauldronRecipe;
|
||||||
|
import com.dre.brewery.recipe.RecipeItem;
|
||||||
|
import com.dre.brewery.utility.LegacyUtil;
|
||||||
|
import net.Indyuce.mmoitems.MMOItems;
|
||||||
|
import net.Indyuce.mmoitems.api.item.NBTItem;
|
||||||
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.Action;
|
||||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
public class IntegrationListener implements Listener {
|
public class IntegrationListener implements Listener {
|
||||||
@ -173,4 +185,36 @@ public class IntegrationListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||||
|
public void onInteract(PlayerInteractEvent event) {
|
||||||
|
// Cancel the Interact Event early, so MMOItems does not act before us and consume the item when trying to add item to Cauldron
|
||||||
|
if (!P.use1_9) return;
|
||||||
|
if (BConfig.hasMMOItems == null) {
|
||||||
|
BConfig.hasMMOItems = P.p.getServer().getPluginManager().isPluginEnabled("MMOItems");
|
||||||
|
}
|
||||||
|
if (!BConfig.hasMMOItems) return;
|
||||||
|
try {
|
||||||
|
if (event.getAction() == Action.RIGHT_CLICK_BLOCK && event.hasItem() && event.getHand() == EquipmentSlot.HAND) {
|
||||||
|
if (event.getClickedBlock() != null && event.getClickedBlock().getType() == Material.CAULDRON) {
|
||||||
|
NBTItem item = MMOItems.plugin.getNMS().getNBTItem(event.getItem());
|
||||||
|
if (item.hasType()) {
|
||||||
|
for (RecipeItem rItem : BCauldronRecipe.acceptedCustom) {
|
||||||
|
if (rItem instanceof MMOItemsPluginItem) {
|
||||||
|
MMOItemsPluginItem mmo = ((MMOItemsPluginItem) rItem);
|
||||||
|
if (mmo.matches(event.getItem())) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
P.p.playerListener.onPlayerInteract(event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
P.p.errorLog("Could not check MMOItems for Item");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.dre.brewery.integration;
|
package com.dre.brewery.integration.barrel;
|
||||||
|
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -13,7 +13,7 @@ import vg.civcraft.mc.citadel.reinforcement.Reinforcement;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic Citadel support to prevent randos from stealing your barrel aging brews
|
* Basic Citadel support to prevent randos from stealing your barrel aging brews
|
||||||
*
|
*
|
||||||
* @author ProgrammerDan
|
* @author ProgrammerDan
|
||||||
*/
|
*/
|
||||||
public class CitadelBarrel {
|
public class CitadelBarrel {
|
||||||
@ -21,11 +21,11 @@ public class CitadelBarrel {
|
|||||||
|
|
||||||
public static boolean checkAccess(Player player, Block sign) {
|
public static boolean checkAccess(Player player, Block sign) {
|
||||||
ReinforcementManager manager = Citadel.getReinforcementManager();
|
ReinforcementManager manager = Citadel.getReinforcementManager();
|
||||||
|
|
||||||
Reinforcement rein = manager.getReinforcement(sign);
|
Reinforcement rein = manager.getReinforcement(sign);
|
||||||
|
|
||||||
if (rein == null) return true; // no protections in place.
|
if (rein == null) return true; // no protections in place.
|
||||||
|
|
||||||
if (rein instanceof PlayerReinforcement) {
|
if (rein instanceof PlayerReinforcement) {
|
||||||
PlayerReinforcement prein = (PlayerReinforcement) rein;
|
PlayerReinforcement prein = (PlayerReinforcement) rein;
|
||||||
if (prein.canAccessChests(player)) {
|
if (prein.canAccessChests(player)) {
|
||||||
@ -35,7 +35,7 @@ public class CitadelBarrel {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// no support for multiblock atm, would require namelayer support.
|
// no support for multiblock atm, would require namelayer support.
|
||||||
|
|
||||||
// special locked, or no access.
|
// special locked, or no access.
|
||||||
brewery.msg(player, brewery.languageReader.get("Error_NoBarrelAccess"));
|
brewery.msg(player, brewery.languageReader.get("Error_NoBarrelAccess"));
|
||||||
return false;
|
return false;
|
@ -1,4 +1,4 @@
|
|||||||
package com.dre.brewery.integration;
|
package com.dre.brewery.integration.barrel;
|
||||||
|
|
||||||
import com.dre.brewery.P;
|
import com.dre.brewery.P;
|
||||||
import com.dre.brewery.api.events.barrel.BarrelAccessEvent;
|
import com.dre.brewery.api.events.barrel.BarrelAccessEvent;
|
@ -1,4 +1,4 @@
|
|||||||
package com.dre.brewery.integration;
|
package com.dre.brewery.integration.barrel;
|
||||||
|
|
||||||
import com.dre.brewery.Barrel;
|
import com.dre.brewery.Barrel;
|
||||||
import com.dre.brewery.P;
|
import com.dre.brewery.P;
|
@ -1,4 +1,4 @@
|
|||||||
package com.dre.brewery.integration;
|
package com.dre.brewery.integration.barrel;
|
||||||
|
|
||||||
import com.dre.brewery.utility.LegacyUtil;
|
import com.dre.brewery.utility.LegacyUtil;
|
||||||
import com.dre.brewery.P;
|
import com.dre.brewery.P;
|
@ -1,4 +1,4 @@
|
|||||||
package com.dre.brewery.integration;
|
package com.dre.brewery.integration.barrel;
|
||||||
|
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
@ -1,4 +1,4 @@
|
|||||||
package com.dre.brewery.integration;
|
package com.dre.brewery.integration.barrel;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
@ -1,4 +1,4 @@
|
|||||||
package com.dre.brewery.integration;
|
package com.dre.brewery.integration.barrel;
|
||||||
|
|
||||||
|
|
||||||
import com.sk89q.worldguard.bukkit.RegionQuery;
|
import com.sk89q.worldguard.bukkit.RegionQuery;
|
@ -1,4 +1,4 @@
|
|||||||
package com.dre.brewery.integration;
|
package com.dre.brewery.integration.barrel;
|
||||||
|
|
||||||
|
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
30
src/com/dre/brewery/integration/item/BreweryPluginItem.java
Normal file
30
src/com/dre/brewery/integration/item/BreweryPluginItem.java
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package com.dre.brewery.integration.item;
|
||||||
|
|
||||||
|
import com.dre.brewery.Brew;
|
||||||
|
import com.dre.brewery.recipe.BRecipe;
|
||||||
|
import com.dre.brewery.recipe.PluginItem;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For recipes that use Brewery Items as input
|
||||||
|
*/
|
||||||
|
public class BreweryPluginItem extends PluginItem {
|
||||||
|
|
||||||
|
// When implementing this, put Brewery as softdepend in your plugin.yml!
|
||||||
|
// We're calling this as server start:
|
||||||
|
// PluginItem.registerForConfig("brewery", BreweryPluginItem::new);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(ItemStack item) {
|
||||||
|
Brew brew = Brew.get(item);
|
||||||
|
if (brew != null) {
|
||||||
|
BRecipe recipe = brew.getCurrentRecipe();
|
||||||
|
if (recipe != null) {
|
||||||
|
return recipe.getRecipeName().equalsIgnoreCase(getItemId()) || recipe.getName(10).equalsIgnoreCase(getItemId());
|
||||||
|
}
|
||||||
|
return ChatColor.stripColor(item.getItemMeta().getDisplayName()).equalsIgnoreCase(getItemId());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
32
src/com/dre/brewery/integration/item/MMOItemsPluginItem.java
Normal file
32
src/com/dre/brewery/integration/item/MMOItemsPluginItem.java
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package com.dre.brewery.integration.item;
|
||||||
|
|
||||||
|
import com.dre.brewery.P;
|
||||||
|
import com.dre.brewery.filedata.BConfig;
|
||||||
|
import com.dre.brewery.recipe.PluginItem;
|
||||||
|
import net.Indyuce.mmoitems.MMOItems;
|
||||||
|
import net.Indyuce.mmoitems.api.item.NBTItem;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
public class MMOItemsPluginItem extends PluginItem {
|
||||||
|
|
||||||
|
// When implementing this, put Brewery as softdepend in your plugin.yml!
|
||||||
|
// We're calling this as server start:
|
||||||
|
// PluginItem.registerForConfig("mmoitems", MMOItemsPluginItem::new);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(ItemStack item) {
|
||||||
|
if (BConfig.hasMMOItems == null) {
|
||||||
|
BConfig.hasMMOItems = P.p.getServer().getPluginManager().isPluginEnabled("MMOItems");
|
||||||
|
}
|
||||||
|
if (!BConfig.hasMMOItems) return false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
NBTItem nbtItem = MMOItems.plugin.getNMS().getNBTItem(item);
|
||||||
|
return nbtItem.hasType() && nbtItem.getString("MMOITEMS_ITEM_ID").equalsIgnoreCase(getItemId());
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
P.p.errorLog("Could not check MMOItems for Item ID");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
src/com/dre/brewery/integration/item/SlimefunPluginItem.java
Normal file
35
src/com/dre/brewery/integration/item/SlimefunPluginItem.java
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package com.dre.brewery.integration.item;
|
||||||
|
|
||||||
|
import com.dre.brewery.P;
|
||||||
|
import com.dre.brewery.filedata.BConfig;
|
||||||
|
import com.dre.brewery.recipe.PluginItem;
|
||||||
|
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
public class SlimefunPluginItem extends PluginItem {
|
||||||
|
|
||||||
|
// When implementing this, put Brewery as softdepend in your plugin.yml!
|
||||||
|
// We're calling this as server start:
|
||||||
|
// PluginItem.registerForConfig("slimefun", SlimefunPluginItem::new);
|
||||||
|
// PluginItem.registerForConfig("exoticgarden", SlimefunPluginItem::new);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(ItemStack item) {
|
||||||
|
if (BConfig.hasSlimefun == null) {
|
||||||
|
BConfig.hasSlimefun = P.p.getServer().getPluginManager().isPluginEnabled("Slimefun");
|
||||||
|
}
|
||||||
|
if (!BConfig.hasSlimefun) return false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
SlimefunItem sfItem = SlimefunItem.getByItem(item);
|
||||||
|
if (sfItem != null) {
|
||||||
|
return sfItem.getID().equalsIgnoreCase(getItemId());
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
P.p.errorLog("Could not check Slimefun for Item ID");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@ package com.dre.brewery.listeners;
|
|||||||
import com.dre.brewery.*;
|
import com.dre.brewery.*;
|
||||||
import com.dre.brewery.api.events.brew.BrewModifyEvent;
|
import com.dre.brewery.api.events.brew.BrewModifyEvent;
|
||||||
import com.dre.brewery.filedata.BConfig;
|
import com.dre.brewery.filedata.BConfig;
|
||||||
|
import com.dre.brewery.recipe.BRecipe;
|
||||||
import com.dre.brewery.utility.BUtil;
|
import com.dre.brewery.utility.BUtil;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
|
@ -19,9 +19,9 @@ public class WorldListener implements Listener {
|
|||||||
World world = event.getWorld();
|
World world = event.getWorld();
|
||||||
|
|
||||||
if (world.getName().startsWith("DXL_")) {
|
if (world.getName().startsWith("DXL_")) {
|
||||||
BData.loadWorldData(BUtil.getDxlName(world.getName()), world);
|
BData.loadWorldData(BUtil.getDxlName(world.getName()), world, null);
|
||||||
} else {
|
} else {
|
||||||
BData.loadWorldData(world.getUID().toString(), world);
|
BData.loadWorldData(world.getUID().toString(), world, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package com.dre.brewery.lore;
|
package com.dre.brewery.lore;
|
||||||
|
|
||||||
import com.dre.brewery.BEffect;
|
import com.dre.brewery.recipe.BEffect;
|
||||||
import com.dre.brewery.BIngredients;
|
import com.dre.brewery.BIngredients;
|
||||||
import com.dre.brewery.BRecipe;
|
import com.dre.brewery.recipe.BRecipe;
|
||||||
import com.dre.brewery.Brew;
|
import com.dre.brewery.Brew;
|
||||||
import com.dre.brewery.P;
|
import com.dre.brewery.P;
|
||||||
import com.dre.brewery.filedata.BConfig;
|
import com.dre.brewery.filedata.BConfig;
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
package com.dre.brewery;
|
package com.dre.brewery.recipe;
|
||||||
|
|
||||||
import com.dre.brewery.utility.CustomItem;
|
import com.dre.brewery.P;
|
||||||
import com.dre.brewery.utility.PotionColor;
|
import com.dre.brewery.utility.PotionColor;
|
||||||
import com.dre.brewery.utility.Tuple;
|
import com.dre.brewery.utility.Tuple;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@ -17,10 +16,12 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
public class BCauldronRecipe {
|
public class BCauldronRecipe {
|
||||||
public static List<BCauldronRecipe> recipes = new ArrayList<>();
|
public static List<BCauldronRecipe> recipes = new ArrayList<>();
|
||||||
public static Set<Material> acceptedMaterials = EnumSet.noneOf(Material.class);
|
public static List<RecipeItem> acceptedCustom = new ArrayList<>(); // All accepted custom and other items
|
||||||
|
public static Set<Material> acceptedSimple = EnumSet.noneOf(Material.class); // All accepted simple items
|
||||||
|
public static Set<Material> acceptedMaterials = EnumSet.noneOf(Material.class); // Fast cache for all accepted Materials
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private List<Tuple<CustomItem, Integer>> ingredients; // Item and amount
|
private List<RecipeItem> ingredients;
|
||||||
//private List<String> particles
|
//private List<String> particles
|
||||||
private PotionColor color;
|
private PotionColor color;
|
||||||
private List<String> lore;
|
private List<String> lore;
|
||||||
@ -72,7 +73,7 @@ public class BCauldronRecipe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public List<Tuple<CustomItem, Integer>> getIngredients() {
|
public List<RecipeItem> getIngredients() {
|
||||||
return ingredients;
|
return ingredients;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,28 +93,26 @@ public class BCauldronRecipe {
|
|||||||
* If all Ingredients and their amounts are equal, returns 10
|
* If all Ingredients and their amounts are equal, returns 10
|
||||||
* Returns something between 0 and 10 if all ingredients present, but differing amounts, depending on how much the amount differs.
|
* Returns something between 0 and 10 if all ingredients present, but differing amounts, depending on how much the amount differs.
|
||||||
*/
|
*/
|
||||||
public float getIngredientMatch(List<ItemStack> items) {
|
public float getIngredientMatch(List<Ingredient> items) {
|
||||||
if (items.size() < ingredients.size()) {
|
if (items.size() < ingredients.size()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
float match = 10;
|
float match = 10;
|
||||||
search: for (Tuple<CustomItem, Integer> ing : ingredients) {
|
search: for (RecipeItem recipeIng : ingredients) {
|
||||||
for (ItemStack item : items) {
|
for (Ingredient ing : items) {
|
||||||
if (ing.a().matches(item)) {
|
if (recipeIng.matches(ing)) {
|
||||||
double difference = Math.abs(ing.b() - item.getAmount());
|
double difference = Math.abs(recipeIng.getAmount() - ing.getAmount());
|
||||||
if (difference >= 1000) {
|
if (difference >= 1000) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// The Item Amount is the determining part here, the higher the better.
|
// The Item Amount is the determining part here, the higher the better.
|
||||||
// But let the difference in amount to what the recipe expects have a tiny factor as well.
|
// But let the difference in amount to what the recipe expects have a tiny factor as well.
|
||||||
// This way for the same amount, the recipe with the lower difference wins.
|
// This way for the same amount, the recipe with the lower difference wins.
|
||||||
double factor = item.getAmount() * (1.0 - (difference / 1000.0)) ;
|
double factor = ing.getAmount() * (1.0 - (difference / 1000.0)) ;
|
||||||
//double mod = 0.1 + (0.9 * Math.exp(-0.03 * difference)); // logarithmic curve from 1 to 0.1
|
//double mod = 0.1 + (0.9 * Math.exp(-0.03 * difference)); // logarithmic curve from 1 to 0.1
|
||||||
double mod = 1 + (0.9 * -Math.exp(-0.03 * factor)); // logarithmic curve from 0.1 to 1, small for a low factor
|
double mod = 1 + (0.9 * -Math.exp(-0.03 * factor)); // logarithmic curve from 0.1 to 1, small for a low factor
|
||||||
|
|
||||||
P.p.debugLog("Mod for " + ing.a() + "/" + ing.b() + ": " + mod);
|
P.p.debugLog("Mod for " + recipeIng + ": " + mod);
|
||||||
assert mod >= 0.1;
|
|
||||||
assert mod <= 1; // TODO Test
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -138,4 +137,40 @@ public class BCauldronRecipe {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "BCauldronRecipe{" + name + '}';
|
return "BCauldronRecipe{" + name + '}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*public static boolean acceptItem(ItemStack item) {
|
||||||
|
if (acceptedMaterials.contains(item.getType())) {
|
||||||
|
// Extremely fast way to check for most items
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!item.hasItemMeta()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// If the Item is not on the list, but customized, we have to do more checks
|
||||||
|
ItemMeta meta = item.getItemMeta();
|
||||||
|
assert meta != null;
|
||||||
|
if (meta.hasDisplayName() || meta.hasLore()) {
|
||||||
|
for (BItem bItem : acceptedCustom) {
|
||||||
|
if (bItem.matches(item)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static RecipeItem acceptItem(ItemStack item) {
|
||||||
|
if (!acceptedMaterials.contains(item.getType()) && !item.hasItemMeta()) {
|
||||||
|
// Extremely fast way to check for most items
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// If the Item is on the list, or customized, we have to do more checks
|
||||||
|
for (RecipeItem rItem : acceptedItems) {
|
||||||
|
if (rItem.matches(item)) {
|
||||||
|
return rItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}*/
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package com.dre.brewery;
|
package com.dre.brewery.recipe;
|
||||||
|
|
||||||
|
import com.dre.brewery.P;
|
||||||
import com.dre.brewery.utility.BUtil;
|
import com.dre.brewery.utility.BUtil;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.meta.PotionMeta;
|
import org.bukkit.inventory.meta.PotionMeta;
|
@ -1,7 +1,9 @@
|
|||||||
package com.dre.brewery;
|
package com.dre.brewery.recipe;
|
||||||
|
|
||||||
|
import com.dre.brewery.BIngredients;
|
||||||
|
import com.dre.brewery.Brew;
|
||||||
|
import com.dre.brewery.P;
|
||||||
import com.dre.brewery.filedata.BConfig;
|
import com.dre.brewery.filedata.BConfig;
|
||||||
import com.dre.brewery.utility.CustomItem;
|
|
||||||
import com.dre.brewery.utility.PotionColor;
|
import com.dre.brewery.utility.PotionColor;
|
||||||
import com.dre.brewery.utility.Tuple;
|
import com.dre.brewery.utility.Tuple;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@ -12,14 +14,13 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class BRecipe {
|
public class BRecipe {
|
||||||
|
|
||||||
public static List<BRecipe> recipes = new ArrayList<>();
|
public static List<BRecipe> recipes = new ArrayList<>();
|
||||||
|
|
||||||
private String[] name;
|
private String[] name;
|
||||||
private List<Tuple<CustomItem, Integer>> ingredients = new ArrayList<>(); // Items and amounts
|
private List<RecipeItem> ingredients = new ArrayList<>(); // Items and amounts
|
||||||
private int cookingTime; // time to cook in cauldron
|
private int cookingTime; // time to cook in cauldron
|
||||||
private byte distillruns; // runs through the brewer
|
private byte distillruns; // runs through the brewer
|
||||||
private int distillTime; // time for one distill run in seconds
|
private int distillTime; // time for one distill run in seconds
|
||||||
@ -96,7 +97,7 @@ public class BRecipe {
|
|||||||
return recipe;
|
return recipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Tuple<CustomItem, Integer>> loadIngredients(ConfigurationSection cfg, String recipeId) {
|
public static List<RecipeItem> loadIngredients(ConfigurationSection cfg, String recipeId) {
|
||||||
List<String> ingredientsList;
|
List<String> ingredientsList;
|
||||||
if (cfg.isString(recipeId + ".ingredients")) {
|
if (cfg.isString(recipeId + ".ingredients")) {
|
||||||
ingredientsList = new ArrayList<>(1);
|
ingredientsList = new ArrayList<>(1);
|
||||||
@ -107,7 +108,7 @@ public class BRecipe {
|
|||||||
if (ingredientsList == null) {
|
if (ingredientsList == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
List<Tuple<CustomItem, Integer>> ingredients = new ArrayList<>(ingredientsList.size());
|
List<RecipeItem> ingredients = new ArrayList<>(ingredientsList.size());
|
||||||
listLoop: for (String item : ingredientsList) {
|
listLoop: for (String item : ingredientsList) {
|
||||||
String[] ingredParts = item.split("/");
|
String[] ingredParts = item.split("/");
|
||||||
int amount = 1;
|
int amount = 1;
|
||||||
@ -121,19 +122,51 @@ public class BRecipe {
|
|||||||
String[] matParts;
|
String[] matParts;
|
||||||
if (ingredParts[0].contains(",")) {
|
if (ingredParts[0].contains(",")) {
|
||||||
matParts = ingredParts[0].split(",");
|
matParts = ingredParts[0].split(",");
|
||||||
} else if (ingredParts[0].contains(":")) {
|
|
||||||
matParts = ingredParts[0].split(":");
|
|
||||||
} else if (ingredParts[0].contains(";")) {
|
} else if (ingredParts[0].contains(";")) {
|
||||||
matParts = ingredParts[0].split(";");
|
matParts = ingredParts[0].split(";");
|
||||||
} else {
|
} else {
|
||||||
matParts = ingredParts[0].split("\\.");
|
matParts = ingredParts[0].split("\\.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if this is a Plugin Item
|
||||||
|
String[] pluginItem = matParts[0].split(":");
|
||||||
|
if (pluginItem.length > 1) {
|
||||||
|
RecipeItem custom = PluginItem.fromConfig(pluginItem[0], pluginItem[1]);
|
||||||
|
if (custom != null) {
|
||||||
|
custom.setAmount(amount);
|
||||||
|
custom.makeImmutable();
|
||||||
|
ingredients.add(custom);
|
||||||
|
BCauldronRecipe.acceptedCustom.add(custom);
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
// TODO Maybe load later ie on first use of recipe?
|
||||||
|
P.p.errorLog(recipeId + ": Could not Find Plugin: " + ingredParts[1]);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Try to find this Ingredient as Custom Item
|
// Try to find this Ingredient as Custom Item
|
||||||
for (CustomItem custom : BConfig.customItems) {
|
for (RecipeItem custom : BConfig.customItems) {
|
||||||
if (custom.getId().equalsIgnoreCase(matParts[0])) {
|
if (custom.getConfigId().equalsIgnoreCase(matParts[0])) {
|
||||||
ingredients.add(new Tuple<>(custom, amount));
|
custom = custom.getMutableCopy();
|
||||||
BCauldronRecipe.acceptedMaterials.addAll(custom.getMaterials());
|
custom.setAmount(amount);
|
||||||
|
custom.makeImmutable();
|
||||||
|
ingredients.add(custom);
|
||||||
|
if (custom.hasMaterials()) {
|
||||||
|
BCauldronRecipe.acceptedMaterials.addAll(custom.getMaterials());
|
||||||
|
}
|
||||||
|
// Add it as acceptedCustom
|
||||||
|
if (!BCauldronRecipe.acceptedCustom.contains(custom)) {
|
||||||
|
BCauldronRecipe.acceptedCustom.add(custom);
|
||||||
|
/*if (custom instanceof PluginItem || !custom.hasMaterials()) {
|
||||||
|
BCauldronRecipe.acceptedCustom.add(custom);
|
||||||
|
} else if (custom instanceof CustomMatchAnyItem) {
|
||||||
|
CustomMatchAnyItem ma = (CustomMatchAnyItem) custom;
|
||||||
|
if (ma.hasNames() || ma.hasLore()) {
|
||||||
|
BCauldronRecipe.acceptedCustom.add(ma);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
continue listLoop;
|
continue listLoop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -163,14 +196,17 @@ public class BRecipe {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mat != null) {
|
if (mat != null) {
|
||||||
CustomItem custom;
|
RecipeItem rItem;
|
||||||
if (durability > -1) {
|
if (durability > -1) {
|
||||||
custom = CustomItem.asSimpleItem(mat, durability);
|
rItem = new SimpleItem(mat, durability);
|
||||||
} else {
|
} else {
|
||||||
custom = CustomItem.asSimpleItem(mat);
|
rItem = new SimpleItem(mat);
|
||||||
}
|
}
|
||||||
ingredients.add(new Tuple<>(custom, amount));
|
rItem.setAmount(amount);
|
||||||
|
rItem.makeImmutable();
|
||||||
|
ingredients.add(rItem);
|
||||||
BCauldronRecipe.acceptedMaterials.add(mat);
|
BCauldronRecipe.acceptedMaterials.add(mat);
|
||||||
|
BCauldronRecipe.acceptedSimple.add(mat);
|
||||||
} else {
|
} else {
|
||||||
P.p.errorLog(recipeId + ": Unknown Material: " + ingredParts[0]);
|
P.p.errorLog(recipeId + ": Unknown Material: " + ingredParts[0]);
|
||||||
return null;
|
return null;
|
||||||
@ -297,14 +333,14 @@ public class BRecipe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// true if given list misses an ingredient
|
// true if given list misses an ingredient
|
||||||
public boolean isMissingIngredients(List<ItemStack> list) {
|
public boolean isMissingIngredients(List<Ingredient> list) {
|
||||||
if (list.size() < ingredients.size()) {
|
if (list.size() < ingredients.size()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
for (Tuple<CustomItem, Integer> ingredient : ingredients) {
|
for (RecipeItem rItem : ingredients) {
|
||||||
boolean matches = false;
|
boolean matches = false;
|
||||||
for (ItemStack used : list) {
|
for (Ingredient used : list) {
|
||||||
if (ingredient.a().matches(used)) {
|
if (rItem.matches(used)) {
|
||||||
matches = true;
|
matches = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -327,13 +363,18 @@ public class BRecipe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a Brew from this Recipe with best values. Quality can be set, but will reset to 10 if put in a barrel
|
* Create a Brew from this Recipe with best values. Quality can be set, but will reset to 10 if unset immutable and put in a barrel
|
||||||
*
|
*
|
||||||
* @param quality The Quality of the Brew
|
* @param quality The Quality of the Brew
|
||||||
* @return The created Brew
|
* @return The created Brew
|
||||||
*/
|
*/
|
||||||
public Brew createBrew(int quality) {
|
public Brew createBrew(int quality) {
|
||||||
List<ItemStack> list = ingredients.stream().map(ing -> ing.a().createDummy(ing.b())).collect(Collectors.toList());
|
List<Ingredient> list = new ArrayList<>(ingredients.size());
|
||||||
|
for (RecipeItem rItem : ingredients) {
|
||||||
|
Ingredient ing = rItem.toIngredientGeneric();
|
||||||
|
ing.setAmount(rItem.getAmount());
|
||||||
|
list.add(ing);
|
||||||
|
}
|
||||||
|
|
||||||
BIngredients bIngredients = new BIngredients(list, cookingTime);
|
BIngredients bIngredients = new BIngredients(list, cookingTime);
|
||||||
|
|
||||||
@ -343,11 +384,21 @@ public class BRecipe {
|
|||||||
|
|
||||||
// Getter
|
// Getter
|
||||||
|
|
||||||
|
// how many of a specific ingredient in the recipe
|
||||||
|
public int amountOf(Ingredient ing) {
|
||||||
|
for (RecipeItem rItem : ingredients) {
|
||||||
|
if (rItem.matches(ing)) {
|
||||||
|
return rItem.getAmount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// how many of a specific ingredient in the recipe
|
// how many of a specific ingredient in the recipe
|
||||||
public int amountOf(ItemStack item) {
|
public int amountOf(ItemStack item) {
|
||||||
for (Tuple<CustomItem, Integer> ingredient : ingredients) {
|
for (RecipeItem rItem : ingredients) {
|
||||||
if (ingredient.a().matches(item)) {
|
if (rItem.matches(item)) {
|
||||||
return ingredient.b();
|
return rItem.getAmount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
291
src/com/dre/brewery/recipe/CustomItem.java
Normal file
291
src/com/dre/brewery/recipe/CustomItem.java
Normal file
@ -0,0 +1,291 @@
|
|||||||
|
package com.dre.brewery.recipe;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minecraft Item with custon name and lore.
|
||||||
|
* Mostly used for Custom Items of the Config, but also for general custom items
|
||||||
|
*/
|
||||||
|
public class CustomItem extends RecipeItem implements Ingredient {
|
||||||
|
|
||||||
|
private Material mat;
|
||||||
|
private String name;
|
||||||
|
private List<String> lore;
|
||||||
|
|
||||||
|
public CustomItem() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomItem(Material mat) {
|
||||||
|
this.mat = mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomItem(Material mat, String name, List<String> lore) {
|
||||||
|
this.mat = mat;
|
||||||
|
this.name = name;
|
||||||
|
this.lore = lore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomItem(ItemStack item) {
|
||||||
|
mat = item.getType();
|
||||||
|
if (!item.hasItemMeta()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ItemMeta itemMeta = item.getItemMeta();
|
||||||
|
assert itemMeta != null;
|
||||||
|
if (itemMeta.hasDisplayName()) {
|
||||||
|
name = itemMeta.getDisplayName();
|
||||||
|
}
|
||||||
|
if (itemMeta.hasLore()) {
|
||||||
|
lore = itemMeta.getLore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasMaterials() {
|
||||||
|
return mat != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasName() {
|
||||||
|
return name != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasLore() {
|
||||||
|
return lore != null && !lore.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Material> getMaterials() {
|
||||||
|
List<Material> l = new ArrayList<>(1);
|
||||||
|
l.add(mat);
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Material getMaterial() {
|
||||||
|
return mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setMat(Material mat) {
|
||||||
|
this.mat = mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public List<String> getLore() {
|
||||||
|
return lore;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setLore(List<String> lore) {
|
||||||
|
this.lore = lore;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Ingredient toIngredient(ItemStack forItem) {
|
||||||
|
return ((CustomItem) getMutableCopy());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Ingredient toIngredientGeneric() {
|
||||||
|
return ((CustomItem) getMutableCopy());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(Ingredient ingredient) {
|
||||||
|
if (isSimilar(ingredient)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (ingredient instanceof RecipeItem) {
|
||||||
|
RecipeItem rItem = ((RecipeItem) ingredient);
|
||||||
|
if (rItem instanceof SimpleItem) {
|
||||||
|
// If the recipe item is just a simple item, only match if we also only define material
|
||||||
|
// If this is a custom item with more info, we don't want to match a simple item
|
||||||
|
return hasMaterials() && !hasLore() && !hasName() && getMaterial() == ((SimpleItem) rItem).getMaterial();
|
||||||
|
} else if (rItem instanceof CustomItem) {
|
||||||
|
// If the other is a CustomItem as well and not Similar to ours, it might have more data and we still match
|
||||||
|
CustomItem other = ((CustomItem) rItem);
|
||||||
|
if (mat == null || mat == other.mat) {
|
||||||
|
if (!hasName() || (other.name != null && name.equalsIgnoreCase(other.name))) {
|
||||||
|
return !hasLore() || lore == other.lore || (other.hasLore() && matchLore(other.lore));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(ItemStack item) {
|
||||||
|
if (mat != null) {
|
||||||
|
if (item.getType() != mat) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (name == null && !hasLore()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!item.hasItemMeta()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ItemMeta meta = item.getItemMeta();
|
||||||
|
assert meta != null;
|
||||||
|
if (name != null) {
|
||||||
|
if (!meta.hasDisplayName() || !name.equalsIgnoreCase(meta.getDisplayName())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasLore()) {
|
||||||
|
if (!meta.hasLore()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return matchLore(meta.getLore());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this item has lore that matches the given lore.
|
||||||
|
* It matches if our lore is contained in the given lore consecutively, ignoring color of the given lore.
|
||||||
|
*
|
||||||
|
* @param usedLore The given lore to match
|
||||||
|
* @return True if the given lore contains our lore consecutively
|
||||||
|
*/
|
||||||
|
public boolean matchLore(List<String> usedLore) {
|
||||||
|
if (lore == null) return true;
|
||||||
|
int lastIndex = 0;
|
||||||
|
boolean foundFirst = false;
|
||||||
|
for (String line : lore) {
|
||||||
|
do {
|
||||||
|
if (lastIndex == usedLore.size()) {
|
||||||
|
// There is more in lore than in usedLore, bad
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String usedLine = usedLore.get(lastIndex);
|
||||||
|
if (line.equalsIgnoreCase(usedLine) || line.equalsIgnoreCase(ChatColor.stripColor(usedLine))) {
|
||||||
|
// If the line is correct, we have found our first and we want all consecutive lines to also equal
|
||||||
|
foundFirst = true;
|
||||||
|
} else if (foundFirst) {
|
||||||
|
// If a consecutive line is not equal, thats bad
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
lastIndex++;
|
||||||
|
// If we once found one correct line, iterate over 'lore' consecutively
|
||||||
|
} while (!foundFirst);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't compare id here
|
||||||
|
@Override
|
||||||
|
public boolean isSimilar(Ingredient item) {
|
||||||
|
if (this == item) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (item instanceof CustomItem) {
|
||||||
|
CustomItem ci = ((CustomItem) item);
|
||||||
|
return mat == ci.mat && Objects.equals(name, ci.name) && Objects.equals(lore, ci.lore);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (!super.equals(obj)) return false;
|
||||||
|
if (obj instanceof CustomItem) {
|
||||||
|
return isSimilar(((CustomItem) obj));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(super.hashCode(), mat, name, lore);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "CustomItem{" +
|
||||||
|
"id=" + getConfigId() +
|
||||||
|
", mat=" + (mat != null ? mat.name().toLowerCase() : "null") +
|
||||||
|
", name='" + name + '\'' +
|
||||||
|
", loresize: " + (lore != null ? lore.size() : 0) +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveTo(DataOutputStream out) throws IOException {
|
||||||
|
out.writeUTF("CI");
|
||||||
|
if (mat != null) {
|
||||||
|
out.writeBoolean(true);
|
||||||
|
out.writeUTF(mat.name());
|
||||||
|
} else {
|
||||||
|
out.writeBoolean(false);
|
||||||
|
}
|
||||||
|
if (name != null) {
|
||||||
|
out.writeBoolean(true);
|
||||||
|
out.writeUTF(name);
|
||||||
|
} else {
|
||||||
|
out.writeBoolean(false);
|
||||||
|
}
|
||||||
|
if (lore != null) {
|
||||||
|
short size = (short) Math.min(lore.size(), Short.MAX_VALUE);
|
||||||
|
out.writeShort(size);
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
out.writeUTF(lore.get(i));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.writeShort(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CustomItem loadFrom(ItemLoader loader) {
|
||||||
|
try {
|
||||||
|
DataInputStream in = loader.getInputStream();
|
||||||
|
CustomItem item = new CustomItem();
|
||||||
|
if (in.readBoolean()) {
|
||||||
|
item.mat = Material.getMaterial(in.readUTF());
|
||||||
|
}
|
||||||
|
if (in.readBoolean()) {
|
||||||
|
item.name = in.readUTF();
|
||||||
|
}
|
||||||
|
short size = in.readShort();
|
||||||
|
if (size > 0) {
|
||||||
|
item.lore = new ArrayList<>(size);
|
||||||
|
for (short i = 0; i < size; i++) {
|
||||||
|
item.lore.add(in.readUTF());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Needs to be called at Server start
|
||||||
|
public static void registerItemLoader() {
|
||||||
|
Ingredient.registerForItemLoader("CI", CustomItem::loadFrom);
|
||||||
|
}
|
||||||
|
}
|
231
src/com/dre/brewery/recipe/CustomMatchAnyItem.java
Normal file
231
src/com/dre/brewery/recipe/CustomMatchAnyItem.java
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
package com.dre.brewery.recipe;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom Item that matches any one of the given info.
|
||||||
|
* Does not implement Ingredient, as it can not directly be added to an ingredient
|
||||||
|
*/
|
||||||
|
public class CustomMatchAnyItem extends RecipeItem {
|
||||||
|
|
||||||
|
private List<Material> materials;
|
||||||
|
private List<String> names;
|
||||||
|
private List<String> lore;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasMaterials() {
|
||||||
|
return materials != null && !materials.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasNames() {
|
||||||
|
return names != null && !names.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasLore() {
|
||||||
|
return lore != null && !lore.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public List<Material> getMaterials() {
|
||||||
|
return materials;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setMaterials(List<Material> materials) {
|
||||||
|
this.materials = materials;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public List<String> getNames() {
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setNames(List<String> names) {
|
||||||
|
this.names = names;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public List<String> getLore() {
|
||||||
|
return lore;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setLore(List<String> lore) {
|
||||||
|
this.lore = lore;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Ingredient toIngredient(ItemStack forItem) {
|
||||||
|
// We only use the one part of this item that actually matched the given item to add to ingredients
|
||||||
|
Material mat = getMaterialMatch(forItem);
|
||||||
|
if (mat != null) {
|
||||||
|
return new CustomItem(mat);
|
||||||
|
}
|
||||||
|
String name = getNameMatch(forItem);
|
||||||
|
if (name != null) {
|
||||||
|
return new CustomItem(null, name, null);
|
||||||
|
}
|
||||||
|
String l = getLoreMatch(forItem);
|
||||||
|
if (l != null) {
|
||||||
|
List<String> lore = new ArrayList<>(1);
|
||||||
|
lore.add(l);
|
||||||
|
return new CustomItem(null, null, lore);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shouldnt happen
|
||||||
|
return new SimpleItem(Material.GOLDEN_HOE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Ingredient toIngredientGeneric() {
|
||||||
|
if (hasMaterials()) {
|
||||||
|
return new CustomItem(materials.get(0));
|
||||||
|
}
|
||||||
|
if (hasNames()) {
|
||||||
|
return new CustomItem(null, names.get(0), null);
|
||||||
|
}
|
||||||
|
if (hasLore()) {
|
||||||
|
List<String> l = new ArrayList<>(1);
|
||||||
|
l.add(lore.get(0));
|
||||||
|
return new CustomItem(null, null, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shouldnt happen
|
||||||
|
return new SimpleItem(Material.GOLDEN_HOE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Material getMaterialMatch(ItemStack item) {
|
||||||
|
if (!hasMaterials()) return null;
|
||||||
|
|
||||||
|
Material usedMat = item.getType();
|
||||||
|
for (Material mat : materials) {
|
||||||
|
if (usedMat == mat) {
|
||||||
|
return mat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNameMatch(ItemStack item) {
|
||||||
|
if (!item.hasItemMeta() || !hasNames()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ItemMeta meta = item.getItemMeta();
|
||||||
|
assert meta != null;
|
||||||
|
if (meta.hasDisplayName()) {
|
||||||
|
return getNameMatch(meta.getDisplayName());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNameMatch(String usedName) {
|
||||||
|
if (!hasNames()) return null;
|
||||||
|
|
||||||
|
for (String name : names) {
|
||||||
|
if (name.equalsIgnoreCase(usedName)) {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLoreMatch(ItemStack item) {
|
||||||
|
if (!item.hasItemMeta() || !hasLore()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ItemMeta meta = item.getItemMeta();
|
||||||
|
assert meta != null;
|
||||||
|
if (meta.hasLore()) {
|
||||||
|
return getLoreMatch(meta.getLore());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLoreMatch(List<String> usedLore) {
|
||||||
|
if (!hasLore()) return null;
|
||||||
|
|
||||||
|
for (String line : this.lore) {
|
||||||
|
for (String usedLine : usedLore) {
|
||||||
|
if (line.equalsIgnoreCase(usedLine) || line.equalsIgnoreCase(ChatColor.stripColor(usedLine))) {
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(ItemStack item) {
|
||||||
|
if (getMaterialMatch(item) != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (getNameMatch(item) != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return getLoreMatch(item) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(Ingredient ingredient) {
|
||||||
|
// Ingredient can not be CustomMatchAnyItem, so we don't need to/can't check for similarity.
|
||||||
|
if (ingredient instanceof CustomItem) {
|
||||||
|
// If the custom item has any of our data, we match
|
||||||
|
CustomItem ci = ((CustomItem) ingredient);
|
||||||
|
if (hasMaterials() && ci.hasMaterials()) {
|
||||||
|
if (materials.contains(ci.getMaterial())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasNames() && ci.hasName()) {
|
||||||
|
if (getNameMatch(ci.getName()) != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasLore() && ci.hasLore()) {
|
||||||
|
return getLoreMatch(ci.getLore()) != null;
|
||||||
|
}
|
||||||
|
} else if (ingredient instanceof SimpleItem) {
|
||||||
|
// If we contain the Material of the Simple Item, we match
|
||||||
|
SimpleItem si = (SimpleItem) ingredient;
|
||||||
|
return hasMaterials() && materials.contains(si.getMaterial());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
if (!super.equals(o)) return false;
|
||||||
|
CustomMatchAnyItem that = (CustomMatchAnyItem) o;
|
||||||
|
return Objects.equals(materials, that.materials) &&
|
||||||
|
Objects.equals(names, that.names) &&
|
||||||
|
Objects.equals(lore, that.lore);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(super.hashCode(), materials, names, lore);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "CustomMatchAnyItem{" +
|
||||||
|
"id=" + getConfigId() +
|
||||||
|
", materials: " + (materials != null ? materials.size() : 0) +
|
||||||
|
", names:" + (names != null ? names.size() : 0) +
|
||||||
|
", loresize: " + (lore != null ? lore.size() : 0) +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
88
src/com/dre/brewery/recipe/Ingredient.java
Normal file
88
src/com/dre/brewery/recipe/Ingredient.java
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
package com.dre.brewery.recipe;
|
||||||
|
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item used in a BIngredients, inside BCauldron or Brew.
|
||||||
|
* Represents the Items used as ingredients in the Brewing process
|
||||||
|
* Can be a copy of a recipe item
|
||||||
|
* Will be saved and loaded with a DataStream
|
||||||
|
* Each implementing class needs to register a static function as Item Loader
|
||||||
|
*/
|
||||||
|
public interface Ingredient {
|
||||||
|
|
||||||
|
Map<String, Function<ItemLoader, Ingredient>> LOADERS = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a Static function as function that takes an ItemLoader, containing a DataInputStream.
|
||||||
|
* Using the Stream it constructs a corresponding Ingredient for the chosen SaveID
|
||||||
|
*
|
||||||
|
* @param saveID The SaveID should be a small identifier like "AB"
|
||||||
|
* @param loadFct The Static Function that loads the Item, i.e.
|
||||||
|
* public static AItem loadFrom(ItemLoader loader)
|
||||||
|
*/
|
||||||
|
static void registerForItemLoader(String saveID, Function<ItemLoader, Ingredient> loadFct) {
|
||||||
|
LOADERS.put(saveID, loadFct);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregister the ItemLoader
|
||||||
|
*
|
||||||
|
* @param saveID the chosen SaveID
|
||||||
|
*/
|
||||||
|
static void unRegisterItemLoader(String saveID) {
|
||||||
|
LOADERS.remove(saveID);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves this Ingredient to the DataOutputStream.
|
||||||
|
* The first data HAS to be storing the SaveID like:
|
||||||
|
* out.writeUTF("AB");
|
||||||
|
* Amount will be saved automatically and does not have to be saved here.
|
||||||
|
* Saving is done to Brew or for BCauldron into data.yml
|
||||||
|
*
|
||||||
|
* @param out The outputstream to write to
|
||||||
|
* @throws IOException Any IOException
|
||||||
|
*/
|
||||||
|
void saveTo(DataOutputStream out) throws IOException;
|
||||||
|
|
||||||
|
int getAmount();
|
||||||
|
|
||||||
|
void setAmount(int amount);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does this Ingredient match the given ItemStack
|
||||||
|
*
|
||||||
|
* @param item The given ItemStack to match
|
||||||
|
* @return true if all required data is contained on the item
|
||||||
|
*/
|
||||||
|
boolean matches(ItemStack item);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Does this Item match the given RecipeItem.
|
||||||
|
* An IngredientItem matches a RecipeItem if all required info of the RecipeItem are fulfilled on this IngredientItem
|
||||||
|
* This does not imply that the same holds the other way round, as this item might have more info than needed
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param recipeItem The recipeItem whose requirements need to be fulfilled
|
||||||
|
* @return True if this matches the required info of the recipeItem
|
||||||
|
*/
|
||||||
|
//boolean matches(RecipeItem recipeItem);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The other Ingredient is Similar if it is equal except amount
|
||||||
|
*
|
||||||
|
* @param item The item to check similarity with
|
||||||
|
* @return True if this is equal to item except for amount
|
||||||
|
*/
|
||||||
|
boolean isSimilar(Ingredient item);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
28
src/com/dre/brewery/recipe/ItemLoader.java
Normal file
28
src/com/dre/brewery/recipe/ItemLoader.java
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package com.dre.brewery.recipe;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
|
||||||
|
public class ItemLoader {
|
||||||
|
|
||||||
|
private final int version;
|
||||||
|
private final DataInputStream in;
|
||||||
|
private final String saveID;
|
||||||
|
|
||||||
|
public ItemLoader(int version, DataInputStream in, String saveID) {
|
||||||
|
this.version = version;
|
||||||
|
this.in = in;
|
||||||
|
this.saveID = saveID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataInputStream getInputStream() {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSaveID() {
|
||||||
|
return saveID;
|
||||||
|
}
|
||||||
|
}
|
213
src/com/dre/brewery/recipe/PluginItem.java
Normal file
213
src/com/dre/brewery/recipe/PluginItem.java
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
package com.dre.brewery.recipe;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An Item of a Recipe or as Ingredient in a Brew that corresponds to an item from another plugin.
|
||||||
|
* See /integration/item for examples on how to extend this class.
|
||||||
|
* This class stores items as name of the plugin and item id
|
||||||
|
*/
|
||||||
|
public abstract class PluginItem extends RecipeItem implements Ingredient {
|
||||||
|
|
||||||
|
private static Map<String, Supplier<PluginItem>> constructors = new HashMap<>();
|
||||||
|
|
||||||
|
private String plugin;
|
||||||
|
private String itemId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New Empty PluginItem
|
||||||
|
*/
|
||||||
|
public PluginItem() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New PluginItem with both fields already set
|
||||||
|
*
|
||||||
|
* @param plugin The name of the Plugin
|
||||||
|
* @param itemId The ItemID
|
||||||
|
*/
|
||||||
|
public PluginItem(String plugin, String itemId) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.itemId = itemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasMaterials() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Material> getMaterials() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPlugin() {
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getItemId() {
|
||||||
|
return itemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setPlugin(String plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setItemId(String itemId) {
|
||||||
|
this.itemId = itemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after Loading this Plugin Item from Config, or (by default) from Ingredients.
|
||||||
|
* Allows Override to define custom actions after an Item was constructed
|
||||||
|
*/
|
||||||
|
protected void onConstruct() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does this PluginItem Match the other Ingredient.
|
||||||
|
* By default it matches exactly when they are similar, i.e. also a PluginItem with same parameters
|
||||||
|
*
|
||||||
|
* @param ingredient The ingredient that needs to fulfill the requirements
|
||||||
|
* @return True if the ingredient matches the required info of this
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean matches(Ingredient ingredient) {
|
||||||
|
return isSimilar(ingredient);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Ingredient toIngredient(ItemStack forItem) {
|
||||||
|
return ((PluginItem) getMutableCopy());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Ingredient toIngredientGeneric() {
|
||||||
|
return ((PluginItem) getMutableCopy());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSimilar(Ingredient item) {
|
||||||
|
if (item instanceof PluginItem) {
|
||||||
|
return Objects.equals(plugin, ((PluginItem) item).plugin) && Objects.equals(itemId, ((PluginItem) item).itemId);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
if (!super.equals(o)) return false;
|
||||||
|
PluginItem item = (PluginItem) o;
|
||||||
|
return Objects.equals(plugin, item.plugin) &&
|
||||||
|
Objects.equals(itemId, item.itemId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(super.hashCode(), plugin, itemId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveTo(DataOutputStream out) throws IOException {
|
||||||
|
out.writeUTF("PI");
|
||||||
|
out.writeUTF(plugin);
|
||||||
|
out.writeUTF(itemId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when loading this Plugin Item from Ingredients (of a Brew)
|
||||||
|
* The default loading is the same as loading from Config
|
||||||
|
*
|
||||||
|
* @param loader The ItemLoader from which to load the data, use loader.getInputStream()
|
||||||
|
* @return The constructed PluginItem
|
||||||
|
*/
|
||||||
|
public static PluginItem loadFrom(ItemLoader loader) {
|
||||||
|
try {
|
||||||
|
DataInputStream in = loader.getInputStream();
|
||||||
|
String plugin = in.readUTF();
|
||||||
|
String itemId = in.readUTF();
|
||||||
|
PluginItem item = fromConfig(plugin, itemId);
|
||||||
|
if (item == null) {
|
||||||
|
// Plugin not found when loading from Item, use a generic PluginItem that never matches other items
|
||||||
|
item = new PluginItem(plugin, itemId) {
|
||||||
|
@Override
|
||||||
|
public boolean matches(ItemStack item) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Needs to be called at Server start
|
||||||
|
* Registers the chosen SaveID and the loading Method for loading from Brew or BCauldron
|
||||||
|
*/
|
||||||
|
public static void registerItemLoader() {
|
||||||
|
Ingredient.registerForItemLoader("PI", PluginItem::loadFrom);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when loading trying to find a config defined Plugin Item, or by default also when loading from ingredients
|
||||||
|
* Will call a registered constructor matching the given plugin identifier
|
||||||
|
*
|
||||||
|
* @param plugin The Identifier of the Plugin used in the config
|
||||||
|
* @param itemId The Identifier of the Item belonging to this Plugin used in the config
|
||||||
|
* @return The Plugin Item if found, or null if there is no plugin for the given String
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public static PluginItem fromConfig(String plugin, String itemId) {
|
||||||
|
plugin = plugin.toLowerCase();
|
||||||
|
if (constructors.containsKey(plugin)) {
|
||||||
|
PluginItem item = constructors.get(plugin).get();
|
||||||
|
item.setPlugin(plugin);
|
||||||
|
item.setItemId(itemId);
|
||||||
|
item.onConstruct();
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This needs to be called at Server Start before Brewery loads its data.
|
||||||
|
* When implementing this, put Brewery as softdepend in your plugin.yml!
|
||||||
|
* Registers a Constructor that returns a new or cloned instance of a PluginItem
|
||||||
|
* This Constructor will be called when loading a Plugin Item from Config or by default from ingredients
|
||||||
|
* After the Constructor is called, the plugin and itemid will be set on the new instance
|
||||||
|
* Finally the onConstruct is called.
|
||||||
|
*
|
||||||
|
* @param pluginId The ID to use in the config
|
||||||
|
* @param constructor The constructor i.e. YourPluginItem::new
|
||||||
|
*/
|
||||||
|
public static void registerForConfig(String pluginId, Supplier<PluginItem> constructor) {
|
||||||
|
constructors.put(pluginId.toLowerCase(), constructor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void unRegisterForConfig(String pluginId) {
|
||||||
|
constructors.remove(pluginId.toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
314
src/com/dre/brewery/recipe/RecipeItem.java
Normal file
314
src/com/dre/brewery/recipe/RecipeItem.java
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
package com.dre.brewery.recipe;
|
||||||
|
|
||||||
|
import com.dre.brewery.P;
|
||||||
|
import com.dre.brewery.filedata.BConfig;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item that can be used in a Recipe.
|
||||||
|
* They are not necessarily only loaded from config
|
||||||
|
* They are immutable if used in a recipe. If one implements Ingredient,
|
||||||
|
* it can be used as mutable copy directly in a
|
||||||
|
* BIngredients. Otherwise it needs to be converted to an Ingredient
|
||||||
|
*/
|
||||||
|
public abstract class RecipeItem implements Cloneable {
|
||||||
|
|
||||||
|
private String cfgId;
|
||||||
|
private int amount;
|
||||||
|
private boolean immutable = false;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does this RecipeItem match the given ItemStack?
|
||||||
|
* Used to determine if the given item corresponds to this recipeitem
|
||||||
|
*
|
||||||
|
* @param item The ItemStack for comparison
|
||||||
|
* @return True if the given item matches this recipeItem
|
||||||
|
*/
|
||||||
|
public abstract boolean matches(ItemStack item);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does this Item match the given Ingredient.
|
||||||
|
* A RecipeItem matches an Ingredient if all required info of the RecipeItem are fulfilled on the Ingredient
|
||||||
|
* This does not imply that the same holds the other way round, as the ingredient item might have more info than needed
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param ingredient The ingredient that needs to fulfill the requirements
|
||||||
|
* @return True if the ingredient matches the required info of this
|
||||||
|
*/
|
||||||
|
public abstract boolean matches(Ingredient ingredient);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Corresponding Ingredient Item. For Items implementing Ingredient, just getMutableCopy()
|
||||||
|
* This is called when this recipe item is added to a BIngredients
|
||||||
|
*
|
||||||
|
* @param forItem The ItemStack that has previously matched this RecipeItem. Used if the resulting Ingredient needs more info from the ItemStack
|
||||||
|
* @return The IngredientItem corresponding to this RecipeItem
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public abstract Ingredient toIngredient(ItemStack forItem);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a Generic Ingredient for this recipe item
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public abstract Ingredient toIngredientGeneric();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return True if this recipeItem has one or more materials that could classify an item. if true, getMaterials() is NotNull
|
||||||
|
*/
|
||||||
|
public abstract boolean hasMaterials();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return List of one or more Materials this recipeItem uses.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public abstract List<Material> getMaterials();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The Id this Item uses in the config in the custom-items section
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public String getConfigId() {
|
||||||
|
return cfgId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The Amount of this Item in a Recipe
|
||||||
|
*/
|
||||||
|
public int getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the Amount of this Item in a Recipe
|
||||||
|
* The amount can not be set on an existing item in a recipe or existing custom item.
|
||||||
|
* To change amount you need to use getMutableCopy() and change the amount on the copy
|
||||||
|
*
|
||||||
|
* @param amount The new amount
|
||||||
|
*/
|
||||||
|
public void setAmount(int amount) {
|
||||||
|
if (immutable) throw new IllegalStateException("Setting amount only possible on mutable copy");
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes this Item immutable, for example when loaded from config. Used so if this is added to BIngredients,
|
||||||
|
* it needs to be cloned before changing anything like amount
|
||||||
|
*/
|
||||||
|
public void makeImmutable() {
|
||||||
|
immutable = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a shallow clone of this RecipeItem whose fields like amount can be changed.
|
||||||
|
*
|
||||||
|
* @return A mutable copy of this
|
||||||
|
*/
|
||||||
|
public RecipeItem getMutableCopy() {
|
||||||
|
try {
|
||||||
|
RecipeItem i = (RecipeItem) super.clone();
|
||||||
|
i.immutable = false;
|
||||||
|
return i;
|
||||||
|
} catch (CloneNotSupportedException e) {
|
||||||
|
throw new InternalError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to find a matching RecipeItem for this item. It checks custom items and if it has found a unique custom item
|
||||||
|
* it will return that. If there are multiple matching custom items, a new CustomItem with all item info is returned
|
||||||
|
* If there is no matching CustomItem, it will return a SimpleItem with the items type
|
||||||
|
*
|
||||||
|
* @param item The Item for which to find a matching RecipeItem
|
||||||
|
* @param acceptAll If true it will accept any item and return a SimpleItem even if not on the accepted list
|
||||||
|
* If false it will return null if the item is not acceptable by the Cauldron
|
||||||
|
* @return The Matched CustomItem, new CustomItem with all item info or SimpleItem
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
@Contract("_, true -> !null")
|
||||||
|
public static RecipeItem getMatchingRecipeItem(ItemStack item, boolean acceptAll) {
|
||||||
|
RecipeItem rItem = null;
|
||||||
|
boolean multiMatch = false;
|
||||||
|
for (RecipeItem ri : BCauldronRecipe.acceptedCustom) {
|
||||||
|
// If we already have a multi match, only check if there is a PluginItem that matches more strictly
|
||||||
|
if (!multiMatch || (ri instanceof PluginItem)) {
|
||||||
|
if (ri.matches(item)) {
|
||||||
|
// If we match a plugin item, thats a very strict match, so immediately return it
|
||||||
|
if (ri instanceof PluginItem) {
|
||||||
|
return ri;
|
||||||
|
}
|
||||||
|
if (rItem == null) {
|
||||||
|
rItem = ri;
|
||||||
|
} else {
|
||||||
|
multiMatch = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (multiMatch) {
|
||||||
|
// We have multiple Custom Items matching, so just store all item info
|
||||||
|
return new CustomItem(item);
|
||||||
|
}
|
||||||
|
if (rItem == null && (acceptAll || BCauldronRecipe.acceptedSimple.contains(item.getType()))) {
|
||||||
|
// No Custom item found
|
||||||
|
if (P.use1_13) {
|
||||||
|
return new SimpleItem(item.getType());
|
||||||
|
} else {
|
||||||
|
//noinspection deprecation
|
||||||
|
return new SimpleItem(item.getType(), item.getDurability());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static RecipeItem fromConfigCustom(ConfigurationSection cfg, String id) {
|
||||||
|
RecipeItem rItem;
|
||||||
|
if (cfg.getBoolean(id + ".matchAny", false)) {
|
||||||
|
rItem = new CustomMatchAnyItem();
|
||||||
|
} else {
|
||||||
|
rItem = new CustomItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
rItem.cfgId = id;
|
||||||
|
rItem.immutable = true;
|
||||||
|
|
||||||
|
List<Material> materials;
|
||||||
|
List<String> names;
|
||||||
|
List<String> lore;
|
||||||
|
|
||||||
|
List<String> load = null;
|
||||||
|
String path = id + ".material";
|
||||||
|
if (cfg.isString(path)) {
|
||||||
|
load = new ArrayList<>(1);
|
||||||
|
load.add(cfg.getString(path));
|
||||||
|
} else if (cfg.isList(path)) {
|
||||||
|
load = cfg.getStringList(path);
|
||||||
|
}
|
||||||
|
if (load != null && !load.isEmpty()) {
|
||||||
|
if ((materials = loadMaterials(load)) == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
materials = new ArrayList<>(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
load = null;
|
||||||
|
path = id + ".name";
|
||||||
|
if (cfg.isString(path)) {
|
||||||
|
load = new ArrayList<>(1);
|
||||||
|
load.add(cfg.getString(path));
|
||||||
|
} else if (cfg.isList(path)) {
|
||||||
|
load = cfg.getStringList(path);
|
||||||
|
}
|
||||||
|
if (load != null && !load.isEmpty()) {
|
||||||
|
names = load.stream().map(l -> P.p.color(l)).collect(Collectors.toList());
|
||||||
|
if (P.use1_13) {
|
||||||
|
// In 1.13 trailing Color white is removed from display names
|
||||||
|
names = names.stream().map(l -> l.startsWith("§f") ? l.substring(2) : l).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
names = new ArrayList<>(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
load = null;
|
||||||
|
path = id + ".lore";
|
||||||
|
if (cfg.isString(path)) {
|
||||||
|
load = new ArrayList<>(1);
|
||||||
|
load.add(cfg.getString(path));
|
||||||
|
} else if (cfg.isList(path)) {
|
||||||
|
load = cfg.getStringList(path);
|
||||||
|
}
|
||||||
|
if (load != null && !load.isEmpty()) {
|
||||||
|
lore = load.stream().map(l -> P.p.color(l)).collect(Collectors.toList());
|
||||||
|
} else {
|
||||||
|
lore = new ArrayList<>(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (materials.isEmpty() && names.isEmpty() && lore.isEmpty()) {
|
||||||
|
P.p.errorLog("No Config Entries found for Custom Item");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rItem instanceof CustomItem) {
|
||||||
|
CustomItem cItem = ((CustomItem) rItem);
|
||||||
|
if (!materials.isEmpty()) {
|
||||||
|
cItem.setMat(materials.get(0));
|
||||||
|
}
|
||||||
|
if (!names.isEmpty()) {
|
||||||
|
cItem.setName(names.get(0));
|
||||||
|
}
|
||||||
|
cItem.setLore(lore);
|
||||||
|
} else {
|
||||||
|
CustomMatchAnyItem maItem = (CustomMatchAnyItem) rItem;
|
||||||
|
maItem.setMaterials(materials);
|
||||||
|
maItem.setNames(names);
|
||||||
|
maItem.setLore(lore);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
protected static List<Material> loadMaterials(List<String> ingredientsList) {
|
||||||
|
List<Material> materials = new ArrayList<>(ingredientsList.size());
|
||||||
|
for (String item : ingredientsList) {
|
||||||
|
String[] ingredParts = item.split("/");
|
||||||
|
if (ingredParts.length == 2) {
|
||||||
|
P.p.errorLog("Item Amount can not be specified for Custom Items: " + item);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Material mat = Material.matchMaterial(ingredParts[0]);
|
||||||
|
|
||||||
|
if (mat == null && BConfig.hasVault) {
|
||||||
|
try {
|
||||||
|
net.milkbowl.vault.item.ItemInfo vaultItem = net.milkbowl.vault.item.Items.itemByString(ingredParts[0]);
|
||||||
|
if (vaultItem != null) {
|
||||||
|
mat = vaultItem.getType();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
P.p.errorLog("Could not check vault for Item Name");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mat != null) {
|
||||||
|
materials.add(mat);
|
||||||
|
} else {
|
||||||
|
P.p.errorLog("Unknown Material: " + ingredParts[0]);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return materials;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof RecipeItem)) return false;
|
||||||
|
RecipeItem that = (RecipeItem) o;
|
||||||
|
return amount == that.amount &&
|
||||||
|
immutable == that.immutable &&
|
||||||
|
Objects.equals(cfgId, that.cfgId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(cfgId, amount, immutable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "RecipeItem{(" + getClass().getSimpleName() + ") ID: " + getConfigId() + " Materials: " + (hasMaterials() ? getMaterials().size() : 0) + " Amount: " + getAmount();
|
||||||
|
}
|
||||||
|
}
|
151
src/com/dre/brewery/recipe/SimpleItem.java
Normal file
151
src/com/dre/brewery/recipe/SimpleItem.java
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
package com.dre.brewery.recipe;
|
||||||
|
|
||||||
|
import com.dre.brewery.P;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple Minecraft Item with just Material
|
||||||
|
*/
|
||||||
|
public class SimpleItem extends RecipeItem implements Ingredient {
|
||||||
|
|
||||||
|
private Material mat;
|
||||||
|
private short dur; // Old Mc
|
||||||
|
|
||||||
|
|
||||||
|
public SimpleItem(Material mat) {
|
||||||
|
this(mat, (short) 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleItem(Material mat, short dur) {
|
||||||
|
this.mat = mat;
|
||||||
|
this.dur = dur;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasMaterials() {
|
||||||
|
return mat != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Material getMaterial() {
|
||||||
|
return mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Material> getMaterials() {
|
||||||
|
List<Material> l = new ArrayList<>(1);
|
||||||
|
l.add(mat);
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Ingredient toIngredient(ItemStack forItem) {
|
||||||
|
return ((SimpleItem) getMutableCopy());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Ingredient toIngredientGeneric() {
|
||||||
|
return ((SimpleItem) getMutableCopy());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(ItemStack item) {
|
||||||
|
if (!mat.equals(item.getType())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//noinspection deprecation
|
||||||
|
return P.use1_13 || dur == item.getDurability();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(Ingredient ingredient) {
|
||||||
|
if (isSimilar(ingredient)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (ingredient instanceof RecipeItem) {
|
||||||
|
if (!((RecipeItem) ingredient).hasMaterials()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ingredient instanceof CustomItem) {
|
||||||
|
// Only match if the Custom Item also only defines material
|
||||||
|
// If the custom item has more info like name and lore, it is not supposed to match a simple item
|
||||||
|
CustomItem ci = (CustomItem) ingredient;
|
||||||
|
return !ci.hasLore() && !ci.hasName() && mat == ci.getMaterial();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSimilar(Ingredient item) {
|
||||||
|
if (this == item) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (item instanceof SimpleItem) {
|
||||||
|
SimpleItem si = ((SimpleItem) item);
|
||||||
|
return si.mat == mat && si.dur == dur;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
if (!super.equals(o)) return false;
|
||||||
|
SimpleItem item = (SimpleItem) o;
|
||||||
|
return dur == item.dur &&
|
||||||
|
mat == item.mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(super.hashCode(), mat, dur);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "SimpleItem{" +
|
||||||
|
"mat=" + mat.name().toLowerCase() +
|
||||||
|
" amount=" + getAmount() +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveTo(DataOutputStream out) throws IOException {
|
||||||
|
out.writeUTF("SI");
|
||||||
|
out.writeUTF(mat.name());
|
||||||
|
out.writeShort(dur);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SimpleItem loadFrom(ItemLoader loader) {
|
||||||
|
try {
|
||||||
|
DataInputStream in = loader.getInputStream();
|
||||||
|
Material mat = Material.getMaterial(in.readUTF());
|
||||||
|
if (mat != null) {
|
||||||
|
SimpleItem item = new SimpleItem(mat, in.readShort());
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Needs to be called at Server start
|
||||||
|
public static void registerItemLoader() {
|
||||||
|
Ingredient.registerForItemLoader("SI", SimpleItem::loadFrom);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,329 +0,0 @@
|
|||||||
package com.dre.brewery.utility;
|
|
||||||
|
|
||||||
import com.dre.brewery.P;
|
|
||||||
import com.dre.brewery.filedata.BConfig;
|
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class CustomItem {
|
|
||||||
private String id;
|
|
||||||
private boolean simple; // Simple Custom Item is just materials.get(0) and durability for old mc
|
|
||||||
private boolean matchAny; // If only one of the values needs to match
|
|
||||||
private short dur; // Old Mc
|
|
||||||
private List<Material> materials;
|
|
||||||
private List<String> names;
|
|
||||||
private List<String> lore;
|
|
||||||
|
|
||||||
public static CustomItem asSimpleItem(Material mat) {
|
|
||||||
return asSimpleItem(mat, (short) 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CustomItem asSimpleItem(Material mat, short dur) {
|
|
||||||
CustomItem it = new CustomItem();
|
|
||||||
it.simple = true;
|
|
||||||
it.dur = dur;
|
|
||||||
it.materials = new ArrayList<>(1);
|
|
||||||
it.materials.add(mat);
|
|
||||||
return it;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static CustomItem fromConfig(ConfigurationSection cfg, String id) {
|
|
||||||
CustomItem custom = new CustomItem();
|
|
||||||
|
|
||||||
custom.id = id;
|
|
||||||
custom.matchAny = cfg.getBoolean(id + ".matchAny", false);
|
|
||||||
|
|
||||||
List<String> load = null;
|
|
||||||
String path = id + ".material";
|
|
||||||
if (cfg.isString(path)) {
|
|
||||||
load = new ArrayList<>(1);
|
|
||||||
load.add(cfg.getString(path));
|
|
||||||
} else if (cfg.isList(path)) {
|
|
||||||
load = cfg.getStringList(path);
|
|
||||||
}
|
|
||||||
if (load != null && !load.isEmpty()) {
|
|
||||||
custom.materials = new ArrayList<>(load.size());
|
|
||||||
if (!custom.loadMaterials(load)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
custom.materials = new ArrayList<>(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
load = null;
|
|
||||||
path = id + ".name";
|
|
||||||
if (cfg.isString(path)) {
|
|
||||||
load = new ArrayList<>(1);
|
|
||||||
load.add(cfg.getString(path));
|
|
||||||
} else if (cfg.isList(path)) {
|
|
||||||
load = cfg.getStringList(path);
|
|
||||||
}
|
|
||||||
if (load != null && !load.isEmpty()) {
|
|
||||||
custom.names = load.stream().map(l -> P.p.color(l)).collect(Collectors.toList());
|
|
||||||
if (P.use1_13) {
|
|
||||||
// In 1.13 trailing Color white is removed from display names
|
|
||||||
custom.names = custom.names.stream().map(l -> l.startsWith("§f") ? l.substring(2) : l).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
custom.names = new ArrayList<>(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
load = null;
|
|
||||||
path = id + ".lore";
|
|
||||||
if (cfg.isString(path)) {
|
|
||||||
load = new ArrayList<>(1);
|
|
||||||
load.add(cfg.getString(path));
|
|
||||||
} else if (cfg.isList(path)) {
|
|
||||||
load = cfg.getStringList(path);
|
|
||||||
}
|
|
||||||
if (load != null && !load.isEmpty()) {
|
|
||||||
custom.lore = load.stream().map(l -> P.p.color(l)).collect(Collectors.toList());
|
|
||||||
} else {
|
|
||||||
custom.lore = new ArrayList<>(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (custom.materials.isEmpty() && custom.names.isEmpty() && custom.lore.isEmpty()) {
|
|
||||||
P.p.errorLog("No Config Entries found for Custom Item");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return custom;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean loadMaterials(List<String> ingredientsList) {
|
|
||||||
for (String item : ingredientsList) {
|
|
||||||
String[] ingredParts = item.split("/");
|
|
||||||
if (ingredParts.length == 2) {
|
|
||||||
P.p.errorLog("Item Amount can not be specified for Custom Items: " + item);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Material mat = Material.matchMaterial(ingredParts[0]);
|
|
||||||
|
|
||||||
if (mat == null && BConfig.hasVault) {
|
|
||||||
try {
|
|
||||||
net.milkbowl.vault.item.ItemInfo vaultItem = net.milkbowl.vault.item.Items.itemByString(ingredParts[0]);
|
|
||||||
if (vaultItem != null) {
|
|
||||||
mat = vaultItem.getType();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
P.p.errorLog("Could not check vault for Item Name");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mat != null) {
|
|
||||||
materials.add(mat);
|
|
||||||
} else {
|
|
||||||
P.p.errorLog("Unknown Material: " + ingredParts[0]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSimple() {
|
|
||||||
return simple;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isMatchAny() {
|
|
||||||
return matchAny;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Material> getMaterials() {
|
|
||||||
return materials;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Material getSimpleMaterial() {
|
|
||||||
return materials.get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getNames() {
|
|
||||||
return names;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getLore() {
|
|
||||||
return lore;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean matches(ItemStack usedItem) {
|
|
||||||
if (simple) {
|
|
||||||
return matchSimple(usedItem);
|
|
||||||
} else if (matchAny){
|
|
||||||
return matchAny(usedItem);
|
|
||||||
} else {
|
|
||||||
return matchOne(usedItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean matchSimple(ItemStack usedItem) {
|
|
||||||
if (!materials.get(0).equals(usedItem.getType())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
//noinspection deprecation
|
|
||||||
return P.use1_13 || dur == usedItem.getDurability();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean matchAny(ItemStack usedItem) {
|
|
||||||
Material usedMat = usedItem.getType();
|
|
||||||
for (Material mat : materials) {
|
|
||||||
if (usedMat == mat) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!usedItem.hasItemMeta()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
ItemMeta meta = usedItem.getItemMeta();
|
|
||||||
assert meta != null;
|
|
||||||
if (meta.hasDisplayName()) {
|
|
||||||
String usedName = meta.getDisplayName();
|
|
||||||
for (String name : names) {
|
|
||||||
if (name.equalsIgnoreCase(usedName)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (meta.hasLore()) {
|
|
||||||
List<String> usedLore = meta.getLore();
|
|
||||||
assert usedLore != null;
|
|
||||||
for (String line : this.lore) {
|
|
||||||
for (String usedLine : usedLore) {
|
|
||||||
if (line.equalsIgnoreCase(usedLine) || line.equalsIgnoreCase(ChatColor.stripColor(usedLine))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean matchOne(ItemStack item) {
|
|
||||||
if (!materials.isEmpty()) {
|
|
||||||
if (item.getType() != materials.get(0)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (names.isEmpty() && lore.isEmpty()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (!item.hasItemMeta()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
ItemMeta meta = item.getItemMeta();
|
|
||||||
assert meta != null;
|
|
||||||
if (!names.isEmpty()) {
|
|
||||||
if (!meta.hasDisplayName() || !names.get(0).equalsIgnoreCase(meta.getDisplayName())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!lore.isEmpty()) {
|
|
||||||
if (!meta.hasLore()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lastIndex = 0;
|
|
||||||
List<String> usedLore = meta.getLore();
|
|
||||||
assert usedLore != null;
|
|
||||||
boolean foundFirst = false;
|
|
||||||
for (String line : lore) {
|
|
||||||
do {
|
|
||||||
if (lastIndex == usedLore.size()) {
|
|
||||||
// There is more in lore than in usedLore, bad
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
String usedLine = usedLore.get(lastIndex);
|
|
||||||
if (line.equalsIgnoreCase(usedLine) || line.equalsIgnoreCase(ChatColor.stripColor(usedLine))) {
|
|
||||||
// If the line is correct, we have found our first and we want all consecutive lines to also equal
|
|
||||||
foundFirst = true;
|
|
||||||
} else if (foundFirst) {
|
|
||||||
// If a consecutive line is not equal, thats bad
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
lastIndex++;
|
|
||||||
// If we once found one correct line, iterate over 'lore' consecutively
|
|
||||||
} while (!foundFirst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public ItemStack createDummy(int amount) {
|
|
||||||
if (simple) {
|
|
||||||
if (P.use1_13) {
|
|
||||||
return new ItemStack(getSimpleMaterial(), amount);
|
|
||||||
} else {
|
|
||||||
//noinspection deprecation
|
|
||||||
return new ItemStack(getSimpleMaterial(), amount, dur);
|
|
||||||
}
|
|
||||||
} else if (matchAny) {
|
|
||||||
if (!materials.isEmpty()) {
|
|
||||||
return new ItemStack(materials.get(0), amount);
|
|
||||||
} else if (!names.isEmpty()) {
|
|
||||||
ItemStack item = new ItemStack(Material.DIAMOND_HOE, amount);
|
|
||||||
ItemMeta meta = item.hasItemMeta() ? item.getItemMeta() : P.p.getServer().getItemFactory().getItemMeta(Material.DIAMOND_HOE);
|
|
||||||
assert meta != null;
|
|
||||||
meta.setDisplayName(names.get(0));
|
|
||||||
item.setItemMeta(meta);
|
|
||||||
return item;
|
|
||||||
} else if (!lore.isEmpty()) {
|
|
||||||
ItemStack item = new ItemStack(Material.DIAMOND_HOE, amount);
|
|
||||||
ItemMeta meta = item.hasItemMeta() ? item.getItemMeta() : P.p.getServer().getItemFactory().getItemMeta(Material.DIAMOND_HOE);
|
|
||||||
assert meta != null;
|
|
||||||
List<String> l = new ArrayList<>();
|
|
||||||
l.add(lore.get(0));
|
|
||||||
meta.setLore(l);
|
|
||||||
item.setItemMeta(meta);
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
return new ItemStack(Material.DIAMOND_HOE, amount);
|
|
||||||
} else {
|
|
||||||
ItemStack item;
|
|
||||||
ItemMeta meta;
|
|
||||||
if (!materials.isEmpty()) {
|
|
||||||
item = new ItemStack(materials.get(0), amount);
|
|
||||||
meta = item.hasItemMeta() ? item.getItemMeta() : P.p.getServer().getItemFactory().getItemMeta(materials.get(0));
|
|
||||||
} else {
|
|
||||||
item = new ItemStack(Material.DIAMOND_HOE, amount);
|
|
||||||
meta = item.hasItemMeta() ? item.getItemMeta() : P.p.getServer().getItemFactory().getItemMeta(Material.DIAMOND_HOE);
|
|
||||||
}
|
|
||||||
assert meta != null;
|
|
||||||
if (!names.isEmpty()) {
|
|
||||||
meta.setDisplayName(names.get(0));
|
|
||||||
item.setItemMeta(meta);
|
|
||||||
}
|
|
||||||
if (!lore.isEmpty()) {
|
|
||||||
meta.setLore(lore);
|
|
||||||
item.setItemMeta(meta);
|
|
||||||
}
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
if (simple) {
|
|
||||||
return "CustomItem{Simple: " + getSimpleMaterial().name().toLowerCase() + "}";
|
|
||||||
}
|
|
||||||
if (materials == null || names == null || lore == null) {
|
|
||||||
return "CustomItem{" + id + "}";
|
|
||||||
}
|
|
||||||
return "CustomItem{" + id + ": " + (matchAny ? "MatchAny, " : "MatchOne, ") + materials.size() + " Materials, " + names.size() + " Names, " + lore.size() + " Lore}";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,10 @@
|
|||||||
package com.dre.brewery;
|
package com.dre.brewery;
|
||||||
|
|
||||||
|
import com.dre.brewery.recipe.BCauldronRecipe;
|
||||||
|
import com.dre.brewery.recipe.BRecipe;
|
||||||
|
import com.dre.brewery.recipe.Ingredient;
|
||||||
|
import com.dre.brewery.recipe.RecipeItem;
|
||||||
|
import com.dre.brewery.recipe.SimpleItem;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
@ -24,9 +29,12 @@ public class RecipeTests {
|
|||||||
int y = recipe.amountOf(new ItemStack(Material.NETHER_BRICK));
|
int y = recipe.amountOf(new ItemStack(Material.NETHER_BRICK));
|
||||||
|
|
||||||
|
|
||||||
List<ItemStack> list = new ArrayList<>();
|
List<Ingredient> list = new ArrayList<>();
|
||||||
list.add(new ItemStack(Material.DIAMOND_HOE, 3));
|
Ingredient ing = new SimpleItem(Material.DIAMOND_HOE);
|
||||||
list.add(new ItemStack(Material.RED_MUSHROOM, 1));
|
ing.setAmount(3);
|
||||||
|
list.add(ing);
|
||||||
|
ing = new SimpleItem(Material.RED_MUSHROOM);
|
||||||
|
list.add(ing);
|
||||||
for (int i = 1; i < 20; i++) {
|
for (int i = 1; i < 20; i++) {
|
||||||
list.get(0).setAmount(i + 3);
|
list.get(0).setAmount(i + 3);
|
||||||
list.get(1).setAmount(i);
|
list.get(1).setAmount(i);
|
||||||
@ -46,5 +54,16 @@ public class RecipeTests {
|
|||||||
}
|
}
|
||||||
P.p.debugLog("Found best for i:" + i + " " + best);
|
P.p.debugLog("Found best for i:" + i + " " + best);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item = new ItemStack(Material.BARRIER);
|
||||||
|
itemMeta = item.getItemMeta();
|
||||||
|
l = new ArrayList<>();
|
||||||
|
l.add("Eine Tür");
|
||||||
|
l.add("§6Besonders gut geschützt");
|
||||||
|
itemMeta.setLore(l);
|
||||||
|
itemMeta.setDisplayName("Mauer");
|
||||||
|
item.setItemMeta(itemMeta);
|
||||||
|
|
||||||
|
RecipeItem.getMatchingRecipeItem(item, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user