mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-12 00:07:45 +00:00
Fix issues in VillagerTrades.EmeraldsForVillagerTypeItem related to custom Villager Types (#10310)
Add VillagerType#registerBiomeType
This commit is contained in:
1 parent
6a78310a52
commit
384fe451fc
3 files changed
+113
No files matched your search
@@ -0,0 +1,21 @@
|
||||
--- a/net/minecraft/world/entity/npc/VillagerTrades.java
|
||||
+++ b/net/minecraft/world/entity/npc/VillagerTrades.java
|
||||
@@ -1366,6 +_,7 @@
|
||||
private final int villagerXp;
|
||||
|
||||
public EmeraldsForVillagerTypeItem(int p_35669_, int p_35670_, int p_35671_, Map<VillagerType, Item> p_35672_) {
|
||||
+ if (false) // FORGE: Modders can add custom villager types, so remove this validation
|
||||
BuiltInRegistries.VILLAGER_TYPE.stream().filter(p_35680_ -> !p_35672_.containsKey(p_35680_)).findAny().ifPresent(p_327046_ -> {
|
||||
throw new IllegalStateException("Missing trade for villager type: " + BuiltInRegistries.VILLAGER_TYPE.getKey(p_327046_));
|
||||
});
|
||||
@@ -1379,7 +_,9 @@
|
||||
@Override
|
||||
public MerchantOffer getOffer(Entity p_219685_, RandomSource p_219686_) {
|
||||
if (p_219685_ instanceof VillagerDataHolder villagerdataholder) {
|
||||
- ItemCost itemcost = new ItemCost(this.trades.get(villagerdataholder.getVillagerData().getType()), this.cost);
|
||||
+ Item item = this.trades.get(villagerdataholder.getVillagerData().getType());
|
||||
+ if (item == null) return null;
|
||||
+ ItemCost itemcost = new ItemCost(item, this.cost); // FORGE: Account for modded villager types by returning null if there is no trade
|
||||
return new MerchantOffer(itemcost, new ItemStack(Items.EMERALD), this.maxUses, this.villagerXp, 0.05F);
|
||||
} else {
|
||||
return null;
|
||||
@@ -0,0 +1,12 @@
|
||||
--- a/net/minecraft/world/entity/npc/VillagerType.java
|
||||
+++ b/net/minecraft/world/entity/npc/VillagerType.java
|
||||
@@ -69,4 +_,9 @@
|
||||
public static VillagerType byBiome(Holder<Biome> p_204074_) {
|
||||
return p_204074_.unwrapKey().map(BY_BIOME::get).orElse(PLAINS);
|
||||
}
|
||||
+
|
||||
+ /** FORGE: Registers the VillagerType that will spawn in the given biome. This method should be called during FMLCommonSetupEvent using event.enqueueWork() */
|
||||
+ public static void registerBiomeType(ResourceKey<Biome> biomeKey, VillagerType villagerType) {
|
||||
+ BY_BIOME.put(biomeKey, villagerType);
|
||||
+ }
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) Forge Development LLC and contributors
|
||||
* SPDX-License-Identifier: LGPL-2.1-only
|
||||
*/
|
||||
|
||||
package net.minecraftforge.debug.gameplay.villager;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.gametest.framework.GameTest;
|
||||
import net.minecraft.gametest.framework.GameTestHelper;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.npc.Villager;
|
||||
import net.minecraft.world.entity.npc.VillagerTrades;
|
||||
import net.minecraft.world.entity.npc.VillagerType;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.Biomes;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import net.minecraftforge.gametest.GameTestHolder;
|
||||
import net.minecraftforge.registries.DeferredRegister;
|
||||
import net.minecraftforge.registries.RegistryObject;
|
||||
import net.minecraftforge.test.BaseTestMod;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@GameTestHolder("forge." + VillagerTypeTestMod.MOD_ID)
|
||||
@Mod(VillagerTypeTestMod.MOD_ID)
|
||||
public class VillagerTypeTestMod extends BaseTestMod {
|
||||
public static final String MOD_ID = "villager_type_test";
|
||||
|
||||
private static final DeferredRegister<VillagerType> VILLAGER_TYPES = DeferredRegister.create(Registries.VILLAGER_TYPE, MOD_ID);
|
||||
|
||||
private static final RegistryObject<VillagerType> TEST_VILLAGER_TYPE = VILLAGER_TYPES.register("test_villager_type", () -> new VillagerType("test_villager_type"));
|
||||
|
||||
public VillagerTypeTestMod(FMLJavaModLoadingContext context) {
|
||||
context.getModEventBus().addListener(this::onCommonSetup);
|
||||
}
|
||||
|
||||
private void onCommonSetup(final FMLCommonSetupEvent event) {
|
||||
event.enqueueWork(() -> VillagerType.registerBiomeType(Biomes.PLAINS, TEST_VILLAGER_TYPE.get()));
|
||||
}
|
||||
|
||||
@GameTest(template = "forge:empty3x3x3")
|
||||
public static void biome_type(GameTestHelper helper) {
|
||||
RegistryAccess access = helper.getLevel().registryAccess();
|
||||
VillagerType type = access.registryOrThrow(Registries.VILLAGER_TYPE).get(TEST_VILLAGER_TYPE.getId());
|
||||
if (type == null)
|
||||
helper.fail("Failed to find test_villager_type");
|
||||
helper.assertValueEqual(type, TEST_VILLAGER_TYPE.get(), "Loaded entry does not contain expected value");
|
||||
|
||||
Holder<Biome> biome = access.lookupOrThrow(Registries.BIOME).getOrThrow(Biomes.PLAINS);
|
||||
helper.assertValueEqual(VillagerType.byBiome(biome), TEST_VILLAGER_TYPE.get(), "VillagerType.byBiome did not return the expected value");
|
||||
|
||||
helper.succeed();
|
||||
}
|
||||
|
||||
/** Test verifies NPE not thrown when looking up a villager type in the trade that doesn't contain that type.*/
|
||||
@GameTest(template = "forge:empty3x3x3")
|
||||
public static void emeralds_for_villager_type(GameTestHelper helper) {
|
||||
var trade = new VillagerTrades.EmeraldsForVillagerTypeItem(1, 12, 30, Map.of(TEST_VILLAGER_TYPE.get(), Items.DIRT));
|
||||
var rnd = helper.getLevel().getRandom();
|
||||
|
||||
// Should be a successful trade for dirt for our test villager
|
||||
var test = new Villager(EntityType.VILLAGER, helper.getLevel(), TEST_VILLAGER_TYPE.get());
|
||||
var test_offer = trade.getOffer(test, rnd);
|
||||
helper.assertFalse(test_offer == null, "Failed to retreive trade value for test profession");
|
||||
helper.assertValueEqual(test_offer.getItemCostA().itemStack().getItem(), Items.DIRT, "Offer did not return the expected item");
|
||||
|
||||
var plains = new Villager(EntityType.VILLAGER, helper.getLevel(), VillagerType.PLAINS);
|
||||
// This will NPE on unpatched code, we need to test that it returns null correctly
|
||||
var plains_offer = trade.getOffer(plains, rnd);
|
||||
helper.assertTrue(plains_offer == null, "Offer should not be available for a plains villager");
|
||||
|
||||
helper.succeed();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user