mirror of
https://github.com/architectury/architectury-api.git
synced 2026-03-28 03:56:59 -05:00
Update to 1.19
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 {
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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"))
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
"MixinEntitySpawnExtension",
|
||||
"MixinFallingBlockEntity",
|
||||
"MixinItemExtension",
|
||||
"MixinRegistryEntry",
|
||||
"MixinWorldEvent"
|
||||
],
|
||||
"injectors": {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user