Tag Factory API ()

* Tag factory

* Add static biome tag factory to the API

* Use SERVER_STARTING event

* Use the ctor directly

* Use the default BIOME factory

* AccessorDynamicRegistryManager -> DynamicRegistryManagerAccess

* Return Tag.Identified

* Load dynamic registry tags right after datapack entries loaded

* DynamicRegistryManagerAccess -> DynamicRegistryManagerAccessor

* Fix grammar
This commit is contained in:
deirn 2021-08-18 01:07:12 +07:00 committed by GitHub
parent 2e8bd82f1c
commit 5e85fc0a09
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 642 additions and 19 deletions

View file

@ -5,3 +5,9 @@ moduleDependencies(project, [
'fabric-api-base',
'fabric-resource-loader-v0'
])
dependencies {
testmodImplementation project(path: ':fabric-command-api-v1', configuration: 'dev')
testmodImplementation project(path: ':fabric-key-binding-api-v1', configuration: 'dev')
testmodImplementation project(path: ':fabric-lifecycle-events-v1', configuration: 'dev')
}

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.api.tag;
import java.util.function.Supplier;
import net.minecraft.block.Block;
import net.minecraft.entity.EntityType;
import net.minecraft.fluid.Fluid;
import net.minecraft.item.Item;
import net.minecraft.tag.BlockTags;
import net.minecraft.tag.EntityTypeTags;
import net.minecraft.tag.FluidTags;
import net.minecraft.tag.GameEventTags;
import net.minecraft.tag.ItemTags;
import net.minecraft.tag.Tag;
import net.minecraft.tag.TagGroup;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.event.GameEvent;
import net.fabricmc.fabric.impl.tag.extension.TagFactoryImpl;
/**
* A factory for accessing datapack tags.
*/
public interface TagFactory<T> {
TagFactory<Item> ITEM = of(ItemTags::getTagGroup);
TagFactory<Block> BLOCK = of(BlockTags::getTagGroup);
TagFactory<Fluid> FLUID = of(FluidTags::getTagGroup);
TagFactory<GameEvent> GAME_EVENT = of(GameEventTags::getTagGroup);
TagFactory<EntityType<?>> ENTITY_TYPE = of(EntityTypeTags::getTagGroup);
TagFactory<Biome> BIOME = of(Registry.BIOME_KEY, "tags/biomes");
/**
* Create a new tag factory for specified registry.
*
* @param registryKey the key of the registry.
* @param dataType the data type of this tag group, vanilla uses "tags/[plural]" format for built-in groups.
*/
static <T> TagFactory<T> of(RegistryKey<? extends Registry<T>> registryKey, String dataType) {
return TagFactoryImpl.of(registryKey, dataType);
}
static <T> TagFactory<T> of(Supplier<TagGroup<T>> tagGroupSupplier) {
return TagFactoryImpl.of(tagGroupSupplier);
}
Tag.Identified<T> create(Identifier id);
}

View file

