From 2d3e5dfbac0b3cdd266ea5a4406a270f9a979571 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Mon, 21 Oct 2019 12:44:26 +0200 Subject: [PATCH] Implemented Custom Lore --- resources/config/v12/de/config.yml | 21 ++ resources/config/v13/de/config.yml | 82 +++-- resources/config/v13/en/config.yml | 23 ++ src/com/dre/brewery/BIngredients.java | 1 + src/com/dre/brewery/BRecipe.java | 67 ++++ src/com/dre/brewery/Brew.java | 2 + .../brewery/listeners/InventoryListener.java | 2 +- src/com/dre/brewery/lore/BrewLore.java | 327 +++++++++++++++--- src/com/dre/brewery/utility/Tuple.java | 80 +++++ 9 files changed, 534 insertions(+), 71 deletions(-) create mode 100644 src/com/dre/brewery/utility/Tuple.java diff --git a/resources/config/v12/de/config.yml b/resources/config/v12/de/config.yml index ac799da..aa2e05b 100644 --- a/resources/config/v12/de/config.yml +++ b/resources/config/v12/de/config.yml @@ -96,6 +96,8 @@ oldMat: true # Oder RGB Farben (Hex: also zB '99FF33') (Ohne #) (mit '') (Einfach nach "HTML color" im Internet suchen) # difficulty: 1-10 Genauigkeit der Einhaltung der Vorgaben (1 = ungenau/einfach 10 = sehr genau/schwer) # alcohol: Alkoholgehalt 0-100 in absoluter Menge bei perfektem Getränk (wird dem Spieler hinzugefügt, bei 100 = tot) +# lore: Auflistung von zusätzlichem Text auf dem fertigen Trank. (Farbcodes möglich: z.b. &6) +# Lore nur für bestimmte Qualität möglich mit + Schlecht, ++ Mittel, +++ Gut, vorne anhängen. # effects: Auflistung Effekt/Level/Dauer Besonderere Trank-Effekte beim Trinken, Dauer in sek. # Ein 'X' an den Namen anhängen, um ihn zu verbergen. Bsp: 'POISONX/2/10' (WEAKNESS, INCREASE_DAMAGE, SLOW und SPEED sind immer verborgen.) # Effekte sind ab der 1.9 immer verborgen, wegen Änderungen an den Tränken. @@ -124,6 +126,14 @@ recipes: color: DARK_RED difficulty: 3 alcohol: 23 + lore: + - Dies ist ein Beispiel Trank + - ++Ganz normales Beispiel + - Man kann ihn nicht brauen + - Aber dies würde auf dem Trank stehen + - + Riecht eklig + - ++ Riecht ganz ok + - +++ Riecht richtig gut effects: - FIRE_RESISTANCE/20 - HEAL/1 @@ -162,6 +172,8 @@ recipes: color: BLACK difficulty: 2 alcohol: 7 + lore: + - +++ &8Perlt wunderschön 4: name: Scheußlicher Met/Met/&6Goldener Met ingredients: @@ -173,6 +185,8 @@ recipes: color: ORANGE difficulty: 2 alcohol: 9 + lore: + - +++ Hat einen goldenen Schein 5: name: Apfelmet/Süßer Apfelmet/&6Goldensüßer Apfelmet ingredients: @@ -185,6 +199,10 @@ recipes: color: ORANGE difficulty: 4 alcohol: 12 + lore: + - + Ist da wirklich Apfel drin? + - ++ Schmeckt nach süßem Apfel + - +++ Hat eine wunderbare Apfelnote effects: - WATER_BREATHINGX/1-2/150 6: @@ -212,6 +230,8 @@ recipes: color: BRIGHT_GREY difficulty: 4 alcohol: 20 + lore: + - + &8Fast nicht trinkbar effects: - WEAKNESS/15 - POISON/10 @@ -245,6 +265,7 @@ recipes: cookingtime: 2 color: BLACK difficulty: 3 + lore: + &8Bestimmt schon eine Woche alt effects: - REGENERATION/1/2-5 - SPEED/1/30-140 diff --git a/resources/config/v13/de/config.yml b/resources/config/v13/de/config.yml index 681e8fb..f55c7f8 100644 --- a/resources/config/v13/de/config.yml +++ b/resources/config/v13/de/config.yml @@ -92,6 +92,8 @@ version: '1.8' # Oder RGB Farben (Hex: also zB '99FF33') (Ohne #) (mit '') (Einfach nach "HTML color" im Internet suchen) # difficulty: 1-10 Genauigkeit der Einhaltung der Vorgaben (1 = ungenau/einfach 10 = sehr genau/schwer) # alcohol: Alkoholgehalt 0-100 in absoluter Menge bei perfektem Getränk (wird dem Spieler hinzugefügt, bei 100 = tot) +# lore: Auflistung von zusätzlichem Text auf dem fertigen Trank. (Farbcodes möglich: z.b. &6) +# Lore nur für bestimmte Qualität möglich mit + Schlecht, ++ Mittel, +++ Gut, vorne anhängen. # effects: Auflistung Effekt/Level/Dauer Besonderere Trank-Effekte beim Trinken, Dauer in sek. # Mögliche Effekte: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/potion/PotionEffectType.html # Minimale und Maximale Level/Dauer können durch "-" festgelegt werden, Bsp: 'SPEED/1-2/30-40' = Level 1 und 30 sek minimal, Level 2 und 40 sek maximal @@ -103,11 +105,11 @@ recipes: 0: name: Schlechtes Beispiel/Beispiel/Gutes Beispiel ingredients: - - Sugar_Cane/5 - - Diamond/1 - - Cocoa_Beans/20 - - Spruce_Planks/8 - - Bedrock/1 + - Sugar_Cane/5 + - Diamond/1 + - Cocoa_Beans/20 + - Spruce_Planks/8 + - Bedrock/1 cookingtime: 3 distillruns: 2 distilltime: 60 @@ -116,15 +118,22 @@ recipes: color: DARK_RED difficulty: 3 alcohol: 23 + lore: + - Dies ist ein Beispiel Trank + - ++Ganz normales Beispiel + - Dies würde auf dem Trank stehen + - + Riecht eklig + - ++ Riecht ganz ok + - +++ Riecht richtig gut effects: - - FIRE_RESISTANCE/20 - - HEAL/1 - - WEAKNESS/2-3/50-60 - - POISON/1-0/20-0 + - FIRE_RESISTANCE/20 + - HEAL/1 + - WEAKNESS/2-3/50-60 + - POISON/1-0/20-0 1: name: Ranziges Weißbier/Weißbier/Feines Weißbier ingredients: - - Wheat/3 + - Wheat/3 cookingtime: 8 distillruns: 0 wood: 1 @@ -135,18 +144,20 @@ recipes: 2: name: Ranziges Bier/Bier/Feines Bier ingredients: - - Wheat/6 + - Wheat/6 cookingtime: 8 distillruns: 0 wood: 0 age: 3 color: ORANGE difficulty: 1 + lore: + - +++ &8Perlt wunderschön alcohol: 6 3: name: Ranziges Dunkelbier/Dunkelbier/Feines Dunkelbier ingredients: - - Wheat/6 + - Wheat/6 cookingtime: 8 distillruns: 0 wood: 4 @@ -157,7 +168,7 @@ recipes: 4: name: Scheußlicher Met/Met/&6Goldener Met ingredients: - - Sugar_Cane/6 + - Sugar_Cane/6 cookingtime: 3 distillruns: 0 wood: 2 @@ -165,11 +176,13 @@ recipes: color: ORANGE difficulty: 2 alcohol: 9 + lore: + - +++ Hat einen goldenen Schein 5: name: Apfelmet/Süßer Apfelmet/&6Goldensüßer Apfelmet ingredients: - - Sugar_Cane/6 - - Apple/2 + - Sugar_Cane/6 + - Apple/2 cookingtime: 4 distillruns: 0 wood: 2 @@ -177,12 +190,16 @@ recipes: color: ORANGE difficulty: 4 alcohol: 12 + lore: + - + Ist da wirklich Apfel drin? + - ++ Schmeckt nach süßem Apfel + - +++ Hat eine wunderbare Apfelnote effects: - - WATER_BREATHING/1-2/150 + - WATER_BREATHING/1-2/150 6: name: Bitterer Rum/Würziger Rum/&6Goldener Rum ingredients: - - Sugar_Cane/14 + - Sugar_Cane/14 cookingtime: 5 distillruns: 2 distilltime: 30 @@ -192,25 +209,27 @@ recipes: difficulty: 6 alcohol: 30 effects: - - FIRE_RESISTANCE/1/20-100 - - POISON/1-0/30-0 + - FIRE_RESISTANCE/1/20-100 + - POISON/1-0/30-0 7: name: Abgeranzter Vodka/Vodka/Russischer Vodka ingredients: - - Potato/10 + - Potato/10 cookingtime: 15 distillruns: 3 age: 0 color: BRIGHT_GREY difficulty: 4 alcohol: 20 + lore: + - + &8Fast nicht trinkbar effects: - - WEAKNESS/15 - - POISON/10 + - WEAKNESS/15 + - POISON/10 8: name: minderwertiger Absinth/Absinth/Starker Absinth ingredients: - - Grass/15 + - Grass/15 cookingtime: 3 distillruns: 6 distilltime: 80 @@ -218,28 +237,29 @@ recipes: difficulty: 8 alcohol: 45 effects: - - POISON/20-30 + - POISON/20-30 9: name: Kartoffelsuppe ingredients: - - Potato/5 - - Grass/3 + - Potato/5 + - Grass/3 cookingtime: 3 color: PINK difficulty: 1 effects: - - HEAL/0-1 + - HEAL/0-1 10: name: Fader Kaffee/Kaffee/Starker Kaffee ingredients: - - Cocoa_Beans/12 - - Milk_Bucket/2 + - Cocoa_Beans/12 + - Milk_Bucket/2 cookingtime: 2 color: BLACK difficulty: 3 + lore: + &8Bestimmt schon eine Woche alt effects: - - REGENERATION/1/2-5 - - SPEED/1/30-140 + - REGENERATION/1/2-5 + - SPEED/1/30-140 # Mehr Ideen für Rezepte: Cachaca, Gin, Whiskey, Tequila, Cidre, etc, sowie Rezeptvarianten wie Goldener Vodka etc. # Ich werde keine weiteren Rezepte zu dieser Standardconfig hinzufügen, da diese öffentlich und für Spieler zum Abschauen einsehbar wären diff --git a/resources/config/v13/en/config.yml b/resources/config/v13/en/config.yml index 376d920..2829bf9 100644 --- a/resources/config/v13/en/config.yml +++ b/resources/config/v13/en/config.yml @@ -93,6 +93,10 @@ version: '1.8' # Or RGB colors (hex: for example '99FF33') (with '') (search for "HTML color" on the internet) # difficulty: 1-10 accuracy needed to get good quality (1 = unaccurate/easy, 10 = very precise/hard) # alcohol: Absolute amount of alcohol 0-100 in a perfect potion (will be added directly to the player, where 100 means fainting) +# lore: List of additional text on the finished brew. (Formatting codes possible: such as &6) +# Specific lore for quality possible, using + bad, ++ normal, ++ good, added to the front of the line. +# lore: Auflistung von zusätzlichem Text auf dem fertigen Trank. (Farbcodes möglich: z.b. &6) +# Lore nur für bestimmte Qualität möglich mit + Schlecht, ++ Mittel, +++ Gut, vorne anhängen. # effects: List of effect/level/duration Special potion-effect when drinking, duration in sek. # Possible Effects: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/potion/PotionEffectType.html # Level or Duration ranges may be specified with a "-", ex. 'SPEED/1-2/30-40' = lvl 1 and 30 sec at worst and lvl 2 and 40 sec at best @@ -117,6 +121,13 @@ recipes: color: DARK_RED difficulty: 3 alcohol: 23 + lore: + - This is an examble brew + - ++Just a normal Example + - This text would be on the brew + - + Smells disgusting + - ++ Smells alright + - +++ Smells really good effects: - FIRE_RESISTANCE/20 - HEAL/1 @@ -143,6 +154,8 @@ recipes: age: 3 color: ORANGE difficulty: 1 + lore: + - +++ &8Crisp taste alcohol: 6 3: name: Skunky Darkbeer/Darkbeer/Fine Darkbeer @@ -154,6 +167,8 @@ recipes: age: 8 color: BLACK difficulty: 2 + lore: + - +++ &8Roasted taste alcohol: 7 4: name: Awkward Mead/Mead/&6Golden Mead @@ -165,6 +180,8 @@ recipes: age: 4 color: ORANGE difficulty: 2 + lore: + - +++ Has a golden shine alcohol: 9 5: name: Apple Mead/Sweet Apple Mead/&6Sweet Golden Apple Mead @@ -178,6 +195,10 @@ recipes: color: ORANGE difficulty: 4 alcohol: 12 + lore: + - +Is there any Apple in this? + - ++Refreshing taste of Apple + - +++Sweetest hint of Apple effects: - WATER_BREATHING/1-2/150 6: @@ -205,6 +226,7 @@ recipes: color: BRIGHT_GREY difficulty: 4 alcohol: 20 + lore: +&8Almost undrinkable effects: - WEAKNESS/15 - POISON/10 @@ -238,6 +260,7 @@ recipes: cookingtime: 2 color: BLACK difficulty: 3 + lore: + &8Probably a week old effects: - REGENERATION/1/2-5 - SPEED/1/30-140 diff --git a/src/com/dre/brewery/BIngredients.java b/src/com/dre/brewery/BIngredients.java index fc44e07..9dbffed 100644 --- a/src/com/dre/brewery/BIngredients.java +++ b/src/com/dre/brewery/BIngredients.java @@ -93,6 +93,7 @@ public class BIngredients { P.p.debugLog("cooked potion has Quality: " + quality); brew = new Brew(quality, cookRecipe, this); BrewLore lore = new BrewLore(brew, potionMeta); + lore.updateCustomLore(); lore.addOrReplaceEffects(brew.getEffects(), brew.getQuality()); cookedName = cookRecipe.getName(quality); diff --git a/src/com/dre/brewery/BRecipe.java b/src/com/dre/brewery/BRecipe.java index 4263f78..6ce49e9 100644 --- a/src/com/dre/brewery/BRecipe.java +++ b/src/com/dre/brewery/BRecipe.java @@ -2,9 +2,13 @@ package com.dre.brewery; import com.dre.brewery.filedata.BConfig; import com.dre.brewery.utility.PotionColor; +import com.dre.brewery.utility.Tuple; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.craftbukkit.libs.jline.internal.Nullable; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -21,6 +25,7 @@ public class BRecipe { private String color; // color of the destilled/finished potion private int difficulty; // difficulty to brew the potion, how exact the instruction has to be followed private int alcohol; // Alcohol in perfect potion + private List> lore; // Custom Lore on the Potion. The int is for Quality Lore, 0 = any, 1,2,3 = Bad,Middle,Good private ArrayList effects = new ArrayList<>(); // Special Effects when drinking public BRecipe(ConfigurationSection configSectionRecipes, String recipeId) { @@ -103,6 +108,38 @@ public class BRecipe { this.difficulty = configSectionRecipes.getInt(recipeId + ".difficulty", 0); this.alcohol = configSectionRecipes.getInt(recipeId + ".alcohol", 0); + List load = null; + if (configSectionRecipes.isString(recipeId + ".lore")) { + load = new ArrayList<>(1); + load.add(configSectionRecipes.getString(recipeId + ".lore")); + } else if (configSectionRecipes.isList(recipeId + ".lore")) { + load = configSectionRecipes.getStringList(recipeId + ".lore"); + } + if (load != null) { + for (String line : load) { + line = P.p.color(line); + int plus = 0; + if (line.startsWith("+++")) { + plus = 3; + line = line.substring(3); + } else if (line.startsWith("++")) { + plus = 2; + line = line.substring(2); + } else if (line.startsWith("+")) { + plus = 1; + line = line.substring(1); + } + if (line.startsWith(" ")) { + line = line.substring(1); + } + if (!line.startsWith("§")) { + line = "§9" + line; + } + if (lore == null) lore = new ArrayList<>(); + lore.add(new Tuple<>(plus, line)); + } + } + List effectStringList = configSectionRecipes.getStringList(recipeId + ".effects"); if (effectStringList != null) { for (String effectString : effectStringList) { @@ -333,6 +370,7 @@ public class BRecipe { return distillTime; } + @NotNull public String getColor() { if (color != null) { return color.toUpperCase(); @@ -357,6 +395,35 @@ public class BRecipe { return alcohol; } + public boolean hasLore() { + return lore != null && !lore.isEmpty(); + } + + @Nullable + public List> getLore() { + return lore; + } + + @Nullable + public List getLoreForQuality(int quality) { + if (lore == null) return null; + int plus; + if (quality <= 3) { + plus = 1; + } else if (quality <= 7) { + plus = 2; + } else { + plus = 3; + } + List list = new ArrayList<>(lore.size()); + for (Tuple line : lore) { + if (line.first() == 0 || line.first() == plus) { + list.add(line.second()); + } + } + return list; + } + public ArrayList getEffects() { return effects; } diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index 32e9189..036374f 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -490,6 +490,7 @@ public class Brew { currentRecipe = recipe; quality = calcQuality(); + lore.updateCustomLore(); lore.addOrReplaceEffects(getEffects(), quality); potionMeta.setDisplayName(P.p.color("&f" + recipe.getName(quality))); PotionColor.fromString(recipe.getColor()).colorBrew(potionMeta, slotItem, canDistill()); @@ -559,6 +560,7 @@ public class Brew { currentRecipe = recipe; quality = calcQuality(); + lore.updateCustomLore(); lore.addOrReplaceEffects(getEffects(), quality); potionMeta.setDisplayName(P.p.color("&f" + recipe.getName(quality))); PotionColor.fromString(recipe.getColor()).colorBrew(potionMeta, item, canDistill()); diff --git a/src/com/dre/brewery/listeners/InventoryListener.java b/src/com/dre/brewery/listeners/InventoryListener.java index bcc53b0..57a3023 100644 --- a/src/com/dre/brewery/listeners/InventoryListener.java +++ b/src/com/dre/brewery/listeners/InventoryListener.java @@ -117,7 +117,7 @@ public class InventoryListener implements Listener { Brew brew = Brew.get(item); if (brew != null) { P.p.log(brew.toString()); - P.p.log(potion.getLore().get(0).replaceAll("§", "")); + //P.p.log(potion.getLore().get(0).replaceAll("§", "")); //P.p.log("similar to beispiel? " + BRecipe.get("Beispiel").createBrew(10).isSimilar(brew)); brew.touch(); diff --git a/src/com/dre/brewery/lore/BrewLore.java b/src/com/dre/brewery/lore/BrewLore.java index 7891db2..23819ea 100644 --- a/src/com/dre/brewery/lore/BrewLore.java +++ b/src/com/dre/brewery/lore/BrewLore.java @@ -5,21 +5,16 @@ import com.dre.brewery.utility.BUtil; import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; public class BrewLore { - - private static final String INGR = "§v"; - private static final String COOK = "§w"; - private static final String DISTILL = "§x"; - private static final String AGE = "§y"; - private static final String WOOD = "§z"; - private Brew brew; private PotionMeta meta; private List lore; + private boolean lineAddedOrRem = false; public BrewLore(Brew brew, PotionMeta meta) { this.brew = brew; @@ -31,21 +26,79 @@ public class BrewLore { } } - // Write the new lore into the Meta + /** + * Write the new lore into the Meta + * Should be called at the end of operation on this Brew Lore + */ public PotionMeta write() { + if (lineAddedOrRem) { + updateSpacer(); + } meta.setLore(lore); return meta; } - public void updateIngredientLore(boolean qualityColor) { - if (qualityColor && brew.hasRecipe()) { - String prefix = getQualityColor(brew.getIngredients().getIngredientQuality(brew.getCurrentRecipe())); - addOrReplaceLore(INGR, prefix, P.p.languageReader.get("Brew_Ingredients")); - } else { - removeLore(INGR, P.p.languageReader.get("Brew_Ingredients")); + /** + * adds or removes an empty line in lore to space out the text a bit + */ + public void updateSpacer() { + boolean hasCustom = false; + boolean hasSpace = false; + for (int i = 0; i < lore.size(); i++) { + Type t = Type.get(lore.get(i)); + if (t == Type.CUSTOM) { + hasCustom = true; + } else if (t == Type.SPACE) { + hasSpace = true; + } else if (t != null && t.isAfter(Type.SPACE)) { + if (hasSpace) return; + + if (hasCustom || P.useNBT) { + // We want to add the spacer if we have Custom Lore, to have a space between custom and brew lore. + // Also add a space if there is no Custom Lore but we don't already have a invisible data line + lore.add(i, Type.SPACE.id); + } + return; + } + } + if (hasSpace) { + // There was a space but nothing after the space + removeLore(Type.SPACE); } } + /*private void addSpacer() { + if (!P.useNBT) return; + + for (int i = 0; i < lore.size(); i++) { + if (Type.get(lore.get(i)) != null) { + if (i == 0 || !lore.get(i - 1).equals("")) { + lore.add(i, ""); + } + break; + } + } + }*/ + + /** + * updates the IngredientLore + * + * @param qualityColor If the lore should have colors according to quality + */ + public void updateIngredientLore(boolean qualityColor) { + if (qualityColor && brew.hasRecipe()) { + String prefix = getQualityColor(brew.getIngredients().getIngredientQuality(brew.getCurrentRecipe())); + addOrReplaceLore(Type.INGR, prefix, P.p.languageReader.get("Brew_Ingredients")); + } else { + removeLore(Type.INGR, P.p.languageReader.get("Brew_Ingredients")); + } + } + + /** + * updates the CookLore + * + * @param qualityColor If the lore should have colors according to quality + */ public void updateCookLore(boolean qualityColor) { if (qualityColor && brew.hasRecipe() && brew.getDistillRuns() > 0 == brew.getCurrentRecipe().needsDistilling()) { BIngredients ingredients = brew.getIngredients(); @@ -54,13 +107,17 @@ public class BrewLore { if (ingredients.getCookedTime() > 1) { prefix = prefix + P.p.languageReader.get("Brew_MinutePluralPostfix"); } - addOrReplaceLore(COOK, prefix, " " + P.p.languageReader.get("Brew_fermented")); + addOrReplaceLore(Type.COOK, prefix, " " + P.p.languageReader.get("Brew_fermented")); } else { - removeLore(COOK, P.p.languageReader.get("Brew_fermented")); + removeLore(Type.COOK, P.p.languageReader.get("Brew_fermented")); } } - // sets the DistillLore. Prefix is the color to be used + /** + * updates the DistillLore + * + * @param qualityColor If the lore should have colors according to quality + */ public void updateDistillLore(boolean qualityColor) { if (brew.getDistillRuns() <= 0) return; String prefix; @@ -75,10 +132,14 @@ public class BrewLore { prefix = prefix + distillRuns + P.p.languageReader.get("Brew_-times") + " "; } } - addOrReplaceLore(DISTILL, prefix, P.p.languageReader.get("Brew_Distilled")); + addOrReplaceLore(Type.DISTILL, prefix, P.p.languageReader.get("Brew_Distilled")); } - // sets the AgeLore. Prefix is the color to be used + /** + * updates the AgeLore + * + * @param qualityColor If the lore should have colors according to quality + */ public void updateAgeLore(boolean qualityColor) { String prefix; float age = brew.getAgeTime(); @@ -96,25 +157,64 @@ public class BrewLore { prefix = prefix + P.p.languageReader.get("Brew_HundredsOfYears") + " "; } } - addOrReplaceLore(AGE, prefix, P.p.languageReader.get("Brew_BarrelRiped")); + addOrReplaceLore(Type.AGE, prefix, P.p.languageReader.get("Brew_BarrelRiped")); } - // updates/sets the color on WoodLore + /** + * updates the WoodLore + * + * @param qualityColor If the lore should have colors according to quality + */ public void updateWoodLore(boolean qualityColor) { if (qualityColor && brew.hasRecipe()) { int quality = brew.getIngredients().getWoodQuality(brew.getCurrentRecipe(), brew.getWood()); - addOrReplaceLore(WOOD, getQualityColor(quality), P.p.languageReader.get("Brew_Woodtype")); + addOrReplaceLore(Type.WOOD, getQualityColor(quality), P.p.languageReader.get("Brew_Woodtype")); } else { - removeLore(WOOD, P.p.languageReader.get("Brew_Woodtype")); + removeLore(Type.WOOD, P.p.languageReader.get("Brew_Woodtype")); } } - // Converts to/from qualitycolored Lore + /** + * updates the Custom Lore + */ + public void updateCustomLore() { + int index = Type.CUSTOM.findInLore(lore); + + while (index > -1) { + lore.remove(index); + index = Type.CUSTOM.findInLore(lore); + } + + BRecipe recipe = brew.getCurrentRecipe(); + if (recipe != null && recipe.hasLore()) { + index = -1; + for (String line : recipe.getLoreForQuality(brew.getQuality())) { + if (index == -1) { + index = addLore(Type.CUSTOM, "", line); + index++; + } else { + lore.add(index, Type.CUSTOM.id + line); + index++; + } + } + + /*if (index < lore.size()) { + // If there are more lines after this, add a spacer + lore.add(index, Type.SPACE.id); + }*/ + } + } + + /** + * Converts to/from qualitycolored Lore + */ public void convertLore(boolean toQuality) { if (!brew.hasRecipe()) { return; } + updateCustomLore(); + if (!brew.isUnlabeled()) { // Ingredients updateIngredientLore(toQuality); @@ -139,33 +239,87 @@ public class BrewLore { } } - // Adds or replaces a line of Lore. - // Searches for type and if not found for Substring lore and replaces it - public void addOrReplaceLore(String type, String prefix, String line) { - int index = BUtil.indexOfStart(lore, type); + /** + * Adds or replaces a line of Lore. + * Searches for type and if not found for Substring lore and replaces it + * + * @param type The Type of BrewLore to replace + * @param prefix The Prefix to add to the line of lore + * @param line The Line of Lore to add or replace + */ + public int addOrReplaceLore(Type type, String prefix, String line) { + int index = type.findInLore(lore); if (index == -1) { index = BUtil.indexOfSubstring(lore, line); } if (index > -1) { - lore.set(index, type + prefix + line); + lore.set(index, type.id + prefix + line); + return index; } else { - lore.add(type + prefix + line); + return addLore(type, prefix, line); } } - // Adds or replaces a line of Lore. - // Searches for type and if not found for Substring lore and replaces it - public void removeLore(String type, String line) { - int index = BUtil.indexOfStart(lore, type); + /** + * Adds a line of Lore in the correct ordering + * + * @param type The Type of BrewLore to add + * @param prefix The Prefix to add to the line of lore + * @param line The Line of Lore to add or add + */ + public int addLore(Type type, String prefix, String line) { + lineAddedOrRem = true; + for (int i = 0; i < lore.size(); i++) { + Type existing = Type.get(lore.get(i)); + if (existing != null && existing.isAfter(type)) { + lore.add(i, type.id + prefix + line); + return i; + } + } + lore.add(type.id + prefix + line); + return lore.size() - 1; + } + + /** + * Searches for type and if not found for Substring lore and removes it + */ + public void removeLore(Type type, String line) { + int index = type.findInLore(lore); if (index == -1) { index = BUtil.indexOfSubstring(lore, line); } if (index > -1) { + lineAddedOrRem = true; lore.remove(index); } } - // Adds the Effect names to the Items description + /** + * Searches for type and removes it + */ + public void removeLore(Type type) { + int index = type.findInLore(lore); + if (index > -1) { + lineAddedOrRem = true; + lore.remove(index); + } + } + + /** + * Removes all Brew Lore lines + */ + public void removeAll() { + for (Type t : Type.values()) { + int index = t.findInLore(lore); + if (index > -1) { + lore.remove(index); + } + } + } + + /** + * Adds the Effect names to the Items description + */ public void addOrReplaceEffects(ArrayList effects, int quality) { if (!P.use1_9 && effects != null) { for (BEffect effect : effects) { @@ -176,7 +330,19 @@ public class BrewLore { } } - // Removes all effects + /** + * If the Lore Line at index is a Brew Lore line + * + * @param index the index in lore to check + * @return true if the line at index is of any Brew Lore type + */ + public boolean isBrewLore(int index) { + return index < lore.size() && Type.get(lore.get(index)) != null; + } + + /** + * Removes all effects + */ public void removeEffects() { if (meta.hasCustomEffects()) { for (PotionEffect effect : new ArrayList<>(meta.getCustomEffects())) { @@ -188,6 +354,9 @@ public class BrewLore { } } + /** + * Remove the Old Spacer from the legacy potion data system + */ public void removeLegacySpacing() { if (P.useNBT) { // Using NBT we don't get the invisible line, so we keep our spacing @@ -199,6 +368,9 @@ public class BrewLore { } } + /** + * Remove any Brew Data from Lore + */ public void removeLoreData() { int index = BUtil.indexOfStart(lore, LoreSaveStream.IDENTIFIER); if (index != -1) { @@ -207,14 +379,16 @@ public class BrewLore { } } - // True if the PotionMeta has Lore in quality color + /** + * True if the PotionMeta has Lore in quality color + */ public static boolean hasColorLore(PotionMeta meta) { if (!meta.hasLore()) return false; List lore = meta.getLore(); if (lore.size() < 2) { return false; } - if (BUtil.indexOfStart(lore, INGR) != -1) { + if (Type.INGR.findInLore(lore) != -1) { // Ingredient lore present, must be quality colored return true; } @@ -222,7 +396,12 @@ public class BrewLore { //!meta.getLore().get(1).startsWith("§7"); } - // gets the Color that represents a quality in Lore + /** + * gets the Color that represents a quality in Lore + * + * @param quality The Quality for which to find the color code + * @return Color Code for given Quality + */ public static String getQualityColor(int quality) { String color; if (quality > 8) { @@ -238,4 +417,74 @@ public class BrewLore { } return P.p.color(color); } + + public enum Type { + CUSTOM("§t", 0), + SPACE("§u", 1), + + INGR("§v", 2), + COOK("§w", 3), + DISTILL("§x", 4), + AGE("§y", 5), + WOOD("§z", 6); + + public final String id; + public final int ordering; + + /** + * @param id Identifier as Prefix of the Loreline + * @param ordering Ordering of the Brew Lore + */ + Type(String id, int ordering) { + this.id = id; + this.ordering = ordering; + } + + /** + * Find this type in the Lore + * + * @param lore The lore to search in + * @return index of this type in the lore, -1 if not found + */ + public int findInLore(List lore) { + return BUtil.indexOfStart(lore, id); + } + + /** + * Is this type after the other in lore + * + * @param other the other type + * @return true if this type should be after the other type in lore + */ + public boolean isAfter(Type other) { + return other.ordering <= ordering; + } + + /** + * Get the Type of the given line of Lore + */ + @Nullable + public static Type get(String loreLine) { + if (loreLine.length() >= 2) { + loreLine = loreLine.substring(0, 2); + return getById(loreLine); + } else { + return null; + } + } + + /** + * Get the Type of the given Identifier, prefix of a line of lore + */ + @Nullable + public static Type getById(String id) { + for (Type t : values()) { + if (t.id.equals(id)) { + return t; + } + } + return null; + } + + } } diff --git a/src/com/dre/brewery/utility/Tuple.java b/src/com/dre/brewery/utility/Tuple.java new file mode 100644 index 0000000..2d50c92 --- /dev/null +++ b/src/com/dre/brewery/utility/Tuple.java @@ -0,0 +1,80 @@ +/* + * Copyright 2011 Tyler Blair. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and contributors and should not be interpreted as representing official policies, + * either expressed or implied, of anybody else. + */ +package com.dre.brewery.utility; + +public class Tuple { + + /** + * The first value in the tuple + */ + private final X x; + + /** + * The second value in the tuple + */ + private final Y y; + + public Tuple(X x, Y y) { + this.x = x; + this.y = y; + } + + /** + * Gets the first value in the tuple + * + * @return + */ + public X first() { + return x; + } + + /** + * Gets the second value in the tuple + * + * @return + */ + public Y second() { + return y; + } + + @Override + public boolean equals(Object object) { + if (!(object instanceof Tuple)) { + return false; + } + + Tuple tuple = (Tuple) object; + return tuple.x == x && tuple.y == y; + } + + @Override + public int hashCode() { + return x.hashCode() ^ y.hashCode(); + } + +}