Update to 1.19

This commit is contained in:
shedaniel
2022-06-08 21:35:41 +08:00
parent 551edceb82
commit c77f040c21
33 changed files with 635 additions and 451 deletions

View File

@@ -1,59 +0,0 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021, 2022 architectury
*
* This program 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; either
* version 3 of the License, or (at your option) any later version.
*
* This program 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 program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package dev.architectury.core;
import com.google.common.reflect.TypeToken;
import dev.architectury.injectables.annotations.PlatformOnly;
import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
/**
* An entry in registries, will implement methods from {@code IForgeRegistryEntry}.
*/
public class RegistryEntry<T> {
private final TypeToken<T> token = new TypeToken<T>(getClass()) {
};
private ResourceLocation registryName = null;
@ApiStatus.Internal
@PlatformOnly(PlatformOnly.FORGE)
public T setRegistryName(ResourceLocation name) {
if (registryName != null) {
throw new IllegalStateException("Tried to override registry name from previous " + registryName + " to " + name);
}
registryName = name;
return (T) this;
}
@Nullable
@ApiStatus.Internal
@PlatformOnly(PlatformOnly.FORGE)
public ResourceLocation getRegistryName() {
return registryName;
}
@ApiStatus.Internal
@PlatformOnly(PlatformOnly.FORGE)
public Class<T> getRegistryType() {
return (Class<T>) token.getRawType();
}
}

View File

@@ -22,17 +22,23 @@ package dev.architectury.event.events.client;
import dev.architectury.event.CompoundEventResult;
import dev.architectury.event.Event;
import dev.architectury.event.EventFactory;
import dev.architectury.event.EventResult;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.chat.ClientChatPreview;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.network.chat.ChatSender;
import net.minecraft.network.chat.ChatType;
import net.minecraft.network.chat.Component;
import org.jetbrains.annotations.Nullable;
import java.util.function.Function;
@Environment(EnvType.CLIENT)
public interface ClientChatEvent {
/**
* @see Process#process(ChatType, Component, ChatSender)
* @see Process#process(ChatProcessor)
*/
Event<Process> PROCESS = EventFactory.createCompoundEventResult();
/**
@@ -46,11 +52,22 @@ public interface ClientChatEvent {
* Event to modify the chat message a clients sends.
* Equivalent to Forge's {@code ClientChatEvent} event.
*
* @param message The chat message the client wants to send.
* @return A {@link CompoundEventResult} determining the outcome of the event,
* @param processor The chat message the client wants to send.
* @return A {@link EventResult} determining the outcome of the event,
* if an outcome is set, the sent message is overridden.
*/
CompoundEventResult<Component> process(ChatType chatType, Component message, @Nullable ChatSender sender);
EventResult process(ChatProcessor processor);
}
interface ChatProcessor {
String getMessage();
@Nullable
Component getComponent();
void setMessage(String message);
void setComponent(@Nullable Component component);
}
@Environment(EnvType.CLIENT)

View File