@ -19,22 +19,21 @@ package net.fabricmc.fabric.api.tag;
import java.util.function.Supplier;
import net.minecraft.block.Block;
import net.minecraft.tag.TagGroup;
import net.minecraft.entity.EntityType;
import net.minecraft.fluid.Fluid;
import net.minecraft.item.Item;
import net.minecraft.tag.BlockTags;
import net.minecraft.tag.EntityTypeTags;
import net.minecraft.tag.ItemTags;
import net.minecraft.tag.Tag;
import net.minecraft.tag.TagGroup;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.impl.tag.extension.TagDelegate;
import net.fabricmc.fabric.mixin.tag.extension.AccessorFluidTags;
/**
* Helper methods for registering Tags.
*
* @deprecated use {@link TagFactory} instead.
*/
@Deprecated
public final class TagRegistry {
private TagRegistry() { }
@ -42,19 +41,35 @@ public final class TagRegistry {
return new TagDelegate<>(id, containerSupplier);
}
/**
* @deprecated use {@link TagFactory#BLOCK}
*/
@Deprecated
public static Tag<Block> block(Identifier id) {
return create(id, BlockTags::getTagGroup);
return TagFactory.BLOCK.create(id);
}
/**
* @deprecated use {@link TagFactory#ENTITY_TYPE}
*/
@Deprecated
public static Tag<EntityType<?>> entityType(Identifier id) {
return create(id, EntityTypeTags::getTagGroup);
return TagFactory.ENTITY_TYPE.create(id);
}
/**
* @deprecated use {@link TagFactory#FLUID}
*/
@Deprecated
public static Tag<Fluid> fluid(Identifier id) {
return create(id, () -> AccessorFluidTags.getRequiredTags().getGroup());
return TagFactory.FLUID.create(id);
}
/**
* @deprecated use {@link TagFactory#ITEM}
*/
@Deprecated
public static Tag<Item> item(Identifier id) {
return create(id, ItemTags::getTagGroup);
return TagFactory.ITEM.create(id);
}
}

View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.impl.tag.extension;
import net.minecraft.tag.TagGroup;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryKey;
public interface FabricTagManagerHooks {
void fabric_addTagGroup(RegistryKey<? extends Registry<?>> registryKey, TagGroup<?> tagGroup);
}

View file

@ -0,0 +1,119 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.impl.tag.extension;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;
import com.google.common.base.Preconditions;
import com.google.common.base.Stopwatch;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import net.minecraft.resource.ResourceManager;
import net.minecraft.resource.ServerResourceManager;
import net.minecraft.server.Main;
import net.minecraft.tag.RequiredTagList;
import net.minecraft.tag.RequiredTagListRegistry;
import net.minecraft.tag.ServerTagManagerHolder;
import net.minecraft.tag.Tag;
import net.minecraft.tag.TagGroup;
import net.minecraft.tag.TagGroupLoader;
import net.minecraft.util.Identifier;
import net.minecraft.util.dynamic.RegistryOps;
import net.minecraft.util.registry.DynamicRegistryManager;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryKey;
import net.fabricmc.fabric.api.tag.TagFactory;
import net.fabricmc.fabric.mixin.tag.extension.DynamicRegistryManagerAccessor;
@SuppressWarnings("ClassCanBeRecord")
public final class TagFactoryImpl<T> implements TagFactory<T> {
private static final Logger LOGGER = LogManager.getLogger();
public static final Map<RegistryKey<? extends Registry<?>>, RequiredTagList<?>> TAG_LISTS = new HashMap<>();
public static final Set<RequiredTagList<?>> DYNAMICS = new HashSet<>();
public static <T> TagFactory<T> of(Supplier<TagGroup<T>> tagGroupSupplier) {
return new TagFactoryImpl<>(tagGroupSupplier);
}
@SuppressWarnings("unchecked")
public static <T> TagFactory<T> of(RegistryKey<? extends Registry<T>> registryKey, String dataType) {
RequiredTagList<T> tagList;
// Use already registered tag list for the registry if it has the same dataType, in case multiple mods tried to do it.
if (TAG_LISTS.containsKey(registryKey)) {
tagList = (RequiredTagList<T>) TAG_LISTS.get(registryKey);
// Throw an exception if the tagList has different dataType.
Preconditions.checkArgument(tagList.getDataType().equals(dataType), "Tag list for registry %s is already existed with data type %s", registryKey.getValue(), tagList.getDataType());
} else {
tagList = RequiredTagListRegistry.register(registryKey, dataType);
TAG_LISTS.put(registryKey, tagList);
// Check whether the registry dynamic.
if (DynamicRegistryManagerAccessor.getInfos().containsKey(registryKey)) {
DYNAMICS.add(tagList);
}
}
return of(tagList::getGroup);
}
/**
* Manually load tags for dynamic registries and add the resulting tag group to the tag list.
*
* <p>Minecraft loads the resource manager before dynamic registries, making tags for them fail to load
* if it mentions datapack entries. The solution is to manually load tags after the registry is loaded.
*
* <p>Look at server's {@link Main#main} function calls for {@link ServerResourceManager#reload} and
* {@link RegistryOps#method_36574} for the relevant code.
*/
public static void loadDynamicRegistryTags(DynamicRegistryManager registryManager, ResourceManager resourceManager) {
Stopwatch stopwatch = Stopwatch.createStarted();
int loadedTags = 0;
for (RequiredTagList<?> tagList : DYNAMICS) {
RegistryKey<? extends Registry<?>> registryKey = tagList.getRegistryKey();
Registry<?> registry = registryManager.get(registryKey);
TagGroupLoader<?> tagGroupLoader = new TagGroupLoader<>(registry::getOrEmpty, tagList.getDataType());
TagGroup<?> tagGroup = tagGroupLoader.load(resourceManager);
((FabricTagManagerHooks) ServerTagManagerHolder.getTagManager()).fabric_addTagGroup(registryKey, tagGroup);
tagList.updateTagManager(ServerTagManagerHolder.getTagManager());
loadedTags += tagGroup.getTags().size();
}
if (loadedTags > 0) {
LOGGER.info("Loaded {} dynamic registry tags in {}", loadedTags, stopwatch);
}
}
private final Supplier<TagGroup<T>> tagGroupSupplier;
private TagFactoryImpl(Supplier<TagGroup<T>> tagGroupSupplier) {
this.tagGroupSupplier = tagGroupSupplier;
}
@Override
public Tag.Identified<T> create(Identifier id) {
return new TagDelegate<>(id, tagGroupSupplier);
}
}

