Skip to content

Commit

Permalink
Fix issue when unstackable items flood challenge description (#135)
Browse files Browse the repository at this point in the history
  • Loading branch information
BONNe committed Jun 16, 2019
1 parent 1a70ee3 commit a7f9e01
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 62 deletions.
13 changes: 7 additions & 6 deletions src/main/java/world/bentobox/challenges/panel/CommonGUI.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package world.bentobox.challenges.panel;


import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.enchantments.Enchantment;
Expand All @@ -20,8 +19,8 @@
import world.bentobox.challenges.ChallengesManager;
import world.bentobox.challenges.database.object.Challenge;
import world.bentobox.challenges.database.object.ChallengeLevel;
import world.bentobox.challenges.utils.GuiUtils;
import world.bentobox.challenges.utils.LevelStatus;
import world.bentobox.challenges.utils.Utils;


/**
Expand Down Expand Up @@ -631,8 +630,7 @@ private List<String> getChallengeRequiredItems(Challenge challenge)
{
result.add(this.user.getTranslation("challenges.gui.challenge-description.required-items"));

for (ItemStack itemStack : challenge.getRequiredItems())
{
Utils.groupEqualItems(challenge.getRequiredItems()).forEach(itemStack -> {
result.add(this.user.getTranslation("challenges.gui.descriptions.item",
"[item]", itemStack.getType().name(),
"[count]", Integer.toString(itemStack.getAmount())));
Expand All @@ -646,9 +644,12 @@ private List<String> getChallengeRequiredItems(Challenge challenge)
for (Map.Entry<Enchantment, Integer> entry : itemStack.getEnchantments().entrySet())
{
result.add(this.user.getTranslation("challenges.gui.descriptions.item-enchant",
"[enchant]", entry.getKey().getKey().getKey(), "[level]", Integer.toString(entry.getValue())));
"[enchant]",
entry.getKey().getKey().getKey(),
"[level]",
Integer.toString(entry.getValue())));
}
}
});
}

if (challenge.getChallengeType().equals(Challenge.ChallengeType.ISLAND) &&
Expand Down
65 changes: 9 additions & 56 deletions src/main/java/world/bentobox/challenges/tasks/TryToComplete.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import world.bentobox.challenges.database.object.Challenge;
import world.bentobox.challenges.database.object.Challenge.ChallengeType;
import world.bentobox.challenges.database.object.ChallengeLevel;
import world.bentobox.challenges.utils.Utils;


/**
Expand Down Expand Up @@ -703,48 +704,19 @@ private void showError(final String cmd)
private ChallengeResult checkInventory(int maxTimes)
{
// Run through inventory
List<ItemStack> requiredItems = new ArrayList<>(this.challenge.getRequiredItems().size());
List<ItemStack> requiredItems;

// Players in creative game mode has got all items. No point to search for them.
if (this.user.getPlayer().getGameMode() != GameMode.CREATIVE)
{
// Group all equal items in singe stack, as otherwise it will be too complicated to check if all
// items are in players inventory.
for (ItemStack item : this.challenge.getRequiredItems())
{
boolean isUnique = true;

int i = 0;
final int requiredSize = requiredItems.size();

while (i < requiredSize && isUnique)
{
ItemStack required = requiredItems.get(i);

// Merge items which meta can be ignored or is similar to item in required list.
if (this.canIgnoreMeta(item.getType()) && item.getType().equals(required.getType()) ||
required.isSimilar(item))
{
required.setAmount(required.getAmount() + item.getAmount());
isUnique = false;
}

i++;
}

if (isUnique)
{
// The same issue as in other places. Clone prevents from changing original item.
requiredItems.add(item.clone());
}
}
requiredItems = Utils.groupEqualItems(this.challenge.getRequiredItems());

// Check if all required items are in players inventory.
for (ItemStack required : requiredItems)
{
int numInInventory;

if (this.canIgnoreMeta(required.getType()))
if (Utils.canIgnoreMeta(required.getType()))
{
numInInventory =
Arrays.stream(this.user.getInventory().getContents()).
Expand Down Expand Up @@ -774,6 +746,10 @@ private ChallengeResult checkInventory(int maxTimes)
maxTimes = Math.min(maxTimes, numInInventory / required.getAmount());
}
}
else
{
requiredItems = Collections.emptyList();
}

// Return the result
return new ChallengeResult().
Expand All @@ -798,7 +774,7 @@ Map<ItemStack, Integer> removeItems(List<ItemStack> requiredItemList, int factor

List<ItemStack> itemsInInventory;

if (this.canIgnoreMeta(required.getType()))
if (Utils.canIgnoreMeta(required.getType()))
{
// Use collecting method that ignores item meta.
itemsInInventory = Arrays.stream(user.getInventory().getContents()).
Expand Down Expand Up @@ -849,29 +825,6 @@ Map<ItemStack, Integer> removeItems(List<ItemStack> requiredItemList, int factor
}


/**
* This method returns if meta data of these items can be ignored. It means, that items will be searched
* and merged by they type instead of using ItemStack#isSimilar(ItemStack) method.
*
* This limits custom Challenges a lot. It comes from ASkyBlock times, and that is the reason why it is
* still here. It would be a great Challenge that could be completed by collecting 4 books, that cannot
* be crafted. Unfortunately, this prevents it.
* The same happens with firework rockets, enchanted books and filled maps.
* In future it should be able to specify, which items meta should be ignored when adding item in required
* item list.
*
* @param material Material that need to be checked.
* @return True if material meta can be ignored, otherwise false.
*/
private boolean canIgnoreMeta(Material material)
{
return material.equals(Material.FIREWORK_ROCKET) ||
material.equals(Material.ENCHANTED_BOOK) ||
material.equals(Material.WRITTEN_BOOK) ||
material.equals(Material.FILLED_MAP);
}


// ---------------------------------------------------------------------
// Section: Island Challenge
// ---------------------------------------------------------------------
Expand Down
81 changes: 81 additions & 0 deletions src/main/java/world/bentobox/challenges/utils/Utils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package world.bentobox.challenges.utils;


import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;


/**
* Util methods used in different situations.
*/
public class Utils
{
/**
* This method groups input items in single itemstack with correct amount and returns it.
* Allows to remove duplicate items from list.
* @param requiredItems Input item list
* @return List that contains unique items that cannot be grouped.
*/
public static List<ItemStack> groupEqualItems(List<ItemStack> requiredItems)
{
List<ItemStack> returnItems = new ArrayList<>(requiredItems.size());

// Group all equal items in singe stack, as otherwise it will be too complicated to check if all
// items are in players inventory.
for (ItemStack item : requiredItems)
{
boolean isUnique = true;

int i = 0;
final int requiredSize = returnItems.size();

while (i < requiredSize && isUnique)
{
ItemStack required = returnItems.get(i);

// Merge items which meta can be ignored or is similar to item in required list.
if (Utils.canIgnoreMeta(item.getType()) && item.getType().equals(required.getType()) ||
required.isSimilar(item))
{
required.setAmount(required.getAmount() + item.getAmount());
isUnique = false;
}

i++;
}

if (isUnique)
{
// The same issue as in other places. Clone prevents from changing original item.
returnItems.add(item.clone());
}
}

return returnItems;
}


/**
* This method returns if meta data of these items can be ignored. It means, that items will be searched
* and merged by they type instead of using ItemStack#isSimilar(ItemStack) method.
*
* This limits custom Challenges a lot. It comes from ASkyBlock times, and that is the reason why it is
* still here. It would be a great Challenge that could be completed by collecting 4 books, that cannot
* be crafted. Unfortunately, this prevents it.
* The same happens with firework rockets, enchanted books and filled maps.
* In future it should be able to specify, which items meta should be ignored when adding item in required
* item list.
*
* @param material Material that need to be checked.
* @return True if material meta can be ignored, otherwise false.
*/
public static boolean canIgnoreMeta(Material material)
{
return material.equals(Material.FIREWORK_ROCKET) ||
material.equals(Material.ENCHANTED_BOOK) ||
material.equals(Material.WRITTEN_BOOK) ||
material.equals(Material.FILLED_MAP);
}
}

0 comments on commit a7f9e01

Please sign in to comment.