package wayoftime.bloodmagic.loot; import java.util.ArrayList; import java.util.List; import javax.annotation.Nonnull; import com.google.gson.JsonObject; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.enchantment.Enchantments; import net.minecraft.inventory.Inventory; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.FurnaceRecipe; import net.minecraft.item.crafting.IRecipeType; import net.minecraft.loot.LootContext; import net.minecraft.loot.LootParameterSets; import net.minecraft.loot.LootParameters; import net.minecraft.loot.LootTable; import net.minecraft.loot.conditions.ILootCondition; import net.minecraft.util.ResourceLocation; import net.minecraftforge.common.loot.GlobalLootModifierSerializer; import net.minecraftforge.common.loot.LootModifier; import net.minecraftforge.fml.RegistryObject; import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; import wayoftime.bloodmagic.BloodMagic; import wayoftime.bloodmagic.anointment.AnointmentHolder; import wayoftime.bloodmagic.core.AnointmentRegistrar; public class GlobalLootModifier { public static final DeferredRegister> GLM = DeferredRegister.create(ForgeRegistries.LOOT_MODIFIER_SERIALIZERS, BloodMagic.MODID); public static final RegistryObject SILKTOUCH = GLM.register("silk_touch_bamboo", SilkTouchTestModifier.Serializer::new); public static final RegistryObject FORTUNE = GLM.register("fortune", FortuneModifier.Serializer::new); public static final RegistryObject LOOTING = GLM.register("looting", LootingModifier.Serializer::new); public static final RegistryObject SMELT = GLM.register("smelt", SmeltingModifier.Serializer::new); private static class SilkTouchTestModifier extends LootModifier { public SilkTouchTestModifier(ILootCondition[] conditionsIn) { super(conditionsIn); // System.out.println("Registering silk touch modifier"); } @Nonnull @Override public List doApply(List generatedLoot, LootContext context) { // System.out.println("Testing to see if we gotta check it~"); ItemStack ctxTool = context.get(LootParameters.TOOL); // return early if silk-touch is already applied (otherwise we'll get stuck in // an infinite loop). if (EnchantmentHelper.getEnchantments(ctxTool).containsKey(Enchantments.SILK_TOUCH)) return generatedLoot; AnointmentHolder holder = AnointmentHolder.fromItemStack(ctxTool); if (holder == null || holder.getAnointmentLevel(AnointmentRegistrar.ANOINTMENT_SILK_TOUCH.get()) <= 0) { return generatedLoot; } ItemStack fakeTool = ctxTool.copy(); fakeTool.addEnchantment(Enchantments.SILK_TOUCH, 1); LootContext.Builder builder = new LootContext.Builder(context); builder.withParameter(LootParameters.TOOL, fakeTool); LootContext ctx = builder.build(LootParameterSets.BLOCK); LootTable loottable = context.getWorld().getServer().getLootTableManager().getLootTableFromLocation(context.get(LootParameters.BLOCK_STATE).getBlock().getLootTable()); return loottable.generate(ctx); } private static class Serializer extends GlobalLootModifierSerializer { @Override public SilkTouchTestModifier read(ResourceLocation name, JsonObject json, ILootCondition[] conditionsIn) { return new SilkTouchTestModifier(conditionsIn); } @Override public JsonObject write(SilkTouchTestModifier instance) { return makeConditions(instance.conditions); } } } private static class FortuneModifier extends LootModifier { public FortuneModifier(ILootCondition[] conditionsIn) { super(conditionsIn); // System.out.println("Registering silk touch modifier"); } // List bufferList = new ArrayList(); @Nonnull @Override public List doApply(List generatedLoot, LootContext context) { ItemStack ctxTool = context.get(LootParameters.TOOL); // return early if silk-touch is already applied (otherwise we'll get stuck in // an infinite loop). if (ctxTool.getTag() != null && ctxTool.getTag().getBoolean("bloodmagic:checked_fortune")) { return generatedLoot; } if (EnchantmentHelper.getEnchantments(ctxTool).containsKey(Enchantments.SILK_TOUCH)) return generatedLoot; AnointmentHolder holder = AnointmentHolder.fromItemStack(ctxTool); if (holder == null) { return generatedLoot; } int additionalFortune = holder.getAnointmentLevel(AnointmentRegistrar.ANOINTMENT_FORTUNE.get()); if (additionalFortune <= 0) { return generatedLoot; } // if (holder.getAnointmentLevel(AnointmentRegistrar.ANOINTMENT_SILK_TOUCH.get()) > 0) // { // return generatedLoot; // } ItemStack fakeTool = ctxTool.copy(); fakeTool.getOrCreateTag().putBoolean("bloodmagic:checked_fortune", true); int baseFortuneLevel = EnchantmentHelper.getEnchantmentLevel(Enchantments.FORTUNE, ctxTool); fakeTool.addEnchantment(Enchantments.FORTUNE, baseFortuneLevel + additionalFortune); LootContext.Builder builder = new LootContext.Builder(context); builder.withParameter(LootParameters.TOOL, fakeTool); LootContext ctx = builder.build(LootParameterSets.BLOCK); LootTable loottable = context.getWorld().getServer().getLootTableManager().getLootTableFromLocation(context.get(LootParameters.BLOCK_STATE).getBlock().getLootTable()); return loottable.generate(ctx); } private static class Serializer extends GlobalLootModifierSerializer { @Override public FortuneModifier read(ResourceLocation name, JsonObject json, ILootCondition[] conditionsIn) { return new FortuneModifier(conditionsIn); } @Override public JsonObject write(FortuneModifier instance) { return makeConditions(instance.conditions); } } } private static class LootingModifier extends LootModifier { public LootingModifier(ILootCondition[] conditionsIn) { super(conditionsIn); } @Nonnull @Override public List doApply(List generatedLoot, LootContext context) { // System.out.println("Checking for looting"); // Entity killerEntity = context.get(LootParameters.KILLER_ENTITY); // if (!(killerEntity instanceof PlayerEntity)) // { return generatedLoot; // } // Entity killedEntity = context.get(LootParameters.THIS_ENTITY); // if (!(killedEntity instanceof LivingEntity)) // { // return generatedLoot; // } // ItemStack ctxTool = ((PlayerEntity) killerEntity).getHeldItemMainhand(); // // return early if silk-touch is already applied (otherwise we'll get stuck in // // an infinite loop). // // System.out.println("Checking looting. ItemStack context: "); //// EndermanEntity d; // if (ctxTool.getTag() != null && ctxTool.getTag().getBoolean("bloodmagic:checked_looting")) // { // return generatedLoot; // } // // if (EnchantmentHelper.getEnchantments(ctxTool).containsKey(Enchantments.SILK_TOUCH)) // return generatedLoot; // AnointmentHolder holder = AnointmentHolder.fromItemStack(ctxTool); // if (holder == null) // { // return generatedLoot; // } // // int additionalLooting = holder.getAnointmentLevel(AnointmentRegistrar.ANOINTMENT_LOOTING.get()) * 20; // if (additionalLooting <= 0) // { // return generatedLoot; // } // //// if (holder.getAnointmentLevel(AnointmentRegistrar.ANOINTMENT_SILK_TOUCH.get()) > 0) //// { //// return generatedLoot; //// } // // ItemStack fakeTool = ctxTool.copy(); // fakeTool.getOrCreateTag().putBoolean("bloodmagic:checked_looting", true); // int baseLootingLevel = EnchantmentHelper.getEnchantmentLevel(Enchantments.LOOTING, ctxTool); // // fakeTool.addEnchantment(Enchantments.LOOTING, baseLootingLevel + additionalLooting); // LootContext.Builder builder = new LootContext.Builder(context); // builder.withParameter(LootParameters.TOOL, fakeTool); // LootContext ctx = builder.build(LootParameterSets.ENTITY); // ResourceLocation resource = ((LivingEntity) killedEntity).getLootTableResourceLocation(); // LootTable loottable = context.getWorld().getServer().getLootTableManager().getLootTableFromLocation(resource); // return loottable.generate(ctx); } private static class Serializer extends GlobalLootModifierSerializer { @Override public LootingModifier read(ResourceLocation name, JsonObject json, ILootCondition[] conditionsIn) { return new LootingModifier(conditionsIn); } @Override public JsonObject write(LootingModifier instance) { return makeConditions(instance.conditions); } } // private static class ExtendedLootContext extends LootContext // { // public ExtendedLootContext() // { // // } // } } private static class SmeltingModifier extends LootModifier { public SmeltingModifier(ILootCondition[] conditionsIn) { super(conditionsIn); } @Nonnull @Override public List doApply(List generatedLoot, LootContext context) { ItemStack ctxTool = context.get(LootParameters.TOOL); // return early if silk-touch is already applied (otherwise we'll get stuck in // an infinite loop). if (ctxTool.getTag() == null) { return generatedLoot; } AnointmentHolder holder = AnointmentHolder.fromItemStack(ctxTool); if (holder == null) { return generatedLoot; } int smeltingLevel = holder.getAnointmentLevel(AnointmentRegistrar.ANOINTMENT_SMELTING.get()); if (smeltingLevel <= 0) { return generatedLoot; } ArrayList ret = new ArrayList(); generatedLoot.forEach((stack) -> ret.add(smelt(stack, context))); return ret; } private static ItemStack smelt(ItemStack stack, LootContext context) { return context.getWorld().getRecipeManager().getRecipe(IRecipeType.SMELTING, new Inventory(stack), context.getWorld()).map(FurnaceRecipe::getRecipeOutput).filter(itemStack -> !itemStack.isEmpty()).map(itemStack -> ItemHandlerHelper.copyStackWithSize(itemStack, stack.getCount() * itemStack.getCount())).orElse(stack); } private static class Serializer extends GlobalLootModifierSerializer { @Override public SmeltingModifier read(ResourceLocation name, JsonObject json, ILootCondition[] conditionsIn) { return new SmeltingModifier(conditionsIn); } @Override public JsonObject write(SmeltingModifier instance) { return makeConditions(instance.conditions); } } } }