[1.16.x] Add loot table ID in Global Loot Modifiers (#7428)

This commit is contained in:
Silk authored and GitHub committed 2021-02-02 13:32:02 +01:00
1 parent aeaebf5785
commit 83fee0b3d4
9 files changed
+237 -10

No files matched your search

@@ -131,6 +131,7 @@ import net.minecraft.world.biome.BiomeGenerationSettings;
import net.minecraft.world.biome.MobSpawnInfo;
import net.minecraftforge.common.loot.IGlobalLootModifier;
import net.minecraftforge.common.loot.LootModifierManager;
import net.minecraftforge.common.loot.LootTableIdCondition;
import net.minecraftforge.common.util.BlockSnapshot;
import net.minecraftforge.common.world.BiomeGenerationSettingsBuilder;
import net.minecraftforge.common.world.ForgeWorldType;
@@ -861,6 +862,7 @@ public class ForgeHooks
{
que.push(new LootTableContext(name, custom));
ret = gson.fromJson(data, LootTable.class);
ret.setLootTableId(name);
que.pop();
}
catch (JsonParseException e)
@@ -1253,16 +1255,42 @@ public class ForgeHooks
/**
* All loot table drops should be passed to this function so that mod added effects
* (e.g. smelting enchantments) can be processed.
*
* @param list The loot generated
* @param context The loot context that generated that loot
* @return The modified list
*
* @deprecated Use {@link #modifyLoot(ResourceLocation, List, LootContext)} instead.
*
* @implNote This method will use the {@linkplain LootTableIdCondition#UNKNOWN_LOOT_TABLE
* unknown loot table marker} when redirecting.
*/
@Deprecated
public static List<ItemStack> modifyLoot(List<ItemStack> list, LootContext context) {
return modifyLoot(LootTableIdCondition.UNKNOWN_LOOT_TABLE, list, context);
}
/**
* Handles the modification of loot table drops via the registered Global Loot Modifiers,
* so that custom effects can be processed.
*
* <p>All loot-table generated loot should be passed to this function.</p>
*
* @param lootTableId The ID of the loot table currently being queried
* @param generatedLoot The loot generated by the loot table
* @param context The loot context that generated the loot, unmodified
* @return The modified list of drops
*
* @apiNote The given context will be modified by this method to also store the ID of the
* loot table being queried.
*/
public static List<ItemStack> modifyLoot(ResourceLocation lootTableId, List<ItemStack> generatedLoot, LootContext context) {
context.setQueriedLootTableId(lootTableId); // In case the ID was set via copy constructor, this will be ignored: intended
LootModifierManager man = ForgeInternalHandler.getLootModifierManager();
for(IGlobalLootModifier mod : man.getAllLootMods()) {
list = mod.apply(list, context);
for (IGlobalLootModifier mod : man.getAllLootMods()) {
generatedLoot = mod.apply(generatedLoot, context);
}
return list;
return generatedLoot;
}
public static List<String> getModPacks()
@@ -27,12 +27,15 @@ import net.minecraft.entity.ai.attributes.RangedAttribute;
import net.minecraft.fluid.Fluid;
import net.minecraft.item.Items;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.storage.IServerConfiguration;
import net.minecraft.world.storage.SaveFormat;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.ForgeHooksClient;
import net.minecraftforge.common.data.ExistingFileHelper;
import net.minecraftforge.common.data.ForgeFluidTagsProvider;
import net.minecraftforge.common.loot.GlobalLootModifierSerializer;
import net.minecraftforge.common.loot.LootTableIdCondition;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fluids.FluidAttributes;
@@ -48,7 +51,6 @@ import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.server.command.EnumArgument;
import net.minecraftforge.server.command.ModIdArgument;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.IForgeRegistry;
import net.minecraftforge.versions.forge.ForgeVersion;
import net.minecraftforge.versions.mcp.MCPVersion;
@@ -288,4 +290,12 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook
event.getRegistry().register(new ConditionalRecipe.Serializer<IRecipe<?>>().setRegistryName(new ResourceLocation("forge", "conditional")));
}
@SubscribeEvent //ModBus
@SuppressWarnings("unused") // automatically called by Forge
public void registerLootData(RegistryEvent.Register<GlobalLootModifierSerializer<?>> event)
{
// Ignore the event itself: this is done only not to statically initialize our custom LootConditionType
Registry.register(Registry.LOOT_CONDITION_TYPE, new ResourceLocation("forge:loot_table_id"), LootTableIdCondition.LOOT_TABLE_ID);
}
}
@@ -0,0 +1,93 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2020.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.common.loot;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import net.minecraft.loot.ILootSerializer;
import net.minecraft.loot.LootConditionType;
import net.minecraft.loot.LootContext;
import net.minecraft.loot.conditions.ILootCondition;
import net.minecraft.util.JSONUtils;
import net.minecraft.util.ResourceLocation;
public class LootTableIdCondition implements ILootCondition
{
// TODO Forge Registry at some point?
public static final LootConditionType LOOT_TABLE_ID = new LootConditionType(new LootTableIdCondition.Serializer());
public static final ResourceLocation UNKNOWN_LOOT_TABLE = new ResourceLocation("forge", "unknown_loot_table");
private final ResourceLocation targetLootTableId;
private LootTableIdCondition(final ResourceLocation targetLootTableId)
{
this.targetLootTableId = targetLootTableId;
}
@Override
public LootConditionType func_230419_b_()
{
return LOOT_TABLE_ID;
}
@Override
public boolean test(LootContext lootContext)
{
return lootContext.getQueriedLootTableId().equals(this.targetLootTableId);
}
public static Builder builder(final ResourceLocation targetLootTableId)
{
return new Builder(targetLootTableId);
}
public static class Builder implements ILootCondition.IBuilder
{
private final ResourceLocation targetLootTableId;
public Builder(ResourceLocation targetLootTableId)
{
if (targetLootTableId == null) throw new IllegalArgumentException("Target loot table must not be null");
this.targetLootTableId = targetLootTableId;
}
@Override
public ILootCondition build()
{
return new LootTableIdCondition(this.targetLootTableId);
}
}
public static class Serializer implements ILootSerializer<LootTableIdCondition>
{
@Override
public void serialize(JsonObject object, LootTableIdCondition instance, JsonSerializationContext ctx)
{
object.addProperty("loot_table_id", instance.targetLootTableId.toString());
}
@Override
public LootTableIdCondition deserialize(JsonObject object, JsonDeserializationContext ctx)
{
return new LootTableIdCondition(new ResourceLocation(JSONUtils.getString(object, "loot_table_id")));
}
}
}