@@ -19,6 +19,7 @@
package dev.architectury.hooks.level.biome;
import dev.architectury.injectables.annotations.ExpectPlatform;
import net.minecraft.core.Holder;
import net.minecraft.sounds.Music;
import net.minecraft.sounds.SoundEvent;
@@ -91,7 +92,7 @@ public final class BiomeHooks {
GenerationProperties.Mutable generationProperties,
SpawnProperties.Mutable spawnProperties) {
this(biome,
new ClimateWrapped(biome.climateSettings),
new ClimateWrapped(extractClimateSettings(biome)),
new EffectsWrapped(biome.getSpecialEffects()),
generationProperties,
spawnProperties);
@@ -130,11 +131,17 @@ public final class BiomeHooks {
}
}
@ExpectPlatform
private static Biome.ClimateSettings extractClimateSettings(Biome biome) {
return null;
}
public static class ClimateWrapped implements ClimateProperties.Mutable {
protected final Biome.ClimateSettings climateSettings;
public ClimateWrapped(Biome biome) {
this(biome.climateSettings);
this(extractClimateSettings(biome));
}
public ClimateWrapped(Biome.ClimateSettings climateSettings) {

View File

@@ -0,0 +1,60 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021, 2022 architectury
*
* This program 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; either
* version 3 of the License, or (at your option) any later version.
*
* This program 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 program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package dev.architectury.impl;
import dev.architectury.event.events.client.ClientChatEvent;
import net.minecraft.network.chat.Component;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
@ApiStatus.Internal
public class ChatProcessorImpl implements ClientChatEvent.ChatProcessor {
private String message;
@Nullable
private Component component;
public ChatProcessorImpl(String message, @Nullable Component component) {
this.message = message;
this.component = component;
}
@Override
public String getMessage() {
return message;
}
@Override
@Nullable
public Component getComponent() {
return component;
}
@Override
public void setMessage(String message) {
this.message = Objects.requireNonNull(message);
}
@Override
public void setComponent(@Nullable Component component) {
this.component = component;
}
}

View File

@@ -24,6 +24,7 @@ import dev.architectury.hooks.level.biome.BiomeProperties;
import dev.architectury.injectables.annotations.ExpectPlatform;
import net.minecraft.resources.ResourceLocation;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Predicate;
@@ -86,7 +87,7 @@ public final class BiomeModifications {
}
public interface BiomeContext {
ResourceLocation getKey();
Optional<ResourceLocation> getKey();
BiomeProperties getProperties();
}

View File

@@ -19,8 +19,10 @@
package dev.architectury.registry.registries;
import com.google.common.base.MoreObjects;
import dev.architectury.injectables.annotations.ExpectPlatform;
import net.minecraft.core.Registry;
import net.minecraft.data.BuiltinRegistries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.ApiStatus;
@@ -80,9 +82,10 @@ public final class Registries {
* Fabric: Use registry
*/
@Nullable
@ExpectPlatform
public static <T> ResourceLocation getId(T object, @Nullable ResourceKey<Registry<T>> fallback) {
throw new AssertionError();
if (fallback == null)
return null;
return getId(object, (Registry<T>) MoreObjects.firstNonNull(Registry.REGISTRY.get(fallback.location()), BuiltinRegistries.REGISTRY.get(fallback.location())));
}
/**
@@ -91,19 +94,10 @@ public final class Registries {
*/
@Nullable
@Deprecated
@ExpectPlatform
public static <T> ResourceLocation getId(T object, @Nullable Registry<T> fallback) {
throw new AssertionError();
}
/**
* Forge: If the object is {@code IForgeRegistryEntry}, use `getRegistryName`, else null
* Fabric: null
*/
@Nullable
@Deprecated
public static <T> ResourceLocation getRegistryName(T object) {
return getId(object, (ResourceKey<Registry<T>>) null);
if (fallback == null)
return null;
return fallback.getKey(object);
}
@ExpectPlatform

View File

@@ -57,7 +57,6 @@ transitive-accessible class net/minecraft/world/inventory/MenuType$MenuSupplier
accessible method net/minecraft/world/entity/Entity getEncodeId ()Ljava/lang/String;
accessible field net/minecraft/server/packs/repository/PackRepository sources Ljava/util/Set;
mutable field net/minecraft/server/packs/repository/PackRepository sources Ljava/util/Set;
accessible field net/minecraft/world/level/biome/Biome climateSettings Lnet/minecraft/world/level/biome/Biome$ClimateSettings;
accessible field net/minecraft/world/level/biome/Biome$ClimateSettings precipitation Lnet/minecraft/world/level/biome/Biome$Precipitation;
mutable field net/minecraft/world/level/biome/Biome$ClimateSettings precipitation Lnet/minecraft/world/level/biome/Biome$Precipitation;
accessible field net/minecraft/world/level/biome/Biome$ClimateSettings temperature F
@@ -90,6 +89,18 @@ accessible field net/minecraft/world/level/biome/BiomeSpecialEffects ambientAddi
mutable field net/minecraft/world/level/biome/BiomeSpecialEffects ambientAdditionsSettings Ljava/util/Optional;
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects backgroundMusic Ljava/util/Optional;
mutable field net/minecraft/world/level/biome/BiomeSpecialEffects backgroundMusic Ljava/util/Optional;
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects$Builder fogColor Ljava/util/OptionalInt;
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects$Builder waterColor Ljava/util/OptionalInt;
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects$Builder waterFogColor Ljava/util/OptionalInt;
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects$Builder skyColor Ljava/util/OptionalInt;
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects$Builder foliageColorOverride Ljava/util/Optional;
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects$Builder grassColorOverride Ljava/util/Optional;
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects$Builder grassColorModifier Lnet/minecraft/world/level/biome/BiomeSpecialEffects$GrassColorModifier;
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects$Builder ambientParticle Ljava/util/Optional;
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects$Builder ambientLoopSoundEvent Ljava/util/Optional;
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects$Builder ambientMoodSettings Ljava/util/Optional;
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects$Builder ambientAdditionsSettings Ljava/util/Optional;
accessible field net/minecraft/world/level/biome/BiomeSpecialEffects$Builder backgroundMusic Ljava/util/Optional;
accessible field net/minecraft/world/level/biome/BiomeGenerationSettings$Builder features Ljava/util/List;
accessible field net/minecraft/world/level/biome/MobSpawnSettings$Builder spawners Ljava/util/Map;
accessible field net/minecraft/world/level/biome/MobSpawnSettings$Builder mobSpawnCosts Ljava/util/Map;

View File

@@ -109,6 +109,7 @@ curseforge {
changelogType = "html"
changelog = releaseChangelog()
addGameVersion "1.19"
addGameVersion "1.19-Snapshot"
addGameVersion "Java 17"
addGameVersion "Fabric"
relations {
@@ -138,7 +139,7 @@ modrinth {
versionName = "[Fabric $rootProject.supported_version] v$project.version"
changelog = releaseChangelog()
uploadFile = remapJar
gameVersions = ["1.19-pre1"]
gameVersions = ["1.19"]
loaders = ["fabric", "quilt"]
dependencies {
// TODO: move to slugs if that functionality becomes available in minotaur

View File

@@ -17,13 +17,13 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package dev.architectury.core;
package dev.architectury.hooks.level.biome.fabric;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeSerializer;
import dev.architectury.mixin.fabric.BiomeAccessor;
import net.minecraft.world.level.biome.Biome;
/**
* The equivalent of {@link RecipeSerializer} to use in common that has forge registry entries extended.
*/
public abstract class AbstractRecipeSerializer<T extends Recipe<?>> extends RegistryEntry<RecipeSerializer<?>> implements RecipeSerializer<T> {
public class BiomeHooksImpl {
public static Biome.ClimateSettings extractClimateSettings(Biome biome) {
return ((BiomeAccessor) (Object) biome).getClimateSettings();
}
}

View File

@@ -17,12 +17,14 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package dev.architectury.mixin.forge;
package dev.architectury.mixin.fabric;
import dev.architectury.core.RegistryEntry;
import net.minecraftforge.registries.IForgeRegistryEntry;
import net.minecraft.world.level.biome.Biome;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(RegistryEntry.class)
public abstract class MixinRegistryEntry<T> implements IForgeRegistryEntry<T> {
@Mixin(Biome.class)
public interface BiomeAccessor {
@Accessor("climateSettings")
Biome.ClimateSettings getClimateSettings();
}

View File

@@ -76,37 +76,6 @@ public class MixinClientPacketListener {
this.tmpPlayer = null;
}
@Inject(method = "handleSystemChat", at = @At(value = "INVOKE",
target = "Lnet/minecraft/client/gui/Gui;handleSystemChat(Lnet/minecraft/network/chat/ChatType;Lnet/minecraft/network/chat/Component;)V"),
cancellable = true)
private void handleChat(ClientboundSystemChatPacket packet, CallbackInfo ci) {
var registry = this.level.registryAccess().registryOrThrow(Registry.CHAT_TYPE_REGISTRY);
var chatType = packet.resolveType(registry);
var process = ClientChatEvent.RECEIVED.invoker().process(chatType, packet.content(), null);
if (process.isEmpty()) return;
if (process.isFalse()) {
ci.cancel();
} else if (process.object() != null && !process.object().equals(packet.content())) {
this.minecraft.gui.handleSystemChat(chatType, packet.content());
ci.cancel();
}
}
@Inject(method = "handlePlayerChat(Lnet/minecraft/network/chat/ChatType;Lnet/minecraft/network/chat/PlayerChatMessage;Lnet/minecraft/network/chat/ChatSender;)V", at = @At(value = "INVOKE",
target = "Lnet/minecraft/client/gui/Gui;handlePlayerChat(Lnet/minecraft/network/chat/ChatType;Lnet/minecraft/network/chat/Component;Lnet/minecraft/network/chat/ChatSender;)V"),
cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD)
private void handleChat(ChatType chatType, PlayerChatMessage playerChatMessage, ChatSender sender, CallbackInfo ci, boolean showSigned, PlayerInfo playerInfo, Component component) {
var registry = this.level.registryAccess().registryOrThrow(Registry.CHAT_TYPE_REGISTRY);
var process = ClientChatEvent.RECEIVED.invoker().process(chatType, component, sender);
if (process.isEmpty()) return;
if (process.isFalse()) {
ci.cancel();
} else if (process.object() != null && !process.object().equals(component)) {
this.minecraft.gui.handlePlayerChat(chatType, component, sender);
ci.cancel();
}
}
@Inject(method = "handleUpdateRecipes", at = @At("RETURN"))
private void handleUpdateRecipes(ClientboundUpdateRecipesPacket clientboundUpdateRecipesPacket, CallbackInfo ci) {
ClientRecipeUpdateEvent.EVENT.invoker().update(recipeManager);

View File

@@ -52,7 +52,7 @@ public abstract class MixinGui {
chatSender = null;
return message;
}
var process = ClientChatEvent.PROCESS.invoker().process(chatType, message, chatSender);
var process = ClientChatEvent.RECEIVED.invoker().process(chatType, message, chatSender);
if (process.isPresent()) {
if (process.isFalse())
return EventChatDecorator.CANCELLING_COMPONENT;
@@ -82,7 +82,7 @@ public abstract class MixinGui {
chatType = null;
return message;
}
var process = ClientChatEvent.PROCESS.invoker().process(chatType, message, null);
var process = ClientChatEvent.RECEIVED.invoker().process(chatType, message, null);
if (process.isPresent()) {
if (process.isFalse())
return EventChatDecorator.CANCELLING_COMPONENT;

View File

@@ -0,0 +1,72 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021, 2022 architectury
*
* This program 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; either
* version 3 of the License, or (at your option) any later version.
*
* This program 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 program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package dev.architectury.mixin.fabric.client;
import com.mojang.authlib.GameProfile;
import dev.architectury.event.CompoundEventResult;
import dev.architectury.event.EventResult;
import dev.architectury.event.events.client.ClientChatEvent;
import dev.architectury.impl.ChatProcessorImpl;
import dev.architectury.impl.fabric.EventChatDecorator;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MessageSigner;
import net.minecraft.world.entity.player.ProfilePublicKey;
import org.jetbrains.annotations.Nullable;
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.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Objects;
@Mixin(LocalPlayer.class)
public abstract class MixinLocalPlayer extends AbstractClientPlayer {
public MixinLocalPlayer(ClientLevel clientLevel, GameProfile gameProfile, @Nullable ProfilePublicKey profilePublicKey) {
super(clientLevel, gameProfile, profilePublicKey);
}
@Shadow
protected abstract void sendChat(MessageSigner messageSigner, String string, @Nullable Component component);
@Inject(method = "chat(Ljava/lang/String;Lnet/minecraft/network/chat/Component;)V", at = @At(value = "HEAD"), cancellable = true)
private void chat(String message, Component component, CallbackInfo ci) {
ChatProcessorImpl processor = new ChatProcessorImpl(message, component);
EventResult process = ClientChatEvent.PROCESS.invoker().process(processor);
if (process.isPresent()) {
if (process.isFalse())
ci.cancel();
else {
String processorMessage = processor.getMessage();
Component processorComponent = processor.getComponent();
if (!Objects.equals(processorMessage, message) || !Objects.equals(processorComponent, component)) {
MessageSigner messageSigner = MessageSigner.create(this.getUUID());
this.sendChat(messageSigner, processorMessage, processorComponent);
ci.cancel();
}
}
}
}
}

View File

@@ -101,8 +101,8 @@ public class BiomeModificationsImpl {
BiomeProperties properties = BiomeHooks.getBiomeProperties(context.getBiome());
@Override
public ResourceLocation getKey() {
return context.getBiomeKey().location();
public Optional<ResourceLocation> getKey() {
return Optional.ofNullable(context.getBiomeKey().location());
}
@Override

View File

@@ -67,18 +67,6 @@ public class RegistriesImpl {
return new RegistryProviderImpl(modId);
}
public static <T> ResourceLocation getId(T object, ResourceKey<Registry<T>> fallback) {
if (fallback == null)
return null;
return getId(object, (Registry<T>) MoreObjects.firstNonNull(Registry.REGISTRY.get(fallback.location()), BuiltinRegistries.REGISTRY.get(fallback.location())));
}
public static <T> ResourceLocation getId(T object, Registry<T> fallback) {
if (fallback == null)
return null;
return fallback.getKey(object);
}
public static class RegistryProviderImpl implements Registries.RegistryProvider {
private final String modId;

View File

@@ -15,6 +15,7 @@
"client.MixinGui",
"client.MixinIntegratedServer",
"client.MixinKeyboardHandler",
"client.MixinLocalPlayer",
"client.MixinMinecraft",
"client.MixinMouseHandler",
"client.MixinMultiPlayerGameMode",
@@ -22,6 +23,7 @@
"client.MixinTextureAtlas"
],
"mixins": [
"BiomeAccessor",
"BucketItemAccessor",
"ExplosionPreInvoker",
"HorseTameInvoker",

View File

@@ -148,7 +148,7 @@ modrinth {
versionName = "[Forge $rootProject.supported_version] v$project.version"
changelog = releaseChangelog()
uploadFile = remapJar
gameVersions = ["1.19-pre1"]
gameVersions = ["1.19"]
loaders = ["forge"]
dependencies {
}

View File

@@ -32,6 +32,7 @@ import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.material.Fluid;
import net.minecraftforge.fluids.FluidAttributes;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.registries.ForgeRegistries;
class ArchitecturyFluidAttributesForge extends FluidAttributes {
private final ArchitecturyFluidAttributes attributes;
@@ -40,7 +41,7 @@ class ArchitecturyFluidAttributesForge extends FluidAttributes {
public ArchitecturyFluidAttributesForge(Builder builder, Fluid fluid, ArchitecturyFluidAttributes attributes) {
super(addArchIntoBuilder(builder, attributes), fluid);
this.attributes = attributes;
this.defaultTranslationKey = Util.makeDescriptionId("fluid", fluid.getRegistryName());
this.defaultTranslationKey = Util.makeDescriptionId("fluid", ForgeRegistries.FLUIDS.getKey(fluid));
}
private static Builder addArchIntoBuilder(Builder builder, ArchitecturyFluidAttributes attributes) {

View File

@@ -21,9 +21,11 @@ package dev.architectury.event.forge;
import com.mojang.blaze3d.vertex.PoseStack;
import dev.architectury.event.CompoundEventResult;
import dev.architectury.event.EventResult;
import dev.architectury.event.events.client.ClientChatEvent;
import dev.architectury.event.events.client.*;
import dev.architectury.event.events.common.InteractionEvent;
import dev.architectury.impl.ChatProcessorImpl;
import dev.architectury.impl.ScreenAccessImpl;
import dev.architectury.impl.TooltipEventColorContextImpl;
import dev.architectury.impl.TooltipEventPositionContextImpl;
@@ -59,7 +61,7 @@ public class EventHandlerImplClient {
@SubscribeEvent(priority = EventPriority.HIGH)
public static void event(RenderGameOverlayEvent.Post event) {
if (event.getType() == RenderGameOverlayEvent.ElementType.ALL)
ClientGuiEvent.RENDER_HUD.invoker().renderHud(event.getMatrixStack(), event.getPartialTicks());
ClientGuiEvent.RENDER_HUD.invoker().renderHud(event.getPoseStack(), event.getPartialTick());
}
@SubscribeEvent(priority = EventPriority.HIGH)
@@ -99,18 +101,24 @@ public class EventHandlerImplClient {
@SubscribeEvent(priority = EventPriority.HIGH)
public static void event(net.minecraftforge.client.event.ClientChatEvent event) {
CompoundEventResult<String> process = ClientChatEvent.PROCESS.invoker().process(event.getMessage());
ChatProcessorImpl processor = new ChatProcessorImpl(event.getMessage(), null);
EventResult process = ClientChatEvent.PROCESS.invoker().process(processor);
if (process.isPresent()) {
if (process.isFalse())
event.setCanceled(true);
else if (process.object() != null)
event.setMessage(process.object());
else {
event.setMessage(processor.getMessage());
if (process.isTrue()) {
event.setCanceled(true);
}
}
}
}
@SubscribeEvent(priority = EventPriority.HIGH)
public static void event(ClientChatReceivedEvent event) {
CompoundEventResult<Component> process = ClientChatEvent.RECEIVED.invoker().process(event.getType(), event.getMessage(), event.getSenderUUID());
CompoundEventResult<Component> process = ClientChatEvent.RECEIVED.invoker().process(event.getType(), event.getMessage(), event.getChatSender());
if (process.isPresent()) {
if (process.isFalse())
event.setCanceled(true);
@@ -140,14 +148,14 @@ public class EventHandlerImplClient {
@SubscribeEvent(priority = EventPriority.HIGH)
public static void event(ScreenEvent.DrawScreenEvent.Pre event) {
if (ClientGuiEvent.RENDER_PRE.invoker().render(event.getScreen(), event.getPoseStack(), event.getMouseX(), event.getMouseY(), event.getPartialTicks()).isFalse()) {
if (ClientGuiEvent.RENDER_PRE.invoker().render(event.getScreen(), event.getPoseStack(), event.getMouseX(), event.getMouseY(), event.getPartialTick()).isFalse()) {
event.setCanceled(true);
}
}
@SubscribeEvent(priority = EventPriority.HIGH)
public static void event(ScreenEvent.DrawScreenEvent.Post event) {
ClientGuiEvent.RENDER_POST.invoker().render(event.getScreen(), event.getPoseStack(), event.getMouseX(), event.getMouseY(), event.getPartialTicks());
ClientGuiEvent.RENDER_POST.invoker().render(event.getScreen(), event.getPoseStack(), event.getMouseX(), event.getMouseY(), event.getPartialTick());
}
@SubscribeEvent(priority = EventPriority.HIGH)

View File

@@ -25,10 +25,8 @@ import dev.architectury.event.events.common.PlayerEvent;
import dev.architectury.event.events.common.*;
import dev.architectury.utils.value.IntValue;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.TextFilter;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
@@ -145,7 +143,7 @@ public class EventHandlerImplCommon {
class ChatComponentImpl implements ChatEvent.ChatComponent {
@Override
public Component getRaw() {
return new TextComponent(event.getMessage());
return Component.literal(event.getMessage());
}
@Override
@@ -164,7 +162,7 @@ public class EventHandlerImplCommon {
}
}
EventResult process = ChatEvent.SERVER.invoker().process(event.getPlayer(), TextFilter.FilteredText.passThrough(event.getMessage()), new ChatComponentImpl());
EventResult process = ChatEvent.SERVER.invoker().process(event.getPlayer(), new ChatComponentImpl());
if (process.isFalse())
event.setCanceled(true);
}

View File

@@ -22,6 +22,7 @@ package dev.architectury.fluid.forge;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.material.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.registries.ForgeRegistries;
import org.jetbrains.annotations.ApiStatus;
import java.util.function.Function;
@@ -53,7 +54,7 @@ public enum FluidStackImpl implements dev.architectury.fluid.FluidStack.FluidSta
@Override
public Supplier<Fluid> getRawFluidSupplier(FluidStack object) {
return object.getRawFluid().delegate;
return ForgeRegistries.FLUIDS.getDelegateOrThrow(object.getRawFluid());
}
@Override

View File

@@ -21,6 +21,7 @@ package dev.architectury.forge;
import dev.architectury.platform.forge.EventBuses;
import dev.architectury.event.EventHandler;
import dev.architectury.registry.level.biome.forge.BiomeModificationsImpl;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
@@ -31,5 +32,6 @@ public class ArchitecturyForge {
public ArchitecturyForge() {
EventBuses.registerModEventBus(ArchitecturyForge.MOD_ID, FMLJavaModLoadingContext.get().getModEventBus());
EventHandler.init();
BiomeModificationsImpl.init();
}
}

View File

@@ -1,3 +1,22 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021, 2022 architectury
*
* This program 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; either
* version 3 of the License, or (at your option) any later version.
*
* This program 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 program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package dev.architectury.hooks.item.tool.forge;
import net.minecraft.world.item.context.UseOnContext;

View File

@@ -0,0 +1,28 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021, 2022 architectury
*
* This program 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; either
* version 3 of the License, or (at your option) any later version.
*
* This program 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 program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package dev.architectury.hooks.level.biome.forge;
import net.minecraft.world.level.biome.Biome;
public class BiomeHooksImpl {
public static Biome.ClimateSettings extractClimateSettings(Biome biome) {
return biome.getModifiedClimateSettings();
}
}

View File

@@ -36,8 +36,8 @@ import java.util.function.Supplier;
@Mixin(ClientLevel.class)
public abstract class MixinClientLevel extends Level {
protected MixinClientLevel(WritableLevelData worldInfo, ResourceKey<Level> dimension, Holder<DimensionType> dimensionType, Supplier<ProfilerFiller> profiler, boolean isRemote, boolean isDebug, long seed) {
super(worldInfo, dimension, dimensionType, profiler, isRemote, isDebug, seed);
protected MixinClientLevel(WritableLevelData arg, ResourceKey<Level> arg2, Holder<DimensionType> arg3, Supplier<ProfilerFiller> supplier, boolean bl, boolean bl2, long l, int i) {
super(arg, arg2, arg3, supplier, bl, bl2, l, i);
}
@Inject(method = "tickEntities", at = @At("HEAD"))

View File

@@ -29,6 +29,7 @@ import net.minecraft.client.renderer.texture.TextureAtlas;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleType;
import net.minecraft.util.RandomSource;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.ParticleFactoryRegisterEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
@@ -65,7 +66,7 @@ public class ParticleProviderRegistryImpl {
}
@Override
public TextureAtlasSprite get(Random random) {
public TextureAtlasSprite get(RandomSource random) {
return delegate.get(random);
}
}

View File

@@ -20,39 +20,58 @@
package dev.architectury.registry.level.biome.forge;
import com.google.common.collect.Lists;
import com.mojang.serialization.Codec;
import dev.architectury.forge.ArchitecturyForge;
import dev.architectury.hooks.level.biome.*;
import dev.architectury.platform.forge.EventBuses;
import dev.architectury.registry.level.biome.BiomeModifications.BiomeContext;
import net.minecraft.core.Holder;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.Music;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.MobCategory;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.MobSpawnSettings;
import net.minecraft.world.level.biome.*;
import net.minecraft.world.level.levelgen.GenerationStep;
import net.minecraft.world.level.levelgen.carver.ConfiguredWorldCarver;
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
import net.minecraftforge.common.world.BiomeGenerationSettingsBuilder;
import net.minecraftforge.common.world.MobSpawnSettingsBuilder;
import net.minecraftforge.event.world.BiomeLoadingEvent;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.common.world.*;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegisterEvent;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.function.BiConsumer;
import java.util.function.BiPredicate;
import java.util.function.Predicate;
@Mod.EventBusSubscriber(modid = ArchitecturyForge.MOD_ID)
public class BiomeModificationsImpl {
private static final List<Pair<Predicate<BiomeContext>, BiConsumer<BiomeContext, BiomeProperties.Mutable>>> ADDITIONS = Lists.newArrayList();
private static final List<Pair<Predicate<BiomeContext>, BiConsumer<BiomeContext, BiomeProperties.Mutable>>> POST_PROCESSING = Lists.newArrayList();
private static final List<Pair<Predicate<BiomeContext>, BiConsumer<BiomeContext, BiomeProperties.Mutable>>> REMOVALS = Lists.newArrayList();
private static final List<Pair<Predicate<BiomeContext>, BiConsumer<BiomeContext, BiomeProperties.Mutable>>> REPLACEMENTS = Lists.newArrayList();
@Nullable
private static Codec<BiomeModifierImpl> noneBiomeModCodec = null;
public static void init() {
EventBuses.onRegistered(ArchitecturyForge.MOD_ID, bus -> {
bus.<RegisterEvent>addListener(event -> {
event.register(ForgeRegistries.Keys.BIOME_MODIFIER_SERIALIZERS, registry -> {
registry.register(new ResourceLocation(ArchitecturyForge.MOD_ID, "none_biome_mod_codec"),
noneBiomeModCodec = Codec.unit(BiomeModifierImpl.INSTANCE));
});
event.register(ForgeRegistries.Keys.BIOME_MODIFIERS, registry -> {
registry.register(new ResourceLocation(ArchitecturyForge.MOD_ID, "impl"),
BiomeModifierImpl.INSTANCE);
});
});
});
}
public static void addProperties(Predicate<BiomeContext> predicate, BiConsumer<BiomeContext, BiomeProperties.Mutable> modifier) {
ADDITIONS.add(Pair.of(predicate, modifier));
@@ -70,13 +89,47 @@ public class BiomeModificationsImpl {
REPLACEMENTS.add(Pair.of(predicate, modifier));
}
private static BiomeContext wrapSelectionContext(BiomeLoadingEvent event) {
private static class BiomeModifierImpl implements BiomeModifier {
// cry about it
private static final BiomeModifierImpl INSTANCE = new BiomeModifierImpl();
@Override
public void modify(Holder<Biome> arg, Phase phase, ModifiableBiomeInfo.BiomeInfo.Builder builder) {
List<Pair<Predicate<BiomeContext>, BiConsumer<BiomeContext, BiomeProperties.Mutable>>> list = switch (phase) {
case ADD -> ADDITIONS;
case REMOVE -> REMOVALS;
case MODIFY -> REPLACEMENTS;
case AFTER_EVERYTHING -> POST_PROCESSING;
default -> null;
};
if (list == null) return;
BiomeContext biomeContext = wrapSelectionContext(arg.unwrapKey(), builder);
BiomeProperties.Mutable mutableBiome = new MutableBiomeWrapped(builder);
for (var pair : list) {
if (pair.getLeft().test(biomeContext)) {
pair.getRight().accept(biomeContext, mutableBiome);
}
}
}
@Override
public Codec<? extends BiomeModifier> codec() {
if (noneBiomeModCodec != null) {
return noneBiomeModCodec;
} else {
return Codec.unit(INSTANCE);
}
}
}
private static BiomeContext wrapSelectionContext(Optional<ResourceKey<Biome>> biomeResourceKey, ModifiableBiomeInfo.BiomeInfo.Builder event) {
return new BiomeContext() {
BiomeProperties properties = new BiomeWrapped(event);
@Override
public ResourceLocation getKey() {
return event.getName();
public Optional<ResourceLocation> getKey() {
return biomeResourceKey.map(ResourceKey::location);
}
@Override
@@ -87,22 +140,22 @@ public class BiomeModificationsImpl {
}
public static class BiomeWrapped implements BiomeProperties {
protected final BiomeLoadingEvent event;
protected final ModifiableBiomeInfo.BiomeInfo.Builder event;
protected final ClimateProperties climateProperties;
protected final EffectsProperties effectsProperties;
protected final GenerationProperties generationProperties;
protected final SpawnProperties spawnProperties;
public BiomeWrapped(BiomeLoadingEvent event) {
public BiomeWrapped(ModifiableBiomeInfo.BiomeInfo.Builder event) {
this(event,
new BiomeHooks.ClimateWrapped(event.getClimate()),
new BiomeHooks.EffectsWrapped(event.getEffects()),
new GenerationSettingsBuilderWrapped(event.getGeneration()),
new SpawnSettingsBuilderWrapped(event.getSpawns())
new MutableClimatePropertiesWrapped(event.getClimateSettings()),
new MutableEffectsPropertiesWrapped(event.getEffects()),
new GenerationSettingsBuilderWrapped(event.getGenerationSettings()),
new SpawnSettingsBuilderWrapped(event.getMobSpawnSettings())
);
}
public BiomeWrapped(BiomeLoadingEvent event, ClimateProperties climateProperties, EffectsProperties effectsProperties, GenerationProperties generationProperties, SpawnProperties spawnProperties) {
public BiomeWrapped(ModifiableBiomeInfo.BiomeInfo.Builder event, ClimateProperties climateProperties, EffectsProperties effectsProperties, GenerationProperties generationProperties, SpawnProperties spawnProperties) {
this.event = event;
this.climateProperties = climateProperties;
this.effectsProperties = effectsProperties;
@@ -129,11 +182,6 @@ public class BiomeModificationsImpl {
public SpawnProperties getSpawnProperties() {
return spawnProperties;
}
@Override
public Biome.BiomeCategory getCategory() {
return event.getCategory();
}
}
private static class GenerationSettingsBuilderWrapped implements GenerationProperties {
@@ -183,12 +231,12 @@ public class BiomeModificationsImpl {
}
public static class MutableBiomeWrapped extends BiomeWrapped implements BiomeProperties.Mutable {
public MutableBiomeWrapped(BiomeLoadingEvent event) {
public MutableBiomeWrapped(ModifiableBiomeInfo.BiomeInfo.Builder event) {
super(event,
new MutableClimatePropertiesWrapped(event.getClimate()),
new BiomeHooks.EffectsWrapped(event.getEffects()),
new MutableGenerationSettingsBuilderWrapped(event.getGeneration()),
new MutableSpawnSettingsBuilderWrapped(event.getSpawns())
new MutableClimatePropertiesWrapped(event.getClimateSettings()),
new MutableEffectsPropertiesWrapped(event.getEffects()),
new MutableGenerationSettingsBuilderWrapped(event.getGenerationSettings()),
new MutableSpawnSettingsBuilderWrapped(event.getMobSpawnSettings())
);
}
@@ -211,86 +259,205 @@ public class BiomeModificationsImpl {
public SpawnProperties.Mutable getSpawnProperties() {
return (SpawnProperties.Mutable) super.getSpawnProperties();
}
@Override
public Mutable setCategory(Biome.BiomeCategory category) {
event.setCategory(category);
return this;
}
}
public static class MutableClimatePropertiesWrapped implements ClimateProperties.Mutable {
public Biome.Precipitation precipitation;
public ClimateSettingsBuilder builder;
public float temperature;
public Biome.TemperatureModifier temperatureModifier;
public float downfall;
public boolean dirty;
public MutableClimatePropertiesWrapped(Biome.ClimateSettings settings) {
this(settings.precipitation,
settings.temperature,
settings.temperatureModifier,
settings.downfall);
}
public MutableClimatePropertiesWrapped(Biome.Precipitation precipitation, float temperature, Biome.TemperatureModifier temperatureModifier, float downfall) {
this.precipitation = precipitation;
this.temperature = temperature;
this.temperatureModifier = temperatureModifier;
this.downfall = downfall;
public MutableClimatePropertiesWrapped(ClimateSettingsBuilder builder) {
this.builder = builder;
}
@Override
public Biome.Precipitation getPrecipitation() {
return precipitation;
return builder.getPrecipitation();
}
@Override
public float getTemperature() {
return temperature;
return builder.getTemperature();
}
@Override
public Biome.TemperatureModifier getTemperatureModifier() {
return temperatureModifier;
return builder.getTemperatureModifier();
}
@Override
public float getDownfall() {
return downfall;
return builder.getDownfall();
}
@Override
public Mutable setPrecipitation(Biome.Precipitation precipitation) {
this.precipitation = precipitation;
this.dirty = true;
this.builder.setPrecipitation(precipitation);
return this;
}
@Override
public Mutable setTemperature(float temperature) {
this.temperature = temperature;
this.dirty = true;
this.builder.setTemperature(temperature);
return this;
}
@Override
public Mutable setTemperatureModifier(Biome.TemperatureModifier temperatureModifier) {
this.temperatureModifier = temperatureModifier;
this.dirty = true;
this.builder.setTemperatureModifier(temperatureModifier);
return this;
}
@Override
public Mutable setDownfall(float downfall) {
this.downfall = downfall;
this.dirty = true;
this.builder.setDownfall(downfall);
return this;
}
}
public static class MutableEffectsPropertiesWrapped implements EffectsProperties.Mutable {
public BiomeSpecialEffects.Builder builder;
public MutableEffectsPropertiesWrapped(BiomeSpecialEffects.Builder builder) {
this.builder = builder;
}
@Override
public int getFogColor() {
if (builder instanceof BiomeSpecialEffectsBuilder b) return b.getFogColor();
return builder.fogColor.orElse(-1);
}
@Override
public int getWaterColor() {
if (builder instanceof BiomeSpecialEffectsBuilder b) return b.getWaterFogColor();
return builder.waterColor.orElse(-1);
}
@Override
public int getWaterFogColor() {
if (builder instanceof BiomeSpecialEffectsBuilder b) return b.getWaterFogColor();
return builder.waterFogColor.orElse(-1);
}
@Override
public int getSkyColor() {
if (builder instanceof BiomeSpecialEffectsBuilder b) return b.getSkyColor();
return builder.skyColor.orElse(-1);
}
@Override
public OptionalInt getFoliageColorOverride() {
return builder.foliageColorOverride.map(OptionalInt::of).orElseGet(OptionalInt::empty);
}
@Override
public OptionalInt getGrassColorOverride() {
return builder.grassColorOverride.map(OptionalInt::of).orElseGet(OptionalInt::empty);
}
@Override
public BiomeSpecialEffects.GrassColorModifier getGrassColorModifier() {
return builder.grassColorModifier;
}
@Override
public Optional<AmbientParticleSettings> getAmbientParticle() {
return builder.ambientParticle;
}
@Override
public Optional<SoundEvent> getAmbientLoopSound() {
return builder.ambientLoopSoundEvent;
}
@Override
public Optional<AmbientMoodSettings> getAmbientMoodSound() {
return builder.ambientMoodSettings;
}
@Override
public Optional<AmbientAdditionsSettings> getAmbientAdditionsSound() {
return builder.ambientAdditionsSettings;
}
@Override
public Optional<Music> getBackgroundMusic() {
return builder.backgroundMusic;
}
@Override
public Mutable setFogColor(int color) {
builder.fogColor(color);
return this;
}
@Override
public Mutable setWaterColor(int color) {
builder.waterColor(color);
return this;
}
@Override
public Mutable setWaterFogColor(int color) {
builder.waterFogColor(color);
return this;
}
@Override
public Mutable setSkyColor(int color) {
builder.skyColor(color);
return this;
}
@Override
public Mutable setFoliageColorOverride(@Nullable Integer colorOverride) {
builder.foliageColorOverride = Optional.ofNullable(colorOverride);
return this;
}
@Override
public Mutable setGrassColorOverride(@Nullable Integer colorOverride) {
builder.foliageColorOverride = Optional.ofNullable(colorOverride);
return this;
}
@Override
public Mutable setGrassColorModifier(BiomeSpecialEffects.GrassColorModifier modifier) {
builder.grassColorModifier(modifier);
return this;
}
@Override
public Mutable setAmbientParticle(@Nullable AmbientParticleSettings settings) {
builder.ambientParticle = Optional.ofNullable(settings);
return this;
}
@Override
public Mutable setAmbientLoopSound(@Nullable SoundEvent sound) {
builder.ambientLoopSoundEvent = Optional.ofNullable(sound);
return this;
}
@Override
public Mutable setAmbientMoodSound(@Nullable AmbientMoodSettings settings) {
builder.ambientMoodSettings = Optional.ofNullable(settings);
return this;
}
@Override
public Mutable setAmbientAdditionsSound(@Nullable AmbientAdditionsSettings settings) {
builder.ambientAdditionsSettings = Optional.ofNullable(settings);
return this;
}
@Override
public Mutable setBackgroundMusic(@Nullable Music music) {
builder.backgroundMusic = Optional.ofNullable(music);
return this;
}
}
private static class MutableGenerationSettingsBuilderWrapped extends GenerationSettingsBuilderWrapped implements GenerationProperties.Mutable {
public MutableGenerationSettingsBuilderWrapped(BiomeGenerationSettingsBuilder generation) {
super(generation);
@@ -367,41 +534,4 @@ public class BiomeModificationsImpl {
return this;
}
}
@SubscribeEvent(priority = EventPriority.HIGH)
public static void processAdditions(BiomeLoadingEvent event) {
modifyBiome(event, ADDITIONS);
}
@SubscribeEvent(priority = EventPriority.NORMAL)
public static void processRemovals(BiomeLoadingEvent event) {
modifyBiome(event, REMOVALS);
}
@SubscribeEvent(priority = EventPriority.LOW)
public static void processReplacements(BiomeLoadingEvent event) {
modifyBiome(event, REPLACEMENTS);
}
@SubscribeEvent(priority = EventPriority.LOWEST)
public static void postProcessBiomes(BiomeLoadingEvent event) {
modifyBiome(event, POST_PROCESSING);
}
private static void modifyBiome(BiomeLoadingEvent event, List<Pair<Predicate<BiomeContext>, BiConsumer<BiomeContext, BiomeProperties.Mutable>>> list) {
BiomeContext biomeContext = wrapSelectionContext(event);
BiomeProperties.Mutable mutableBiome = new MutableBiomeWrapped(event);
for (var pair : list) {
if (pair.getLeft().test(biomeContext)) {
pair.getRight().accept(biomeContext, mutableBiome);
}
}
MutableClimatePropertiesWrapped climateProperties = (MutableClimatePropertiesWrapped) mutableBiome.getClimateProperties();
if (climateProperties.dirty) {
event.setClimate(new Biome.ClimateSettings(climateProperties.precipitation,
climateProperties.temperature,
climateProperties.temperatureModifier,
climateProperties.downfall));
}
}
}

View File

@@ -34,9 +34,6 @@ import net.minecraft.core.Registry;
import net.minecraft.data.BuiltinRegistries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.Block;
import net.minecraftforge.common.world.ForgeWorldPreset;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.eventbus.api.SubscribeEvent;
@@ -62,33 +59,24 @@ public class RegistriesImpl {
return new RegistryProviderImpl(modId);
}
public static <T> ResourceLocation getId(T t, ResourceKey<net.minecraft.core.Registry<T>> registryKey) {
if (t instanceof IForgeRegistryEntry)
return ((IForgeRegistryEntry<?>) t).getRegistryName();
return null;
}
public static <T> ResourceLocation getId(T t, net.minecraft.core.Registry<T> registry) {
if (t instanceof IForgeRegistryEntry)
return ((IForgeRegistryEntry<?>) t).getRegistryName();
return null;
}
public static class Data {
private boolean collected = false;
private final Map<RegistryObject<?>, Supplier<? extends IForgeRegistryEntry<?>>> objects = new LinkedHashMap<>();
private final Map<ResourceLocation, Supplier<?>> vanillaObjects = new LinkedHashMap<>();
public static class Data<T> {
private boolean registered = false;
private final Map<ResourceLocation, Supplier<? extends T>> objects = new LinkedHashMap<>();
public void register(IForgeRegistry registry, RegistryObject object, Supplier<? extends IForgeRegistryEntry<?>> reference) {
if (!collected) {
objects.put(object, reference);
public void registerForForge(IForgeRegistry<T> registry, ResourceLocation location, Object[] objectArr, Supplier<? extends T> reference) {
if (!registered) {
objects.put(location, () -> {
T value = reference.get();
objectArr[0] = value;
return value;
});
} else {
ResourceKey<? extends Registry<Object>> resourceKey = ResourceKey.createRegistryKey(registry.getRegistryName());
IForgeRegistryEntry<?> value = reference.get();
registry.register(value);
object.updateReference(registry);
T value = reference.get();
registry.register(location, value);
objectArr[0] = value;
RegistryEntryId<?> registryEntryId = new RegistryEntryId<>(resourceKey, object.getId());
RegistryEntryId<?> registryEntryId = new RegistryEntryId<>(resourceKey, location);
for (Consumer<?> consumer : LISTENERS.get(registryEntryId)) {
((Consumer<Object>) consumer).accept(value);
}
@@ -96,14 +84,14 @@ public class RegistriesImpl {
}
}
public <T> void register(Registry<T> registry, ResourceLocation id, Supplier<? extends T> reference) {
if (!collected) {
vanillaObjects.put(id, reference);
public void register(Registry<T> registry, ResourceLocation location, Supplier<? extends T> reference) {
if (!registered) {
objects.put(location, reference);
} else {
T value = reference.get();
Registry.register(registry, id, value);
Registry.register(registry, location, value);
RegistryEntryId<?> registryEntryId = new RegistryEntryId<>(registry.key(), id);
RegistryEntryId<?> registryEntryId = new RegistryEntryId<>(registry.key(), location);
for (Consumer<?> consumer : LISTENERS.get(registryEntryId)) {
((Consumer<Object>) consumer).accept(value);
}
@@ -139,7 +127,7 @@ public class RegistriesImpl {
private static final Map<ResourceKey<Registry<?>>, Registrar<?>> CUSTOM_REGS = new HashMap<>();
private final String modId;
private final Supplier<IEventBus> eventBus;
private final Map<ResourceKey<? extends Registry<?>>, Data> registry = new HashMap<>();
private final Map<ResourceKey<? extends Registry<?>>, Data<?>> registry = new HashMap<>();
private final Multimap<ResourceKey<Registry<?>>, Consumer<Registrar<?>>> listeners = HashMultimap.create();
record RegistryBuilderEntry(RegistryBuilder<?> builder, Consumer<IForgeRegistry<?>> forgeRegistry) {
@@ -165,9 +153,9 @@ public class RegistriesImpl {
}
@Override
public <T> Registrar<T> get(ResourceKey<net.minecraft.core.Registry<T>> registryKey) {
public <T> Registrar<T> get(ResourceKey<Registry<T>> registryKey) {
updateEventBus();
ForgeRegistry registry = RegistryManager.ACTIVE.getRegistry(registryKey.location());
ForgeRegistry<T> registry = RegistryManager.ACTIVE.getRegistry(registryKey.location());
if (registry == null) {
Registry<T> ts = (Registry<T>) Registry.REGISTRY.get(registryKey.location());
if (ts == null) ts = (Registry<T>) BuiltinRegistries.REGISTRY.get(registryKey.location());
@@ -181,19 +169,19 @@ public class RegistriesImpl {
return get(registry);
}
public <T> Registrar<T> get(IForgeRegistry registry) {
public <T> Registrar<T> get(IForgeRegistry<T> registry) {
updateEventBus();
return new ForgeBackedRegistryImpl<>(modId, this.registry, registry);
}
@Override
public <T> Registrar<T> get(net.minecraft.core.Registry<T> registry) {
public <T> Registrar<T> get(Registry<T> registry) {
updateEventBus();
return new VanillaBackedRegistryImpl<>(modId, this.registry, registry);
}
@Override
public <T> void forRegistry(ResourceKey<net.minecraft.core.Registry<T>> key, Consumer<Registrar<T>> consumer) {
public <T> void forRegistry(ResourceKey<Registry<T>> key, Consumer<Registrar<T>> consumer) {
this.listeners.put((ResourceKey<net.minecraft.core.Registry<?>>) (ResourceKey<? extends net.minecraft.core.Registry<?>>) key,
(Consumer<Registrar<?>>) (Consumer<? extends Registrar<?>>) consumer);
}
@@ -201,128 +189,73 @@ public class RegistriesImpl {
@Override
public <T> RegistrarBuilder<T> builder(Class<T> type, ResourceLocation registryId) {
return new RegistryBuilderWrapper<>(this, new net.minecraftforge.registries.RegistryBuilder<>()
.setName(registryId)
.setType((Class) type), registryId);
.setName(registryId), registryId);
}
public class EventListener {
public void handleVanillaRegistries() {
for (Registry<?> vanillaRegistry : Registry.REGISTRY) {
if (RegistryManager.ACTIVE.getRegistry(vanillaRegistry.key().location()) == null) {
// Must be vanilla
Registrar<?> archRegistry = get(vanillaRegistry);
for (Map.Entry<ResourceKey<? extends Registry<?>>, Data> typeDataEntry : RegistryProviderImpl.this.registry.entrySet()) {
ResourceKey<? extends Registry<?>> resourceKey = archRegistry.key();
if (typeDataEntry.getKey().equals(resourceKey)) {
Data data = typeDataEntry.getValue();
data.collected = true;
for (Map.Entry<ResourceLocation, Supplier<?>> entry : data.vanillaObjects.entrySet()) {
Object value = entry.getValue().get();
Registry.register((Registry<Object>) vanillaRegistry, entry.getKey(), value);
RegistryEntryId<?> registryEntryId = new RegistryEntryId<>(resourceKey, entry.getKey());
for (Consumer<?> consumer : LISTENERS.get(registryEntryId)) {
((Consumer<Object>) consumer).accept(value);
}
LISTENERS.removeAll(registryEntryId);
}
data.objects.clear();
}
}
for (Map.Entry<ResourceKey<net.minecraft.core.Registry<?>>, Consumer<Registrar<?>>> entry : listeners.entries()) {
if (entry.getKey().equals(vanillaRegistry.key())) {
entry.getValue().accept(archRegistry);
}
}
}
}
}
public void handleVanillaRegistriesPost() {
for (Registry<?> vanillaRegistry : Registry.REGISTRY) {
if (RegistryManager.ACTIVE.getRegistry(vanillaRegistry.key().location()) == null) {
// Must be vanilla
Registrar<?> archRegistry = get(vanillaRegistry);
List<RegistryEntryId<?>> toRemove = new ArrayList<>();
for (Map.Entry<RegistryEntryId<?>, Collection<Consumer<?>>> entry : LISTENERS.asMap().entrySet()) {
if (entry.getKey().registryKey.equals(archRegistry.key())) {
if (vanillaRegistry.containsKey(entry.getKey().id)) {
Object value = vanillaRegistry.get(entry.getKey().id);
for (Consumer<?> consumer : entry.getValue()) {
((Consumer<Object>) consumer).accept(value);
}
toRemove.add(entry.getKey());
} else {
LOGGER.warn("Registry entry listened {} was not realized!", entry.getKey());
}
}
}
for (RegistryEntryId<?> entryId : toRemove) {
LISTENERS.removeAll(entryId);
}
}
}
}
@SubscribeEvent
public void handleEvent(RegistryEvent.Register event) {
if (event.getGenericType() == Block.class) {
handleVanillaRegistries();
public void handleEvent(RegisterEvent event) {
for (Map.Entry<ResourceKey<? extends Registry<?>>, Data<?>> typeDataEntry : RegistryProviderImpl.this.registry.entrySet()) {
if (typeDataEntry.getKey().equals(event.getRegistryKey())) {
//noinspection rawtypes
registerFor(event, (ResourceKey) typeDataEntry.getKey(), typeDataEntry.getValue());
}
}
IForgeRegistry registry = event.getRegistry();
Registrar<Object> archRegistry = get(registry);
for (Map.Entry<ResourceKey<? extends Registry<?>>, Data> typeDataEntry : RegistryProviderImpl.this.registry.entrySet()) {
ResourceKey<? extends Registry<Object>> resourceKey = archRegistry.key();
if (typeDataEntry.getKey().equals(resourceKey)) {
Data data = typeDataEntry.getValue();
}
public <T> void registerFor(RegisterEvent event, ResourceKey<? extends Registry<T>> resourceKey, Data<T> data) {
event.register(resourceKey, registry -> {
data.registered = true;
for (Map.Entry<ResourceLocation, Supplier<? extends T>> entry : data.objects.entrySet()) {
ResourceLocation location = entry.getKey();
T value = entry.getValue().get();
registry.register(location, value);
data.collected = true;
for (Map.Entry<RegistryObject<?>, Supplier<? extends IForgeRegistryEntry<?>>> entry : data.objects.entrySet()) {
IForgeRegistryEntry<?> value = entry.getValue().get();
registry.register(value);
entry.getKey().updateReference(registry);
RegistryEntryId<?> registryEntryId = new RegistryEntryId<>(resourceKey, entry.getKey().getId());
for (Consumer<?> consumer : LISTENERS.get(registryEntryId)) {
((Consumer<Object>) consumer).accept(value);
}
LISTENERS.removeAll(registryEntryId);
RegistryEntryId<?> registryEntryId = new RegistryEntryId<>(resourceKey, location);
for (Consumer<?> consumer : LISTENERS.get(registryEntryId)) {
((Consumer<Object>) consumer).accept(value);
}
data.objects.clear();
LISTENERS.removeAll(registryEntryId);
}
}
for (Map.Entry<ResourceKey<net.minecraft.core.Registry<?>>, Consumer<Registrar<?>>> entry : listeners.entries()) {
if (entry.getKey().location().equals(registry.getRegistryName())) {
entry.getValue().accept(archRegistry);
data.objects.clear();
Registrar<Object> archRegistry;
if (event.getForgeRegistry() != null) {
archRegistry = get(event.getForgeRegistry());
} else if (event.getVanillaRegistry() != null) {
archRegistry = get(event.getVanillaRegistry());
} else {
LOGGER.error("Unable to find registry from RegisterEvent as both vanilla and forge registries are null! " + event.getRegistryKey());
return;
}
}
for (Map.Entry<ResourceKey<net.minecraft.core.Registry<?>>, Consumer<Registrar<?>>> entry : listeners.entries()) {
if (entry.getKey().location().equals(resourceKey.location())) {
entry.getValue().accept(archRegistry);
}
}
});
}
@SubscribeEvent(priority = EventPriority.LOWEST)
public void handleEventPost(RegistryEvent.Register event) {
if (event.getGenericType() == ForgeWorldPreset.class) {
handleVanillaRegistriesPost();
public void handleEventPost(RegisterEvent event) {
Registrar<Object> archRegistry;
if (event.getForgeRegistry() != null) {
archRegistry = get(event.getForgeRegistry());
} else if (event.getVanillaRegistry() != null) {
archRegistry = get(event.getVanillaRegistry());
} else {
LOGGER.error("Unable to find registry from RegisterEvent as both vanilla and forge registries are null! " + event.getRegistryKey());
return;
}
IForgeRegistry registry = event.getRegistry();
Registrar<Object> archRegistry = get(registry);
ResourceKey<? extends Registry<Object>> resourceKey = archRegistry.key();
List<RegistryEntryId<?>> toRemove = new ArrayList<>();
for (Map.Entry<RegistryEntryId<?>, Collection<Consumer<?>>> entry : LISTENERS.asMap().entrySet()) {
if (entry.getKey().registryKey.equals(resourceKey)) {
if (registry.containsKey(entry.getKey().id)) {
IForgeRegistryEntry value = registry.getValue(entry.getKey().id);
if (entry.getKey().registryKey.equals(event.getRegistryKey())) {
if (archRegistry.contains(entry.getKey().id)) {
Object value = archRegistry.get(entry.getKey().id);
for (Consumer<?> consumer : entry.getValue()) {
((Consumer<Object>) consumer).accept(value);
}
@@ -332,6 +265,7 @@ public class RegistriesImpl {
}
}
}
for (RegistryEntryId<?> id : toRemove) {
LISTENERS.removeAll(id);
}
@@ -341,7 +275,8 @@ public class RegistriesImpl {
public void handleEvent(NewRegistryEvent event) {
if (builders != null) {
for (RegistryBuilderEntry builder : builders) {
event.create((RegistryBuilder) builder.builder(), (Consumer) builder.forgeRegistry());
//noinspection rawtypes
event.create((RegistryBuilder<?>) builder.builder(), (Consumer) builder.forgeRegistry());
}
builders = null;
}
@@ -370,13 +305,14 @@ public class RegistriesImpl {
throw new IllegalStateException("Cannot create registries when registries are already aggregated!");
}
final var registrarRef = new Registrar<?>[1];
var registrar = new DelegatedRegistrar(provider.modId, () -> java.util.Objects.requireNonNull(registrarRef[0], "Registry not yet initialized!"), registryId);
var registrar = (DelegatedRegistrar<T>) new DelegatedRegistrar<>(provider.modId, () -> java.util.Objects.requireNonNull(registrarRef[0], "Registry not yet initialized!"), registryId);
var entry = new RegistryProviderImpl.RegistryBuilderEntry(builder, forgeRegistry -> {
registrarRef[0] = provider.get(forgeRegistry);
registrar.onRegister();
});
provider.builders.add(entry);
RegistryProviderImpl.CUSTOM_REGS.put(registrar.key(), registrar);
//noinspection rawtypes
RegistryProviderImpl.CUSTOM_REGS.put((ResourceKey) registrar.key(), registrar);
return registrar;
}
@@ -393,10 +329,10 @@ public class RegistriesImpl {
public static class VanillaBackedRegistryImpl<T> implements Registrar<T> {
private final String modId;
private net.minecraft.core.Registry<T> delegate;
private Map<ResourceKey<? extends Registry<?>>, Data> registry;
private Registry<T> delegate;
private Map<ResourceKey<? extends Registry<?>>, Data<?>> registry;
public VanillaBackedRegistryImpl(String modId, Map<ResourceKey<? extends Registry<?>>, Data> registry, net.minecraft.core.Registry<T> delegate) {
public VanillaBackedRegistryImpl(String modId, Map<ResourceKey<? extends Registry<?>>, Data<?>> registry, Registry<T> delegate) {
this.modId = modId;
this.registry = registry;
this.delegate = delegate;
@@ -406,7 +342,7 @@ public class RegistriesImpl {
public RegistrySupplier<T> delegate(ResourceLocation id) {
Supplier<T> value = Suppliers.memoize(() -> get(id));
Registrar<T> registrar = this;
return new RegistrySupplier<T>() {
return new RegistrySupplier<>() {
@Override
public Registries getRegistries() {
return Registries.get(modId);
@@ -452,15 +388,15 @@ public class RegistriesImpl {
@Override
public String toString() {
return getRegistryId().toString() + "@" + id.toString();
return getRegistryId() + "@" + id.toString();
}
};
}
@Override
public <E extends T> RegistrySupplier<E> register(ResourceLocation id, Supplier<E> supplier) {
registry.computeIfAbsent(key(), type -> new Data())
.register(delegate, id, supplier);
Data<T> data = (Data<T>) registry.computeIfAbsent(key(), type -> new Data<>());
data.register(delegate, id, supplier);
return (RegistrySupplier<E>) delegate(id);
}
@@ -512,7 +448,7 @@ public class RegistriesImpl {
}
@Override
public ResourceKey<? extends net.minecraft.core.Registry<T>> key() {
public ResourceKey<? extends Registry<T>> key() {
return delegate.key();
}
@@ -531,12 +467,12 @@ public class RegistriesImpl {
}
}
public static class ForgeBackedRegistryImpl<T extends IForgeRegistryEntry<T>> implements Registrar<T> {
public static class ForgeBackedRegistryImpl<T> implements Registrar<T> {
private final String modId;
private IForgeRegistry<T> delegate;
private Map<ResourceKey<? extends Registry<?>>, Data> registry;
private Map<ResourceKey<? extends Registry<?>>, Data<?>> registry;
public ForgeBackedRegistryImpl(String modId, Map<ResourceKey<? extends Registry<?>>, Data> registry, IForgeRegistry<T> delegate) {
public ForgeBackedRegistryImpl(String modId, Map<ResourceKey<? extends Registry<?>>, Data<?>> registry, IForgeRegistry<T> delegate) {
this.modId = modId;
this.registry = registry;
this.delegate = delegate;
@@ -546,7 +482,7 @@ public class RegistriesImpl {
public RegistrySupplier<T> delegate(ResourceLocation id) {
Supplier<T> value = Suppliers.memoize(() -> get(id));
Registrar<T> registrar = this;
return new RegistrySupplier<T>() {
return new RegistrySupplier<>() {
@Override
public Registries getRegistries() {
return Registries.get(modId);
@@ -599,11 +535,11 @@ public class RegistriesImpl {
@Override
public <E extends T> RegistrySupplier<E> register(ResourceLocation id, Supplier<E> supplier) {
RegistryObject registryObject = RegistryObject.create(id, delegate);
registry.computeIfAbsent(key(), type -> new Data())
.register(delegate, registryObject, () -> supplier.get().setRegistryName(id));
Object[] objectArr = new Object[]{null};
Data<T> data = (Data<T>) registry.computeIfAbsent(key(), type -> new Data<>());
data.registerForForge(delegate, id, objectArr, supplier);
Registrar<T> registrar = this;
return new RegistrySupplier<E>() {
return new RegistrySupplier<>() {
@Override
public Registries getRegistries() {
return Registries.get(modId);
@@ -621,17 +557,21 @@ public class RegistriesImpl {
@Override
public ResourceLocation getId() {
return registryObject.getId();
return id;
}
@Override
public boolean isPresent() {
return registryObject.isPresent();
return objectArr[0] != null;
}
@Override
public E get() {
return (E) registryObject.get();
E value = (E) objectArr[0];
if (value == null) {
throw new NullPointerException("Value missing: " + this.getId() + "@" + getRegistryId());
}
return value;
}
@Override
@@ -642,8 +582,7 @@ public class RegistriesImpl {
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof RegistrySupplier)) return false;
RegistrySupplier<?> other = (RegistrySupplier<?>) obj;
if (!(obj instanceof RegistrySupplier<?> other)) return false;
return other.getRegistryId().equals(getRegistryId()) && other.getId().equals(getId());
}
@@ -702,7 +641,7 @@ public class RegistriesImpl {
}
@Override
public ResourceKey<? extends net.minecraft.core.Registry<T>> key() {
public ResourceKey<? extends Registry<T>> key() {
return ResourceKey.createRegistryKey(delegate.getRegistryName());
}
@@ -749,7 +688,7 @@ public class RegistriesImpl {
@Override
public RegistrySupplier<T> delegate(ResourceLocation id) {
if (isReady()) return delegate.get().delegate(id);
return new RegistrySupplier<T>() {
return new RegistrySupplier<>() {
@Override
public Registries getRegistries() {
return Registries.get(modId);

View File

@@ -13,7 +13,6 @@
"MixinEntitySpawnExtension",
"MixinFallingBlockEntity",
"MixinItemExtension",
"MixinRegistryEntry",
"MixinWorldEvent"
],
"injectors": {

View File

@@ -6,7 +6,7 @@ platforms=fabric,forge
minecraft_version=1.19
supported_version=1.19
artifact_type=beta
artifact_type=release
archives_base_name=architectury
archives_base_name_snapshot=architectury-snapshot

View File

@@ -253,9 +253,9 @@ public class DebugEvents {
e.printStackTrace();
}
});
ClientChatEvent.PROCESS.register((type, message, sender) -> {
TestMod.SINK.accept("Client chat sent: " + message + " of type " + type.chat());
return CompoundEventResult.pass();
ClientChatEvent.PROCESS.register((message) -> {
TestMod.SINK.accept("Client chat sent: " + message.getMessage());
return EventResult.pass();
});
ClientChatEvent.RECEIVED.register((type, message, sender) -> {
TestMod.SINK.accept("Client chat received: " + message.getString());

View File

@@ -20,23 +20,13 @@
package dev.architectury.test.recipes;
import com.google.gson.JsonObject;
import dev.architectury.core.RegistryEntry;
import dev.architectury.platform.Platform;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.crafting.CustomRecipe;
import net.minecraft.world.item.crafting.FireworkRocketRecipe;
import net.minecraft.world.item.crafting.RecipeSerializer;
import java.util.Objects;
public class TestRecipeSerializer extends RegistryEntry<RecipeSerializer<?>> implements RecipeSerializer<CustomRecipe> {
public TestRecipeSerializer() {
if (Platform.isForge() && !Objects.equals(getRegistryType(), RecipeSerializer.class)) {
throw new IllegalStateException("getRegistryType() must be of type " + RecipeSerializer.class.getName());
}
}
public class TestRecipeSerializer implements RecipeSerializer<CustomRecipe> {
@Override
public CustomRecipe fromJson(ResourceLocation id, JsonObject json) {
return new FireworkRocketRecipe(id);

View File

@@ -19,7 +19,6 @@
package dev.architectury.test.registry;
import dev.architectury.core.RegistryEntry;
import dev.architectury.core.fluid.ArchitecturyFluidAttributes;
import dev.architectury.core.fluid.SimpleArchitecturyFluidAttributes;
import dev.architectury.core.item.ArchitecturySpawnEggItem;
@@ -66,7 +65,7 @@ import java.util.function.Supplier;
import static dev.architectury.test.TestMod.SINK;
public class TestRegistries {
public static final class TestInt extends RegistryEntry<TestInt> {
public static final class TestInt {
public final int value;
public TestInt(int value) {
@@ -122,7 +121,8 @@ public class TestRegistries {
return (Item) Class.forName(!Platform.isForge() ? "dev.architectury.core.item.ArchitecturyBucketItem" : "dev.architectury.core.item.forge.imitator.ArchitecturyBucketItem")
.getDeclaredConstructor(Supplier.class, Item.Properties.class)
.newInstance(TestRegistries.TEST_FLUID, new Item.Properties().tab(TestCreativeTabs.TEST_TAB));
} catch (InstantiationException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
} catch (InstantiationException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException |
IllegalAccessException e) {
throw new RuntimeException(e);
}
});
@@ -144,7 +144,8 @@ public class TestRegistries {
return (LiquidBlock) Class.forName(!Platform.isForge() ? "dev.architectury.core.block.ArchitecturyLiquidBlock" : "dev.architectury.core.block.forge.imitator.ArchitecturyLiquidBlock")
.getDeclaredConstructor(Supplier.class, BlockBehaviour.Properties.class)
.newInstance(TestRegistries.TEST_FLUID, BlockBehaviour.Properties.copy(Blocks.WATER).noCollission().strength(100.0F).noLootTable());
} catch (InstantiationException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
} catch (InstantiationException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException |
IllegalAccessException e) {
throw new RuntimeException(e);
}
});
@@ -155,7 +156,8 @@ public class TestRegistries {
return (FlowingFluid) Class.forName(!Platform.isForge() ? "dev.architectury.core.fluid.ArchitecturyFlowingFluid$Source" : "dev.architectury.core.fluid.forge.imitator.ArchitecturyFlowingFluid$Source")
.getDeclaredConstructor(ArchitecturyFluidAttributes.class)
.newInstance(TestRegistries.TEST_FLUID_ATTRIBUTES);
} catch (InstantiationException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
} catch (InstantiationException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException |
IllegalAccessException e) {
throw new RuntimeException(e);
}
});
@@ -166,7 +168,8 @@ public class TestRegistries {
return (FlowingFluid) Class.forName(!Platform.isForge() ? "dev.architectury.core.fluid.ArchitecturyFlowingFluid$Flowing" : "dev.architectury.core.fluid.forge.imitator.ArchitecturyFlowingFluid$Flowing")
.getDeclaredConstructor(ArchitecturyFluidAttributes.class)
.newInstance(TestRegistries.TEST_FLUID_ATTRIBUTES);
} catch (InstantiationException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
} catch (InstantiationException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException |
IllegalAccessException e) {
throw new RuntimeException(e);
}
});