diff --git a/gradle.properties b/gradle.properties index b747e3f..d545ee8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ # This is required to provide enough memory for the Minecraft decompilation process. org.gradle.jvmargs=-Xmx4G name=RockyTweaks -mod_version=0.6.1-SNAPSHOT +mod_version=0.7.0 mc_version=1.12.2 mcp_mappings=20171003-1.12 forge_version=14.23.5.2855 diff --git a/src/main/java/rocks/gameonthe/rockytweaks/crafttweaker/merchant/MerchantCommand.java b/src/main/java/rocks/gameonthe/rockytweaks/crafttweaker/merchant/MerchantCommand.java index a0c845b..714dc2a 100644 --- a/src/main/java/rocks/gameonthe/rockytweaks/crafttweaker/merchant/MerchantCommand.java +++ b/src/main/java/rocks/gameonthe/rockytweaks/crafttweaker/merchant/MerchantCommand.java @@ -4,18 +4,24 @@ import com.google.common.collect.Lists; import crafttweaker.CraftTweakerAPI; import crafttweaker.mc1120.commands.CraftTweakerCommand; + +import java.lang.reflect.Field; import java.util.List; import javax.annotation.Nullable; import net.minecraft.command.ICommandSender; +import net.minecraft.entity.passive.EntityVillager; import net.minecraft.server.MinecraftServer; import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.TextComponentString; +import net.minecraft.world.storage.MapDecoration; import net.minecraftforge.fml.common.registry.VillagerRegistry; import org.apache.commons.lang3.text.StrBuilder; +import static rocks.gameonthe.rockytweaks.crafttweaker.merchant.VillagerHelper.TREASURE_MAP_TRADE; + public class MerchantCommand extends CraftTweakerCommand { - private final List arguments = Lists.newArrayList("professions", "careers"); // TODO: Add "trades" + private final List arguments = Lists.newArrayList("professions", "careers", "trades"); public MerchantCommand() { super("merchant"); @@ -54,11 +60,11 @@ public void executeCommand(MinecraftServer server, ICommandSender sender, String if (profession == null) { VillagerHelper.getVillagerProfessions().forEach(p -> { builder.append(p.getRegistryName()).appendNewLine(); - VillagerHelper.getVillagerCareers(p).forEach(c -> builder.append(" - ").append(c.getName()).appendNewLine()); + VillagerHelper.getProfessionCareers(p).forEach(c -> builder.append(" - ").append(c.getName()).appendNewLine()); }); } else { builder.append(profession.getRegistryName()).appendNewLine(); - VillagerHelper.getVillagerCareers(profession).forEach(c -> builder.append(" - ").append(c.getName()).appendNewLine()); + VillagerHelper.getProfessionCareers(profession).forEach(c -> builder.append(" - ").append(c.getName()).appendNewLine()); } CraftTweakerAPI.logCommand(builder.build()); sender.sendMessage(new TextComponentString("List generated; see crafttweaker.log in your minecraft dir.")); @@ -79,18 +85,115 @@ public void executeCommand(MinecraftServer server, ICommandSender sender, String sender.sendMessage(new TextComponentString("Invalid career.")); } } - if (profession == null) { - VillagerHelper.getVillagerProfessions().forEach(p -> { - VillagerHelper.getVillagerCareers(p).forEach(c -> { - // TODO: Get the Merchant Recipes ¯\_(ツ)_/¯ + } + if (profession == null) { + VillagerHelper.getVillagerProfessions().forEach(p -> { + builder.append(p.getRegistryName()).appendNewLine(); + VillagerHelper.getProfessionCareers(p).forEach(c -> { + builder.append(" - ").append(c.getName()).appendNewLine(); + + int idx = 1; + for (List levelTrades : VillagerHelper.getCareerTrades(c)) { + if (!levelTrades.isEmpty()) builder.append(" - Level ").append(idx++).appendNewLine(); + + levelTrades.forEach(tradeItem -> { + builder.append(" * ").append(buildTradeString(tradeItem)).appendNewLine(); + }); + } + }); + }); + } else if (career == null) { + builder.append(profession.getRegistryName()).appendNewLine(); + VillagerHelper.getProfessionCareers(profession).forEach(c -> { + builder.append(" - ").append(c.getName()).appendNewLine(); + + int idx = 1; + for (List levelTrades : VillagerHelper.getCareerTrades(c)) { + if (!levelTrades.isEmpty()) builder.append(" - Level ").append(idx++).appendNewLine(); + + levelTrades.forEach(tradeItem -> { + builder.append(" * ").append(buildTradeString(tradeItem)).appendNewLine(); }); + } + }); + } else { + builder.append(profession.getRegistryName()).appendNewLine(); + builder.append(" - ").append(career.getName()).appendNewLine(); + + int idx = 1; + for (List levelTrades : VillagerHelper.getCareerTrades(career)) { + if (!levelTrades.isEmpty()) builder.append(" - Level ").append(idx++).appendNewLine(); + + levelTrades.forEach(tradeItem -> { + builder.append(" * ").append(buildTradeString(tradeItem)).appendNewLine(); }); } } CraftTweakerAPI.logCommand(builder.build()); + sender.sendMessage(new TextComponentString("List generated; see crafttweaker.log in your minecraft dir.")); } else { sender.sendMessage(new TextComponentString("I can't even... (╯°□°)╯︵ ┻━┻")); } } } + + private String buildTradeString(EntityVillager.ITradeList tradeItem) { + if(tradeItem instanceof EntityVillager.EmeraldForItems) { + EntityVillager.EmeraldForItems specialized = (EntityVillager.EmeraldForItems) tradeItem; + return "[EmeraldForItems] buy: " + specialized.buyingItem.getRegistryName().toString() + + ", emeralds: " + specialized.price.getFirst() + "/" + specialized.price.getSecond(); + } + + if(tradeItem instanceof MerchantTradeItem) { + MerchantTradeItem specialized = (MerchantTradeItem) tradeItem; + return "[MerchantTradeItem] chance: " + specialized.chance + + ", buy1: " + specialized.recipe.getItemToBuy().serializeNBT().toString() + + ", buy2: " + (specialized.recipe.hasSecondItemToBuy()?specialized.recipe.getSecondItemToBuy().serializeNBT().toString():"null") + + ", sell: " + specialized.recipe.getItemToSell().serializeNBT().toString(); + } + + if(tradeItem instanceof EntityVillager.ItemAndEmeraldToItem) { + EntityVillager.ItemAndEmeraldToItem specialized = (EntityVillager.ItemAndEmeraldToItem) tradeItem; + return "[ItemAndEmeraldToItem] buy: " + specialized.buyingItemStack.serializeNBT().toString() + + ", buyEmeralds: " + specialized.buyingPriceInfo.getFirst() + "/" + specialized.buyingPriceInfo.getSecond() + + ", sell: " + specialized.sellingItemstack.serializeNBT().toString() + + ", sellEmeralds: " + specialized.sellingPriceInfo.getFirst() + "/" + specialized.sellingPriceInfo.getSecond(); + } + + if(tradeItem instanceof EntityVillager.ListEnchantedBookForEmeralds) { + return "[ListEnchantedBookForEmeralds] fixedBuy: book + emeralds" + + ", fixedSell: enchanted_book + enchantment?"; + } + + if(tradeItem instanceof EntityVillager.ListEnchantedItemForEmeralds) { + EntityVillager.ListEnchantedItemForEmeralds specialized = (EntityVillager.ListEnchantedItemForEmeralds) tradeItem; + return "[ListEnchantedItemForEmeralds] emeralds: " + specialized.priceInfo.getFirst() + "/" + specialized.priceInfo.getSecond() + + ", sell: " + specialized.enchantedItemStack.serializeNBT().toString() + " + enchantment?"; + } + + if(tradeItem instanceof EntityVillager.ListItemForEmeralds) { + EntityVillager.ListItemForEmeralds specialized = (EntityVillager.ListItemForEmeralds) tradeItem; + return "[ListItemForEmeralds] buy: " + specialized.itemToBuy.serializeNBT().toString() + + ", emeralds: " + specialized.priceInfo.getFirst() + "/" + specialized.priceInfo.getSecond(); + } + + if(TREASURE_MAP_TRADE.isInstance(tradeItem)) { + try { + Field value = tradeItem.getClass().getDeclaredField("value"); + value.setAccessible(true); + EntityVillager.PriceInfo price = (EntityVillager.PriceInfo) value.get(tradeItem); + + Field destinationType = tradeItem.getClass().getDeclaredField("destinationType"); + destinationType.setAccessible(true); + MapDecoration.Type mapType = (MapDecoration.Type) destinationType.get(tradeItem); + return "[TreasureMapForEmeralds] emeralds: " + price.getFirst() + "/" + price.getSecond() + + ", fixedSell: minecraft:compass" + + ", buyMapFilled: " + mapType.name(); + } catch (Exception e) { + return "[TreasureMapForEmeralds] Malformed???"; + } + } + + return "[Unknown Type] " + tradeItem.getClass().getCanonicalName(); + } } diff --git a/src/main/java/rocks/gameonthe/rockytweaks/crafttweaker/merchant/MerchantTrade.java b/src/main/java/rocks/gameonthe/rockytweaks/crafttweaker/merchant/MerchantTrade.java index c97b331..50fb6b0 100644 --- a/src/main/java/rocks/gameonthe/rockytweaks/crafttweaker/merchant/MerchantTrade.java +++ b/src/main/java/rocks/gameonthe/rockytweaks/crafttweaker/merchant/MerchantTrade.java @@ -1,16 +1,27 @@ package rocks.gameonthe.rockytweaks.crafttweaker.merchant; +import com.blamejared.mtlib.helpers.LogHelper; import net.minecraft.entity.passive.EntityVillager; import net.minecraft.item.ItemStack; +import net.minecraft.util.math.MathHelper; import net.minecraft.village.MerchantRecipe; import net.minecraftforge.fml.common.registry.VillagerRegistry; + +import java.util.Random; + public class MerchantTrade { private VillagerRegistry.VillagerProfession profession; private VillagerRegistry.VillagerCareer career; - private MerchantRecipe recipe; + public final MerchantRecipe recipe; private int level; + private float chance; + + public MerchantTrade(VillagerRegistry.VillagerProfession profession, VillagerRegistry.VillagerCareer career, ItemStack buy1, ItemStack buy2, + ItemStack sell, int level, float chance) { + this(profession, career, new MerchantRecipe(buy1, buy2, sell), level, chance); + } public MerchantTrade(VillagerRegistry.VillagerProfession profession, VillagerRegistry.VillagerCareer career, ItemStack buy1, ItemStack buy2, ItemStack sell, int level) { @@ -22,18 +33,15 @@ public MerchantTrade(VillagerRegistry.VillagerProfession profession, VillagerReg this.career = career; this.recipe = recipe; this.level = level; + this.chance = 100.0f; } - public VillagerRegistry.VillagerProfession getProfession() { - return profession; - } - - public VillagerRegistry.VillagerCareer getCareer() { - return career; - } - - public MerchantRecipe getRecipe() { - return recipe; + public MerchantTrade(VillagerRegistry.VillagerProfession profession, VillagerRegistry.VillagerCareer career, MerchantRecipe recipe, int level, float chance) { + this.profession = profession; + this.career = career; + this.recipe = recipe; + this.level = level; + this.chance = chance; } public int getLevel() { @@ -41,7 +49,15 @@ public int getLevel() { } public void register() { - profession.getCareer(VillagerHelper.getVillagerCareers(profession).indexOf(career)) - .addTrade(getLevel(), (EntityVillager.ITradeList) (merchant, recipeList, random) -> recipeList.add(getRecipe())); + try { + VillagerHelper.getCareerRef(VillagerHelper.getProfessionName(profession).toString(), career.getName()) + .addTrade(getLevel(), toTradeItem()); + } catch (NullPointerException e) { + LogHelper.logError(String.format("Got invalid career: %s", e.getMessage())); + } + } + + private EntityVillager.ITradeList toTradeItem() { + return (EntityVillager.ITradeList) new MerchantTradeItem(this.recipe, this.chance); } } diff --git a/src/main/java/rocks/gameonthe/rockytweaks/crafttweaker/merchant/MerchantTradeHandler.java b/src/main/java/rocks/gameonthe/rockytweaks/crafttweaker/merchant/MerchantTradeHandler.java index b9ea48d..3cd9143 100644 --- a/src/main/java/rocks/gameonthe/rockytweaks/crafttweaker/merchant/MerchantTradeHandler.java +++ b/src/main/java/rocks/gameonthe/rockytweaks/crafttweaker/merchant/MerchantTradeHandler.java @@ -1,6 +1,7 @@ package rocks.gameonthe.rockytweaks.crafttweaker.merchant; import static com.blamejared.mtlib.helpers.InputHelper.toStack; +import static rocks.gameonthe.rockytweaks.crafttweaker.merchant.VillagerHelper.TREASURE_MAP_TRADE; import com.blamejared.mtlib.helpers.LogHelper; import com.blamejared.mtlib.utils.BaseListAddition; @@ -9,7 +10,15 @@ import crafttweaker.CraftTweakerAPI; import crafttweaker.annotations.ZenRegister; import crafttweaker.api.item.IItemStack; + +import java.util.ArrayList; import java.util.List; +import java.util.Objects; +import java.util.Optional; + +import net.minecraft.entity.passive.EntityVillager; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; import net.minecraftforge.fml.common.registry.VillagerRegistry; import stanhebben.zenscript.annotations.ZenClass; import stanhebben.zenscript.annotations.ZenMethod; @@ -36,11 +45,175 @@ public static void addTrade(String profession, String career, IItemStack buy1, I )); } + @ZenMethod + public static void addTradeChance(String profession, String career, IItemStack buy1, IItemStack buy2, IItemStack sell, int level, float chance) { + Preconditions.checkNotNull(profession); + Preconditions.checkArgument(VillagerHelper.getProfession(profession).isPresent()); + VillagerRegistry.VillagerProfession p1 = VillagerHelper.getProfession(profession).get(); + Preconditions.checkNotNull(career); + Preconditions.checkArgument(VillagerHelper.getCareer(p1, career).isPresent()); + Preconditions.checkNotNull(buy1); + Preconditions.checkNotNull(sell); + Preconditions.checkArgument(level > 0); + Preconditions.checkArgument(chance > 0.0f); + Preconditions.checkArgument(chance <= 100.0f); + CraftTweakerAPI.apply(new MerchantTradeHandler.Add( + new MerchantTrade(p1, VillagerHelper.getCareer(p1, career).get(), toStack(buy1), toStack(buy2), toStack(sell), level, chance) + )); + } + + @ZenMethod + public static void addTradeChance(String profession, String career, IItemStack buy1, IItemStack sell, int level, float chance) { + addTradeChance(profession, career, buy1, null, sell, level, chance); + } + @ZenMethod public static void addTrade(String profession, String career, IItemStack buy1, IItemStack sell, int level) { addTrade(profession, career, buy1, null, sell, level); } + @ZenMethod + public static void clearTrades(String profession, String career) { + Preconditions.checkNotNull(profession); + + Optional professionOption = VillagerHelper.getProfession(profession); + Preconditions.checkArgument(professionOption.isPresent()); + VillagerRegistry.VillagerProfession professionObject = professionOption.get(); + + Preconditions.checkArgument(VillagerHelper.getCareer(professionObject, career).isPresent()); + Optional careerOption = VillagerHelper.getCareer(professionObject, career); + Preconditions.checkArgument(careerOption.isPresent()); + VillagerRegistry.VillagerCareer careerObject = careerOption.get(); + + List> allTrades = VillagerHelper.getCareerTrades(careerObject); + + if (allTrades != null) { + for (List tradeLevel : allTrades) { + if (tradeLevel != null) { + tradeLevel.clear(); + } + } + } + } + + @ZenMethod + public static void removeTradeItem(String profession, String career, IItemStack target ) { + Preconditions.checkNotNull(profession); + + Optional professionOption = VillagerHelper.getProfession(profession); + Preconditions.checkArgument(professionOption.isPresent()); + VillagerRegistry.VillagerProfession professionObject = professionOption.get(); + + Preconditions.checkArgument(VillagerHelper.getCareer(professionObject, career).isPresent()); + Optional careerOption = VillagerHelper.getCareer(professionObject, career); + Preconditions.checkArgument(careerOption.isPresent()); + VillagerRegistry.VillagerCareer careerObject = careerOption.get(); + + List> allTrades = VillagerHelper.getCareerTrades(careerObject); + + Preconditions.checkNotNull(target); + + String targetId = target.getDefinition().getId(); + if (allTrades != null) { + for (List tradeLevel : allTrades) { + if (tradeLevel != null) { + + List removeList = new ArrayList(); + + for (EntityVillager.ITradeList trade : tradeLevel) { + + // Emerald for Items + if (trade instanceof EntityVillager.EmeraldForItems) { + if ( ((EntityVillager.EmeraldForItems) trade).buyingItem.equals(target) ) { + removeList.add(trade); + } + + if ("minecraft:emerald".equals(targetId)) removeList.add(trade); + } + + // Our Trade Item, so we can remove it again + if (trade instanceof MerchantTradeItem) { + if ( compareStack(target, ((MerchantTradeItem) trade).recipe.getItemToBuy()) ) { + removeList.add(trade); + } + if ( compareStack(target, ((MerchantTradeItem) trade).recipe.getSecondItemToBuy()) ) { + removeList.add(trade); + } + if ( compareStack(target, ((MerchantTradeItem) trade).recipe.getItemToSell()) ) { + removeList.add(trade); + } + } + + // Item and Emerald To Item + if (trade instanceof EntityVillager.ItemAndEmeraldToItem) { + if ( compareStack(target, ((EntityVillager.ItemAndEmeraldToItem)trade).buyingItemStack) ) { + removeList.add(trade); + } + if ( compareStack(target, ((EntityVillager.ItemAndEmeraldToItem)trade).sellingItemstack) ) { + removeList.add(trade); + } + + if ("minecraft:emerald".equals(targetId)) removeList.add(trade); + } + + // List Enchanted Book For Emeralds + if (trade instanceof EntityVillager.ListEnchantedBookForEmeralds) { + if ("minecraft:book".equals(targetId) + || "minecraft:emerald".equals(targetId) + || "minecraft:enchanted_book".equals(targetId)) { + removeList.add(trade); + } + } + + // List Enchanted Item For Emeralds + if (trade instanceof EntityVillager.ListEnchantedItemForEmeralds) { + if ( compareStack(target, ((EntityVillager.ListEnchantedItemForEmeralds)trade).enchantedItemStack) ) { + removeList.add(trade); + } + + if ("minecraft:emerald".equals(targetId)) removeList.add(trade); + } + + // List Item For Emeralds + if (trade instanceof EntityVillager.ListItemForEmeralds) { + + if ( compareStack(target, ((EntityVillager.ListItemForEmeralds)trade).itemToBuy) ) { + removeList.add(trade); + } + + if ("minecraft:emerald".equals(targetId)) removeList.add(trade); + } + + if(TREASURE_MAP_TRADE.isInstance(trade)) { + if ("minecraft:map_filled".equals(targetId) + || "minecraft:emerald".equals(targetId) + || "minecraft:compass".equals(targetId)) { + removeList.add(trade); + } + } + } + + tradeLevel.removeAll(removeList); + } + } + } + } + + private static boolean compareStack(IItemStack itemStack, Object other) { + if (other instanceof Item) { + Item otherItem = (Item) other; + return itemStack.getDefinition().getId().equals(otherItem.getRegistryName().toString()); + } + + if (other instanceof ItemStack) { + ItemStack otherStack = (ItemStack) other; + return itemStack.getMetadata() == otherStack.getMetadata() + && itemStack.getDefinition().getId().equals(otherStack.getItem().getRegistryName().toString()); + } + + return false; + } + private static class Add extends BaseListAddition { public Add(MerchantTrade recipe) { @@ -57,7 +230,7 @@ public void apply() { this.successful.add(trade); trade.register(); } else { - LogHelper.logError(String.format("Error adding %s Recipe for %s", this.name, this.getRecipeInfo(trade))); + LogHelper.logError(String.format("Error adding %s Recipe for %s", this.name, this.getRecipeInfo())); } } else { LogHelper.logError(String.format("Error adding %s Recipe: null object", this.name)); @@ -68,7 +241,7 @@ public void apply() { @Override public String getRecipeInfo(MerchantTrade trade) { - return LogHelper.getStackDescription(trade.getRecipe()); + return LogHelper.getStackDescription(trade.recipe); } } diff --git a/src/main/java/rocks/gameonthe/rockytweaks/crafttweaker/merchant/MerchantTradeItem.java b/src/main/java/rocks/gameonthe/rockytweaks/crafttweaker/merchant/MerchantTradeItem.java new file mode 100644 index 0000000..df797ee --- /dev/null +++ b/src/main/java/rocks/gameonthe/rockytweaks/crafttweaker/merchant/MerchantTradeItem.java @@ -0,0 +1,43 @@ +package rocks.gameonthe.rockytweaks.crafttweaker.merchant; + +import net.minecraft.entity.IMerchant; +import net.minecraft.entity.passive.EntityVillager; +import net.minecraft.util.math.MathHelper; +import net.minecraft.village.MerchantRecipe; +import net.minecraft.village.MerchantRecipeList; + +import java.util.Random; + +public class MerchantTradeItem implements EntityVillager.ITradeList { + + public final MerchantRecipe recipe; + public final float chance; + + public MerchantTradeItem(MerchantRecipe recipe, float chance) { + this.recipe = recipe; + this.chance = chance; + } + + public MerchantRecipe getRecipe(Random random) { + if (random == null) { + return recipe; + } else { + float randomValue = MathHelper.nextFloat(random, 0.0f, 100.0f); + if (randomValue < this.chance) { + return recipe; + } else { + return null; + } + } + } + + @Override + public void addMerchantRecipe(IMerchant merchant, MerchantRecipeList recipeList, Random random) { + if(recipe != null) { + MerchantRecipe recipeChance = getRecipe(random); + if (recipeChance != null) { + recipeList.add(recipeChance); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/rocks/gameonthe/rockytweaks/crafttweaker/merchant/VillagerHelper.java b/src/main/java/rocks/gameonthe/rockytweaks/crafttweaker/merchant/VillagerHelper.java index 690fada..505516d 100644 --- a/src/main/java/rocks/gameonthe/rockytweaks/crafttweaker/merchant/VillagerHelper.java +++ b/src/main/java/rocks/gameonthe/rockytweaks/crafttweaker/merchant/VillagerHelper.java @@ -3,9 +3,11 @@ import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; -import java.util.Collection; -import java.util.List; -import java.util.Optional; +import java.lang.reflect.Field; +import java.util.*; + +import net.minecraft.entity.passive.EntityVillager; +import net.minecraft.util.ResourceLocation; import net.minecraft.village.MerchantRecipe; import net.minecraftforge.fml.common.registry.ForgeRegistries; import net.minecraftforge.fml.common.registry.VillagerRegistry; @@ -16,21 +18,14 @@ public final class VillagerHelper { private VillagerHelper(){ } + public static Class TREASURE_MAP_TRADE = Arrays.stream(EntityVillager.class.getDeclaredClasses()).filter(clazz -> + "net.minecraft.entity.passive.EntityVillager.TreasureMapForEmeralds".equals(clazz.getCanonicalName()) + ).findFirst().get(); + public static Collection getVillagerProfessions() { return ForgeRegistries.VILLAGER_PROFESSIONS.getValuesCollection(); } - public static List getVillagerCareers(VillagerRegistry.VillagerProfession profession) { - List careers = Lists.newArrayList(profession.getCareer(0)); - int i = 0; - do { - i++; - careers.add(profession.getCareer(i)); - } while (!careers.get(0).equals(careers.get(i))); - careers.remove(profession.getCareer(i)); - return careers; - } - public static Optional getProfession(String profession) { for (VillagerRegistry.VillagerProfession p : getVillagerProfessions()) { if (p.getRegistryName() != null @@ -43,7 +38,50 @@ public static Optional getProfession(String } public static Optional getCareer(VillagerRegistry.VillagerProfession profession, String career) { - return getVillagerCareers(profession).stream().filter(c -> c.getName().equalsIgnoreCase(career)).findAny(); + return getProfessionCareers(profession).stream().filter(c -> c.getName().equalsIgnoreCase(career)).findAny(); + } + + public static ResourceLocation getProfessionName(VillagerRegistry.VillagerProfession profession) { + try { + Field namefield = profession.getClass().getDeclaredField("name"); + namefield.setAccessible(true); + return (ResourceLocation) namefield.get(profession); + } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { + return new ResourceLocation(""); + } + } + + public static List getProfessionCareers(VillagerRegistry.VillagerProfession profession) { + try { + Field namefield = profession.getClass().getDeclaredField("careers"); + namefield.setAccessible(true); + return (List) namefield.get(profession); + } catch (Exception e) { + return new ArrayList<>(); + } + } + + public static List> getCareerTrades(VillagerRegistry.VillagerCareer career) { + try { + Field namefield = career.getClass().getDeclaredField("trades"); + namefield.setAccessible(true); + return (List>) namefield.get(career); + } catch (Exception e) { + return new ArrayList<>(); + } + } + + public static VillagerRegistry.VillagerCareer getCareerRef(String professionName, String careerName) { + Optional> firstEntry = getVillagerProfessions().stream().filter(profession -> { + String name = getProfessionName(profession).toString(); + return professionName.equals(name); + }).map(profession -> getProfessionCareers(profession).stream().filter(career -> careerName.equals(career.getName())).findFirst()).findFirst(); + if (firstEntry.isPresent()) { + Optional innerEntry = firstEntry.get(); + return innerEntry.orElse(null); + } else { + return null; + } } public static Multimap getMerchantRecipes(VillagerRegistry.VillagerCareer career) { diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info index c470f9a..8bab715 100644 --- a/src/main/resources/mcmod.info +++ b/src/main/resources/mcmod.info @@ -8,7 +8,7 @@ "url": "", "updateUrl": "", "authorList": [ - "Mohron" + "Mohron", "BIOCHEMIST" ], "credits": "", "logoFile": "",