diff --git a/src/main/java/net/Indyuce/mmocore/experience/source/CraftItemExperienceSource.java b/src/main/java/net/Indyuce/mmocore/experience/source/CraftItemExperienceSource.java index e3f0322f..0b9b1bc7 100644 --- a/src/main/java/net/Indyuce/mmocore/experience/source/CraftItemExperienceSource.java +++ b/src/main/java/net/Indyuce/mmocore/experience/source/CraftItemExperienceSource.java @@ -1,19 +1,23 @@ package net.Indyuce.mmocore.experience.source; import io.lumine.mythic.lib.api.MMOLineConfig; +import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.experience.provider.ExperienceDispenser; import net.Indyuce.mmocore.experience.source.type.SpecificExperienceSource; import net.Indyuce.mmocore.manager.profession.ExperienceSourceManager; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; -import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.CraftItemEvent; import org.bukkit.event.inventory.InventoryAction; import org.bukkit.inventory.ItemStack; +import javax.annotation.Nullable; + public class CraftItemExperienceSource extends SpecificExperienceSource { public final Material material; @@ -33,9 +37,42 @@ public class CraftItemExperienceSource extends SpecificExperienceSource { + + // First check + int newAmount = getAmount(event.getInventory().getMatrix()[index]); + if (newAmount >= oldAmount) + return; + + // Deduce amount crafted + int amountCrafted = (event.getClick().isShiftClick() ? oldAmount - newAmount : 1) * itemsCraftedPerRecipe; + for (CraftItemExperienceSource source : getSources()) + if (source.matches(data, resultType)) + source.giveExperience(data, amountCrafted, event.getInventory().getLocation()); + }); } }; } @@ -45,30 +82,23 @@ public class CraftItemExperienceSource extends SpecificExperienceSource - * The idea is to find the item with the lowest count which is basically - * the amount of items that are crafted. Minecraft uses the same calculation - * - * @return Amount of items crafted - */ - private final int getAmountCrafted(CraftItemEvent event) { - ItemStack craftedItem = event.getInventory().getResult(); //Get result of recipe - ClickType clickType = event.getClick(); + private int getAmount(@Nullable ItemStack item) { + return item == null || item.getType() == Material.AIR ? 0 : item.getAmount(); + } - // No shift click - if (!clickType.isShiftClick()) - return craftedItem.getAmount(); + private int getLowerAmountIngredientIndex(ItemStack[] matrix) { + int lower = Integer.MAX_VALUE; + int index = -1; - // Find lowest amount of all ingredients - int lowerAmount = craftedItem.getMaxStackSize() + 1000; //Set lower at recipe result max stack size + 1000 (or just highter max stacksize of reciped item) - for (ItemStack actualItem : event.getInventory().getContents()) //For each item in crafting inventory - if (!actualItem.getType().isAir() && lowerAmount > actualItem.getAmount() && !actualItem.getType().equals(craftedItem.getType())) //if slot is not air && lowerAmount is highter than this slot amount && it's not the recipe amount - lowerAmount = actualItem.getAmount(); //Set new lower amount + for (int i = 0; i < 9; i++) { + ItemStack checked = matrix[i]; + if (checked != null && checked.getType() != Material.AIR && checked.getAmount() > 0 && checked.getAmount() < lower) { + lower = checked.getAmount(); + index = i; + } + } - //Calculate the final amount : lowerAmount * craftedItem.getAmount - return lowerAmount * craftedItem.getAmount(); + Validate.isTrue(index != -1, "No item in matrix"); + return index; } }