View file

@ -16,17 +16,19 @@
package net.fabricmc.fabric.mixin.tag.extension;
import java.util.Map;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import net.minecraft.fluid.Fluid;
import net.minecraft.tag.FluidTags;
import net.minecraft.tag.RequiredTagList;
import net.minecraft.util.registry.DynamicRegistryManager;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryKey;
@Mixin(FluidTags.class)
public interface AccessorFluidTags {
@Accessor("REQUIRED_TAGS")
static RequiredTagList<Fluid> getRequiredTags() {
throw new UnsupportedOperationException();
@Mixin(DynamicRegistryManager.class)
public interface DynamicRegistryManagerAccessor {
@Accessor("INFOS")
static Map<RegistryKey<? extends Registry<?>>, ?> getInfos() {
throw new AssertionError();
}
}

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.mixin.tag.extension;
import java.util.Collection;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.resource.ServerResourceManager;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.registry.DynamicRegistryManager;
import net.fabricmc.fabric.impl.tag.extension.TagFactoryImpl;
@Mixin(MinecraftServer.class)
public abstract class MixinMinecraftServer {
@Shadow
@Final
protected DynamicRegistryManager.Impl registryManager;
@SuppressWarnings("UnresolvedMixinReference")
@Inject(method = "method_29440", at = @At(value = "INVOKE", target = "Lnet/minecraft/resource/ServerResourceManager;loadRegistryTags()V", shift = At.Shift.AFTER))
private void method_29440(Collection<?> collection, ServerResourceManager serverResourceManager, CallbackInfo ci) {
// Load dynamic registry tags on datapack reload.
TagFactoryImpl.loadDynamicRegistryTags(registryManager, serverResourceManager.getResourceManager());
}
}

View file

@ -0,0 +1,41 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.mixin.tag.extension;
import com.mojang.serialization.DynamicOps;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.resource.ResourceManager;
import net.minecraft.util.dynamic.RegistryOps;
import net.minecraft.util.registry.DynamicRegistryManager;
import net.fabricmc.fabric.impl.tag.extension.TagFactoryImpl;
/**
* This mixin loads dynamic registry tags right after datapack entries loaded.
* Needs a higher priority so it will be called before biome modifications.
*/
@Mixin(value = RegistryOps.class, priority = 900)
public class MixinRegistryOps {
@Inject(method = "method_36574", at = @At("RETURN"))
private static <T> void afterDynamicRegistryLoaded(DynamicOps<T> dynamicOps, ResourceManager resourceManager, DynamicRegistryManager registryManager, CallbackInfoReturnable<RegistryOps<T>> cir) {
TagFactoryImpl.loadDynamicRegistryTags(registryManager, resourceManager);
}
}

View file

@ -0,0 +1,41 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.mixin.tag.extension;
import java.util.HashSet;
import java.util.Set;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.tag.RequiredTagList;
import net.minecraft.tag.RequiredTagListRegistry;
import net.fabricmc.fabric.impl.tag.extension.TagFactoryImpl;
@Mixin(RequiredTagListRegistry.class)
public class MixinRequiredTagListRegistry {
@Inject(method = "getBuiltinTags", at = @At("TAIL"), cancellable = true)
private static void getBuiltinTags(CallbackInfoReturnable<Set<RequiredTagList<?>>> cir) {
// Add tag lists registered on fabric to the map.
Set<RequiredTagList<?>> set = new HashSet<>(cir.getReturnValue());
set.addAll(TagFactoryImpl.TAG_LISTS.values());
cir.setReturnValue(set);
}
}

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.mixin.tag.extension;
import java.util.HashMap;
import java.util.Map;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.tag.TagGroup;
import net.minecraft.tag.TagManager;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryKey;
import net.fabricmc.fabric.impl.tag.extension.FabricTagManagerHooks;
@Mixin(TagManager.class)
public class MixinTagManager implements FabricTagManagerHooks {
@Shadow
@Mutable
@Final
private Map<RegistryKey<? extends Registry<?>>, TagGroup<?>> tagGroups;
@Inject(method = "<init>", at = @At("TAIL"))
private void init(Map<RegistryKey<? extends Registry<?>>, TagGroup<?>> tagGroups, CallbackInfo ci) {
// Make it mutable so we can add dynamic registry tags later.
this.tagGroups = new HashMap<>(tagGroups);
}
@Override
public void fabric_addTagGroup(RegistryKey<? extends Registry<?>> registryKey, TagGroup<?> tagGroup) {
tagGroups.put(registryKey, tagGroup);
}
}

View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.mixin.tag.extension;
import java.util.List;
import java.util.concurrent.Executor;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.resource.ResourceManager;
import net.minecraft.tag.RequiredTagList;
import net.minecraft.tag.TagManagerLoader;
import net.fabricmc.fabric.impl.tag.extension.TagFactoryImpl;
@Mixin(TagManagerLoader.class)
public abstract class MixinTagManagerLoader {
// RequiredTagListRegistry.forEach in reload.
@SuppressWarnings("UnresolvedMixinReference")
@Inject(method = "method_33179", at = @At("HEAD"), cancellable = true)
private void method_33179(ResourceManager resourceManager, Executor executor, List<?> list, RequiredTagList<?> requiredTagList, CallbackInfo ci) {
// Don't load dynamic registry tags now, we need to load them after the dynamic registry.
if (TagFactoryImpl.DYNAMICS.contains(requiredTagList)) {
ci.cancel();
}
}
}

View file

@ -3,10 +3,15 @@
"package": "net.fabricmc.fabric.mixin.tag.extension",
"compatibilityLevel": "JAVA_16",
"mixins": [
"AccessorFluidTags",
"DynamicRegistryManagerAccessor",
"MixinMinecraftServer",
"MixinObjectBuilder",
"MixinRegistryOps",
"MixinRequiredTagListRegistry",
"MixinTagBuilder",
"MixinTagImpl",
"MixinTagBuilder"
"MixinTagManager",
"MixinTagManagerLoader"
],
"injectors": {
"defaultRequire": 1

View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.test.tag.extension;
import static net.minecraft.server.command.CommandManager.literal;
import java.util.Map;
import java.util.Optional;
import net.minecraft.tag.Tag;
import net.minecraft.text.LiteralText;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.biome.Biome;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
import net.fabricmc.fabric.api.tag.TagFactory;
public class TagExtensionTest implements ModInitializer {
static final Tag<Biome> FACTORY_TEST = TagFactory.BIOME.create(new Identifier("fabric-tag-extensions-v0-testmod:factory_test"));
@Override
public void onInitialize() {
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) -> dispatcher.register(literal("biome_tag_test")
.then(literal("factory").executes(context -> {
FACTORY_TEST.values().forEach(biome -> {
Identifier id = context.getSource().getRegistryManager().get(Registry.BIOME_KEY).getId(biome);
context.getSource().sendFeedback(new LiteralText(id.toString()), false);
});
return 1;
}))
.then(literal("list_all").executes(context -> {
Map<Identifier, Tag<Biome>> tags = context.getSource().getServer().getTagManager().getOrCreateTagGroup(Registry.BIOME_KEY).getTags();
tags.forEach((tagId, tag) -> {
LiteralText text = new LiteralText(tagId.toString() + ":");
tag.values().forEach(biome -> {
Optional<RegistryKey<Biome>> biomeKey = context.getSource().getRegistryManager().get(Registry.BIOME_KEY).getKey(biome);
biomeKey.ifPresent(key -> text.append(" " + key.getValue()));
});
context.getSource().sendFeedback(text, false);
});
return 1;
}))));
}
}

View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.test.tag.extension;
import org.lwjgl.glfw.GLFW;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.text.LiteralText;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
public class TagExtensionTestClient implements ClientModInitializer {
static final KeyBinding KEY_BINDING = KeyBindingHelper.registerKeyBinding(new KeyBinding("tag_test", GLFW.GLFW_KEY_EQUAL, "tag_test"));
@Override
public void onInitializeClient() {
ClientTickEvents.END_CLIENT_TICK.register(client -> {
if (KEY_BINDING.isPressed()) {
TagExtensionTest.FACTORY_TEST.values().forEach(biome -> {
Identifier id = client.getNetworkHandler().getRegistryManager().get(Registry.BIOME_KEY).getId(biome);
client.player.sendMessage(new LiteralText(id.toString()), false);
});
}
});
}
}

View file

@ -0,0 +1,8 @@
{
"replace": false,
"values": [
"minecraft:plains",
"minecraft:desert",
"fabric-tag-extensions-v0-testmod:test"
]
}

View file

@ -0,0 +1,7 @@
{
"replace": false,
"values": [
"minecraft:forest",
"minecraft:taiga"
]
}

View file

@ -0,0 +1,20 @@
{
"surface_builder": "minecraft:grass",
"depth": 0.125,
"scale": 0.05,
"temperature": 0.8,
"downfall": 0.4,
"precipitation": "rain",
"category": "plains",
"effects": {
"sky_color": 7907327,
"fog_color": 12638463,
"water_color": 4159204,
"water_fog_color": 329011
},
"starts": [],
"spawners": {},
"spawn_costs": {},
"carvers": {},
"features": []
}

View file

@ -0,0 +1,19 @@
{
"schemaVersion": 1,
"id": "fabric-tag-extensions-v0-testmod",
"name": "Fabric Tag Extensions (v0) Test Mod",
"version": "1.0.0",
"environment": "*",
"license": "Apache-2.0",
"depends": {
"fabric-tag-extensions-v0": "*"
},
"entrypoints": {
"main": [
"net.fabricmc.fabric.test.tag.extension.TagExtensionTest"
],
"client": [
"net.fabricmc.fabric.test.tag.extension.TagExtensionTestClient"
]
}
}