package com.dre.brewery; import java.util.ArrayList; import java.util.Map; import java.util.HashMap; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.ItemStack; import org.bukkit.Material; import org.bukkit.potion.PotionEffectType; import org.bukkit.inventory.meta.PotionMeta; import com.dre.brewery.BRecipe; import com.dre.brewery.Brew; public class BIngredients { public static ArrayList possibleIngredients = new ArrayList(); public static ArrayList recipes = new ArrayList(); public static Map cookedNames = new HashMap(); private Map ingredients = new HashMap(); private int cookedTime; // Represents ingredients in Cauldron, Brew // Init a new BIngredients public BIngredients() { } // Init a copy of BIngredients with existing values public BIngredients(Map ingredients, int cookedTime) { this.ingredients.putAll(ingredients); this.cookedTime = cookedTime; } // Add an ingredient to this public void add(Material ingredient) { if (ingredients.containsKey(ingredient)) { int newAmount = ingredients.get(ingredient) + 1; ingredients.put(ingredient, newAmount); } else { this.ingredients.put(ingredient, 1); } } // returns an Potion item with cooked ingredients public ItemStack cook(int state) { ItemStack potion = new ItemStack(Material.POTION); PotionMeta potionMeta = (PotionMeta) potion.getItemMeta(); // cookedTime is always time in minutes, state may differ with number of ticks cookedTime = state; String cookedName = null; BRecipe cookRecipe = getCookRecipe(); int uid = Brew.generateUID(); if (cookRecipe != null) { // Potion is best with cooking only, can still be destilled, etc. int quality = (int) Math.round((getIngredientQuality(cookRecipe) + getCookingQuality(cookRecipe)) / 2.0); P.p.log("cooked potion has Quality: " + quality); new Brew(uid, quality, cookRecipe, new BIngredients(ingredients, cookedTime)); cookedName = cookRecipe.getName(quality); potion.setDurability(Brew.PotionColor.valueOf(cookRecipe.getColor()).getColorId(true)); } else { // new base potion new Brew(uid, new BIngredients(ingredients, cookedTime)); if (state == 1) { cookedName = "Schlammiger Sud"; potion.setDurability(Brew.PotionColor.BLUE.getColorId(false)); } else { for (Material ingredient : ingredients.keySet()) { if (cookedNames.containsKey(ingredient)) { // if more than half of the ingredients is of one kind if (ingredients.get(ingredient) > (getIngredientsCount() / 2)) { cookedName = cookedNames.get(ingredient); potion.setDurability(Brew.PotionColor.CYAN.getColorId(true)); } } } } } if (cookedName == null) { // if no name could be found cookedName = "Undefinierbarer Sud"; potion.setDurability(Brew.PotionColor.CYAN.getColorId(true)); } potionMeta.setDisplayName(cookedName); // This effect stores the UID in its Duration potionMeta.addCustomEffect((PotionEffectType.REGENERATION).createEffect((uid * 4), 0), true); potion.setItemMeta(potionMeta); return potion; } // returns amount of ingredients private int getIngredientsCount() { int count = 0; for (int value : ingredients.values()) { count += value; } return count; } //returns the recipe with the given name public static BRecipe getRecipeByName(String name) { for (BRecipe recipe : recipes) { if (recipe.getName(5).equalsIgnoreCase(name)) { return recipe; } } return null; } // best recipe for current state of potion, STILL not always returns the // correct one... public BRecipe getBestRecipe(byte wood, float time) { float quality = 0; int ingredientQuality = 0; int cookingQuality = 0; int woodQuality = 0; int ageQuality = 0; BRecipe bestRecipe = null; for (BRecipe recipe : recipes) { ingredientQuality = getIngredientQuality(recipe); cookingQuality = getCookingQuality(recipe); if (ingredientQuality > -1) { P.p.log("Ingredient Quality: " + ingredientQuality + " Cooking Quality: " + cookingQuality + " Wood Quality: " + getWoodQuality(recipe, wood) + " age Quality: " + getAgeQuality(recipe, time) + " for " + recipe.getName(5)); if (recipe.needsToAge()) { // needs riping in barrel ageQuality = getAgeQuality(recipe, time); woodQuality = getWoodQuality(recipe, wood); // is this recipe better than the previous best? if ((((float) ingredientQuality + cookingQuality + woodQuality + ageQuality) / 4) > quality) { quality = ((float) ingredientQuality + cookingQuality + woodQuality + ageQuality) / 4; bestRecipe = recipe; } } else { // calculate quality without age and barrel if ((((float) ingredientQuality + cookingQuality) / 2) > quality) { quality = ((float) ingredientQuality + cookingQuality) / 2; bestRecipe = recipe; } } } } if (bestRecipe != null) { P.p.log("best recipe: " + bestRecipe.getName(5) + " has Quality= " + quality); } return bestRecipe; } // returns recipe that is cooking only and matches the ingredients and // cooking time public BRecipe getCookRecipe() { BRecipe bestRecipe = getBestRecipe((byte) 0, 0); // Check if best recipe is cooking only if (bestRecipe != null) { if (bestRecipe.isCookingOnly()) { return bestRecipe; } } return null; } // returns the currently best matching recipe for distilling for the // ingredients and cooking time public BRecipe getdistillRecipe() { BRecipe bestRecipe = getBestRecipe((byte) 0, 0); // Check if best recipe needs to be destilled if (bestRecipe != null) { if (bestRecipe.needsDistilling()) { return bestRecipe; } } return null; } // returns currently best matching recipe for ingredients, cooking- and // ageingtime public BRecipe getAgeRecipe(byte wood, float time) { BRecipe bestRecipe = getBestRecipe(wood, time); if (bestRecipe != null) { if (bestRecipe.needsToAge()) { return bestRecipe; } } return null; } // returns the quality of the ingredients conditioning given recipe, -1 if // no recipe is near them public int getIngredientQuality(BRecipe recipe) { float quality = 10; int count = 0; int badStuff = 0; if (recipe.isMissingIngredients(ingredients)) { // when ingredients are not complete return -1; } for (Material ingredient : ingredients.keySet()) { count = ingredients.get(ingredient); if (recipe.amountOf(ingredient) == 0) { // this ingredient doesnt belong into the recipe if (count > (getIngredientsCount() / 2)) { // when more than half of the ingredients dont fit into the // recipe return -1; } badStuff++; if (badStuff < ingredients.size()) { // when there are other ingredients quality -= count * 2; continue; } else { // ingredients dont fit at all return -1; } } // calculate the quality quality -= (((float) Math.abs(count - recipe.amountOf(ingredient)) / recipe.allowedCountDiff(recipe.amountOf(ingredient))) * 10.0); } /* * if(quality != 0){ quality /= ingredients.size(); } */ if (quality >= 0) { return Math.round(quality); } return -1; } // returns the quality regarding the cooking-time conditioning given Recipe public int getCookingQuality(BRecipe recipe) { int quality = 10 - (int) Math.round(((float) Math.abs(cookedTime - recipe.getCookingTime()) / recipe.allowedTimeDiff(recipe.getCookingTime())) * 10.0); if (quality > 0) { return quality; } return 0; } // returns the quality regarding the barrel wood conditioning given Recipe public int getWoodQuality(BRecipe recipe, byte wood) { if (recipe.getWood() == 0x8) { // type of wood doesnt matter return 10; } int quality = 10 - (int) Math.round(recipe.getWoodDiff(wood) * recipe.getDifficulty()); if (quality > 0) { return quality; } return 0; } // returns the quality regarding the ageing time conditioning given Recipe public int getAgeQuality(BRecipe recipe, float time) { int quality = 10 - (int) Math.round(Math.abs(time - recipe.getAge()) * ((float) recipe.getDifficulty() / 2)); if (quality > 0) { return quality; } return 0; } // saves data into ingredient section of Brew/BCauldron public void save(ConfigurationSection config) { if (cookedTime != 0) { config.set("cookedTime", cookedTime); } // convert the ingredient Material to id Map mats = new HashMap(); for (Material mat : ingredients.keySet()) { mats.put(mat.getId(), ingredients.get(mat)); } // list all Material ids with their amount ConfigurationSection matSection = config.createSection("mats"); for (int id : mats.keySet()) { matSection.set("" + id, mats.get(id)); } } }