Skip to content

Commit

Permalink
Merge branch '1.21.x' into 1.21.x-ShapeUpdateEvent
Browse files Browse the repository at this point in the history
  • Loading branch information
ZygZagGaming authored Feb 4, 2025
2 parents 03493f5 + 0d494e8 commit a5fcdce
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 15 deletions.
21 changes: 21 additions & 0 deletions patches/net/minecraft/world/entity/npc/VillagerType.java.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
--- a/net/minecraft/world/entity/npc/VillagerType.java
+++ b/net/minecraft/world/entity/npc/VillagerType.java
@@ -21,6 +_,8 @@
public static final VillagerType SWAMP = register("swamp");
public static final VillagerType TAIGA = register("taiga");
private final String name;
+ /** Neo: use the {@link net.neoforged.neoforge.registries.datamaps.builtin.NeoForgeDataMaps#VILLAGER_TYPES data map} instead as this field will be ignored in future versions */
+ @Deprecated
private static final Map<ResourceKey<Biome>, VillagerType> BY_BIOME = Util.make(Maps.newHashMap(), p_35834_ -> {
p_35834_.put(Biomes.BADLANDS, DESERT);
p_35834_.put(Biomes.DESERT, DESERT);
@@ -67,6 +_,9 @@
}

public static VillagerType byBiome(Holder<Biome> p_204074_) {
+ var fromDataMap = p_204074_.getData(net.neoforged.neoforge.registries.datamaps.builtin.NeoForgeDataMaps.VILLAGER_TYPES);
+ if (fromDataMap != null) return fromDataMap.type();
+ // TODO - 1.22: remove fallback
return p_204074_.unwrapKey().map(BY_BIOME::get).orElse(PLAINS);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
{
"values": {
"minecraft:badlands": {
"villager_type": "minecraft:desert"
},
"minecraft:bamboo_jungle": {
"villager_type": "minecraft:jungle"
},
"minecraft:deep_frozen_ocean": {
"villager_type": "minecraft:snow"
},
"minecraft:desert": {
"villager_type": "minecraft:desert"
},
"minecraft:eroded_badlands": {
"villager_type": "minecraft:desert"
},
"minecraft:frozen_ocean": {
"villager_type": "minecraft:snow"
},
"minecraft:frozen_peaks": {
"villager_type": "minecraft:snow"
},
"minecraft:frozen_river": {
"villager_type": "minecraft:snow"
},
"minecraft:grove": {
"villager_type": "minecraft:snow"
},
"minecraft:ice_spikes": {
"villager_type": "minecraft:snow"
},
"minecraft:jagged_peaks": {
"villager_type": "minecraft:snow"
},
"minecraft:jungle": {
"villager_type": "minecraft:jungle"
},
"minecraft:mangrove_swamp": {
"villager_type": "minecraft:swamp"
},
"minecraft:old_growth_pine_taiga": {
"villager_type": "minecraft:taiga"
},
"minecraft:old_growth_spruce_taiga": {
"villager_type": "minecraft:taiga"
},
"minecraft:savanna": {
"villager_type": "minecraft:savanna"
},
"minecraft:savanna_plateau": {
"villager_type": "minecraft:savanna"
},
"minecraft:snowy_beach": {
"villager_type": "minecraft:snow"
},
"minecraft:snowy_plains": {
"villager_type": "minecraft:snow"
},
"minecraft:snowy_slopes": {
"villager_type": "minecraft:snow"
},
"minecraft:snowy_taiga": {
"villager_type": "minecraft:snow"
},
"minecraft:sparse_jungle": {
"villager_type": "minecraft:jungle"
},
"minecraft:swamp": {
"villager_type": "minecraft:swamp"
},
"minecraft:taiga": {
"villager_type": "minecraft:taiga"
},
"minecraft:windswept_forest": {
"villager_type": "minecraft:taiga"
},
"minecraft:windswept_gravelly_hills": {
"villager_type": "minecraft:taiga"
},
"minecraft:windswept_hills": {
"villager_type": "minecraft:taiga"
},
"minecraft:windswept_savanna": {
"villager_type": "minecraft:savanna"
},
"minecraft:wooded_badlands": {
"villager_type": "minecraft:desert"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.stream.Collectors;
import net.minecraft.advancements.AdvancementHolder;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.commands.CommandSource;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.SharedSuggestionProvider;
Expand All @@ -27,6 +28,7 @@
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.flag.FeatureFlagSet;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec2;
import net.minecraft.world.phys.Vec3;
Expand All @@ -42,65 +44,84 @@ public ClientCommandSourceStack(CommandSource source, Vec3 position, Vec2 rotati
super(source, position, rotation, null, permission, plainTextName, displayName, null, executing);
}

/**
* {@return the current connection, used to shorten method calls and hide the nullability warnings}
*/
private ClientPacketListener connection() {
return Minecraft.getInstance().getConnection();
}

/**
* Sends a success message without attempting to get the server side list of admins
*/
@Override
public void sendSuccess(Supplier<Component> message, boolean sendToAdmins) {
Minecraft.getInstance().gui.getChat().addMessage(message.get());
//Don't send the message to admins, as that requires querying the server for the list of admins, and would cause a NPE
super.sendSuccess(message, false);
}

/**
* {@return the list of teams from the client side}
*/
@Override
public Collection<String> getAllTeams() {
return Minecraft.getInstance().level.getScoreboard().getTeamNames();
return getScoreboard().getTeamNames();
}

/**
* {@return the list of online player names from the client side}
*/
@Override
public Collection<String> getOnlinePlayerNames() {
return Minecraft.getInstance().getConnection().getOnlinePlayers().stream().map((player) -> player.getProfile().getName()).collect(Collectors.toList());
return connection().getOnlinePlayers().stream().map(player -> player.getProfile().getName()).collect(Collectors.toList());
}

@Override
public CompletableFuture<Suggestions> suggestRegistryElements(
ResourceKey<? extends Registry<?>> p_212330_,
SharedSuggestionProvider.ElementSuggestionType p_212331_,
SuggestionsBuilder p_212332_,
CommandContext<?> p_212333_) {
// TODO 1.21.2: Not sure what to do here. Letting super get called will cause an NPE on this.server.
if (p_212330_ == Registries.RECIPE || p_212330_ == Registries.ADVANCEMENT) {
ResourceKey<? extends Registry<?>> registry,
SharedSuggestionProvider.ElementSuggestionType suggestionType,
SuggestionsBuilder suggestionsBuilder,
CommandContext<?> context) {
if (registry == Registries.RECIPE) {
// TODO 1.21.2: Not sure what to do here as the client doesn't receive recipe names. Letting super get called will cause an NPE on this.server.
return Suggestions.empty();
} else if (registry == Registries.ADVANCEMENT) {
//Only suggest from advancements that are visible to the player
return SharedSuggestionProvider.suggestResource(connection().getAdvancements().getTree().nodes().stream().map(node -> node.holder().id()), suggestionsBuilder);
}
return super.suggestRegistryElements(p_212330_, p_212331_, p_212332_, p_212333_);
return super.suggestRegistryElements(registry, suggestionType, suggestionsBuilder, context);
}

/**
* {@return a set of {@link ResourceKey} for levels from the client side}
*/
@Override
public Set<ResourceKey<Level>> levels() {
return Minecraft.getInstance().getConnection().levels();
return connection().levels();
}

/**
* {@return the {@link RegistryAccess} from the client side}
*/
@Override
public RegistryAccess registryAccess() {
return Minecraft.getInstance().getConnection().registryAccess();
return connection().registryAccess();
}

/**
* {@return the {@link FeatureFlagSet} from the client side}
*/
@Override
public FeatureFlagSet enabledFeatures() {
return connection().enabledFeatures();
}

/**
* {@return the scoreboard from the client side}
*/
@Override
public Scoreboard getScoreboard() {
return Minecraft.getInstance().level.getScoreboard();
return connection().scoreboard();
}

/**
Expand All @@ -109,15 +130,15 @@ public Scoreboard getScoreboard() {
@Override
@Nullable
public AdvancementHolder getAdvancement(ResourceLocation id) {
return Minecraft.getInstance().getConnection().getAdvancements().get(id);
return connection().getAdvancements().get(id);
}

/**
* {@return the level from the client side}
*/
@Override
public Level getUnsidedLevel() {
return Minecraft.getInstance().level;
return connection().getLevel();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@
import net.minecraft.world.entity.ai.behavior.WorkAtComposter;
import net.minecraft.world.entity.animal.Parrot;
import net.minecraft.world.entity.npc.VillagerProfession;
import net.minecraft.world.entity.npc.VillagerType;
import net.minecraft.world.flag.FeatureFlags;
import net.minecraft.world.item.HoneycombItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.ComposterBlock;
import net.minecraft.world.level.block.WeatheringCopper;
import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity;
Expand All @@ -38,6 +40,7 @@
import net.minecraft.world.level.storage.loot.LootTable;
import net.neoforged.fml.util.ObfuscationReflectionHelper;
import net.neoforged.neoforge.common.data.DataMapProvider;
import net.neoforged.neoforge.registries.datamaps.builtin.BiomeVillagerType;
import net.neoforged.neoforge.registries.datamaps.builtin.Compostable;
import net.neoforged.neoforge.registries.datamaps.builtin.FurnaceFuel;
import net.neoforged.neoforge.registries.datamaps.builtin.MonsterRoomMob;
Expand All @@ -55,6 +58,10 @@ public NeoForgeDataMapsProvider(PackOutput packOutput, CompletableFuture<HolderL

@Override
protected void gather(HolderLookup.Provider provider) {
final var biomeVillagers = builder(NeoForgeDataMaps.VILLAGER_TYPES);
ObfuscationReflectionHelper.<Map<ResourceKey<Biome>, VillagerType>, VillagerType>getPrivateValue(VillagerType.class, null, "BY_BIOME")
.forEach((biome, type) -> biomeVillagers.add(biome, new BiomeVillagerType(type), false));

final var compostables = builder(NeoForgeDataMaps.COMPOSTABLES);
final List<Item> villagerCompostables = ObfuscationReflectionHelper.getPrivateValue(WorkAtComposter.class, null, "COMPOSTABLE_ITEMS");
ComposterBlock.COMPOSTABLES.forEach((item, chance) -> compostables.add(item.asItem().builtInRegistryHolder(), new Compostable(chance, villagerCompostables.contains(item.asItem())), false));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforge.registries.datamaps.builtin;

import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.entity.npc.VillagerType;

/**
* Data map value for {@linkplain NeoForgeDataMaps#VILLAGER_TYPES biome villager types}.
*
* @param type the type of the villagers present in this biome
*/
public record BiomeVillagerType(VillagerType type) {
public static final Codec<BiomeVillagerType> TYPE_CODEC = BuiltInRegistries.VILLAGER_TYPE.byNameCodec()
.xmap(BiomeVillagerType::new, BiomeVillagerType::type);
public static final Codec<BiomeVillagerType> CODEC = Codec.withAlternative(
RecordCodecBuilder.create(in -> in.group(
BuiltInRegistries.VILLAGER_TYPE.byNameCodec().fieldOf("villager_type").forGetter(BiomeVillagerType::type)).apply(in, BiomeVillagerType::new)),
TYPE_CODEC);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
import net.minecraft.world.entity.ai.behavior.GiveGiftToHero;
import net.minecraft.world.entity.animal.Parrot;
import net.minecraft.world.entity.npc.VillagerProfession;
import net.minecraft.world.entity.npc.VillagerType;
import net.minecraft.world.item.HoneycombItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.ComposterBlock;
import net.minecraft.world.level.block.WeatheringCopper;
Expand Down Expand Up @@ -128,6 +130,19 @@ public class NeoForgeDataMaps {
public static final DataMapType<GameEvent, VibrationFrequency> VIBRATION_FREQUENCIES = DataMapType.builder(
id("vibration_frequencies"), Registries.GAME_EVENT, VibrationFrequency.CODEC).synced(VibrationFrequency.FREQUENCY_CODEC, false).build();

/**
* The {@linkplain Biome} data map that replaces {@link VillagerType#BY_BIOME}.
* <p>
* The location of this data map is {@code neoforge/data_maps/worldgen/biome/villager_types.json}, and the values are objects with 1 field:
* <ul>
* <li>{@code villager_type}, villager type ID - the type of the villagers present in the biome</li>
* </ul>
*
* The use of a string as the value is also possible, though discouraged in case more options are added in the future.
*/
public static final DataMapType<Biome, BiomeVillagerType> VILLAGER_TYPES = DataMapType.builder(
id("villager_types"), Registries.BIOME, BiomeVillagerType.CODEC).synced(BiomeVillagerType.TYPE_CODEC, false).build();

/**
* The {@linkplain Block} data map that replaces {@link HoneycombItem#WAXABLES}.
* <p>
Expand All @@ -154,6 +169,7 @@ private static void register(final RegisterDataMapTypesEvent event) {
event.register(PARROT_IMITATIONS);
event.register(RAID_HERO_GIFTS);
event.register(VIBRATION_FREQUENCIES);
event.register(VILLAGER_TYPES);
event.register(WAXABLES);
}
}

0 comments on commit a5fcdce

Please sign in to comment.