Skip to content

Commit

Permalink
Move client extension registration to an event (#1311)
Browse files Browse the repository at this point in the history
  • Loading branch information
XFactHD authored Jul 17, 2024
1 parent 3b34ded commit 6e420c9
Show file tree
Hide file tree
Showing 19 changed files with 391 additions and 327 deletions.
31 changes: 4 additions & 27 deletions patches/net/minecraft/world/effect/MobEffect.java.patch
Original file line number Diff line number Diff line change
Expand Up @@ -9,40 +9,17 @@
public static final Codec<Holder<MobEffect>> CODEC = BuiltInRegistries.MOB_EFFECT.holderByNameCodec();
public static final StreamCodec<RegistryFriendlyByteBuf, Holder<MobEffect>> STREAM_CODEC = ByteBufCodecs.holderRegistry(Registries.MOB_EFFECT);
private static final int AMBIENT_ALPHA = Mth.floor(38.25F);
@@ -56,6 +_,7 @@
int i = p_333517_.isAmbient() ? AMBIENT_ALPHA : 255;
return ColorParticleOption.create(ParticleTypes.ENTITY_EFFECT, FastColor.ARGB32.color(i, p_19452_));
};
+ initClient();
}

protected MobEffect(MobEffectCategory p_333963_, int p_333864_, ParticleOptions p_333716_) {
@@ -179,6 +_,29 @@
@@ -179,6 +_,14 @@
@Override
public FeatureFlagSet requiredFeatures() {
return this.requiredFeatures;
+ }
+
+ // Neo: Client rendering for MobEffects
+ private Object effectRenderer;
+
+ /**
+ * Neo: DO NOT CALL, IT WILL DISAPPEAR IN THE FUTURE
+ * TODO: Replace this with a better solution
+ * Call {@link net.neoforged.neoforge.client.extensions.common.IClientMobEffectExtensions#of(MobEffect)} instead
+ * Neo: Allowing mods to define client behavior for their MobEffects
+ * @deprecated Use {@link net.neoforged.neoforge.client.extensions.common.RegisterClientExtensionsEvent} instead
+ */
+ public Object getEffectRendererInternal() {
+ return effectRenderer;
+ }
+
+ // Neo: Minecraft instance isn't available in datagen, so don't call initializeClient if in datagen
+ private void initClient() {
+ if (net.neoforged.fml.loading.FMLEnvironment.dist == net.neoforged.api.distmarker.Dist.CLIENT && !net.neoforged.neoforge.data.loading.DatagenModLoader.isRunningDataGen()) {
+ initializeClient(properties -> this.effectRenderer = properties);
+ }
+ }
+
+ // Neo: Allowing mods to define client behavior for their MobEffects
+ @Deprecated(forRemoval = true, since = "1.21")
+ public void initializeClient(java.util.function.Consumer<net.neoforged.neoforge.client.extensions.common.IClientMobEffectExtensions> consumer) {
}

Expand Down
30 changes: 5 additions & 25 deletions patches/net/minecraft/world/item/Item.java.patch
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
public static final ResourceLocation BASE_ATTACK_DAMAGE_ID = ResourceLocation.withDefaultNamespace("base_attack_damage");
public static final ResourceLocation BASE_ATTACK_SPEED_ID = ResourceLocation.withDefaultNamespace("base_attack_speed");
public static final int DEFAULT_MAX_STACK_SIZE = 64;
@@ -89,12 +_,14 @@
@@ -89,12 +_,13 @@
this.components = p_41383_.buildAndValidateComponents();
this.craftingRemainingItem = p_41383_.craftingRemainingItem;
this.requiredFeatures = p_41383_.requiredFeatures;
Expand All @@ -24,7 +24,6 @@
}
}
+ this.canRepair = p_41383_.canRepair;
+ initClient();
}

@Deprecated
Expand Down Expand Up @@ -143,35 +142,16 @@
}

public ItemStack getDefaultInstance() {
@@ -341,13 +_,41 @@
@@ -341,13 +_,22 @@
return this.requiredFeatures;
}

- public static class Properties {
+ // Neo: Client rendering for Items
+ private Object renderProperties;
+
+ /**
+ * Neo: DO NOT CALL, IT WILL DISAPPEAR IN THE FUTURE
+ * TODO: Replace this with a better solution
+ * Call {@link net.neoforged.neoforge.client.extensions.common.IClientItemExtensions#of(Item)} instead
+ * Neo: Allowing mods to define client behavior for their Items
+ * @deprecated Use {@link net.neoforged.neoforge.client.extensions.common.RegisterClientExtensionsEvent} instead
+ */
+ public Object getRenderPropertiesInternal() {
+ return renderProperties;
+ }
+
+ // Neo: Minecraft instance isn't available in datagen, so don't call initializeClient if in datagen
+ private void initClient() {
+ if (net.neoforged.fml.loading.FMLEnvironment.dist == net.neoforged.api.distmarker.Dist.CLIENT && !net.neoforged.neoforge.data.loading.DatagenModLoader.isRunningDataGen()) {
+ initializeClient(properties -> {
+ if (properties == this)
+ throw new IllegalStateException("Don't extend IItemRenderProperties in your item, use an anonymous class instead.");
+ this.renderProperties = properties;
+ });
+ }
+ }
+
+ // Neo: Allowing mods to define client behavior for their Items
+ @Deprecated(forRemoval = true, since = "1.21")
+ public void initializeClient(java.util.function.Consumer<net.neoforged.neoforge.client.extensions.common.IClientItemExtensions> consumer) {
+ }
+
Expand Down
35 changes: 5 additions & 30 deletions patches/net/minecraft/world/level/block/Block.java.patch
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
private static final LoadingCache<VoxelShape, Boolean> SHAPE_FULL_BLOCK_CACHE = CacheBuilder.newBuilder()
.maximumSize(512L)
.weakKeys()
@@ -186,12 +_,13 @@
@@ -186,7 +_,7 @@
this.createBlockStateDefinition(builder);
this.stateDefinition = builder.create(Block::defaultBlockState, BlockState::new);
this.registerDefaultState(this.stateDefinition.any());
Expand All @@ -23,12 +23,6 @@
String s = this.getClass().getSimpleName();
if (!s.endsWith("Block")) {
LOGGER.error("Block classes should end with Block and {} doesn't.", s);
}
}
+ initClient();
}

public static boolean isExceptionForConnection(BlockState p_152464_) {
@@ -208,6 +_,8 @@
BlockState blockstate = p_152446_.getBlockState(p_152449_);
if (p_152445_.skipRendering(blockstate, p_152448_)) {
Expand Down Expand Up @@ -122,7 +116,7 @@
public boolean dropFromExplosion(Explosion p_49826_) {
return true;
}
@@ -485,6 +_,62 @@
@@ -485,6 +_,43 @@
return this.stateDefinition.getPossibleStates().stream().collect(ImmutableMap.toImmutableMap(Function.identity(), p_152459_));
}

Expand Down Expand Up @@ -154,30 +148,11 @@
+ return drops;
+ }
+
+ // Neo: Client rendering for Blocks
+ private Object renderProperties;
+
+ /**
+ * Neo: DO NOT CALL, IT WILL DISAPPEAR IN THE FUTURE
+ * TODO: Replace this with a better solution
+ * Call {@link net.neoforged.neoforge.client.extensions.common.IClientBlockExtensions#of(Block)} instead
+ * Neo: Allowing mods to define client behavior for their Blocks
+ * @deprecated Use {@link net.neoforged.neoforge.client.extensions.common.RegisterClientExtensionsEvent} instead
+ */
+ public Object getRenderPropertiesInternal() {
+ return renderProperties;
+ }
+
+ // Neo: Minecraft instance isn't available in datagen, so don't call initializeClient if in datagen
+ private void initClient() {
+ if (net.neoforged.fml.loading.FMLEnvironment.dist == net.neoforged.api.distmarker.Dist.CLIENT && !net.neoforged.neoforge.data.loading.DatagenModLoader.isRunningDataGen()) {
+ initializeClient(properties -> {
+ if (properties == this)
+ throw new IllegalStateException("Don't extend IBlockRenderProperties in your block, use an anonymous class instead.");
+ this.renderProperties = properties;
+ });
+ }
+ }
+
+ // Neo: Allowing mods to define client behavior for their Blocks
+ @Deprecated(forRemoval = true, since = "1.21")
+ public void initializeClient(java.util.function.Consumer<net.neoforged.neoforge.client.extensions.common.IClientBlockExtensions> consumer) {
+ }
+
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/net/neoforged/neoforge/client/ClientHooks.java
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@
import net.neoforged.neoforge.client.event.ToastAddEvent;
import net.neoforged.neoforge.client.event.ViewportEvent;
import net.neoforged.neoforge.client.event.sound.PlaySoundEvent;
import net.neoforged.neoforge.client.extensions.common.ClientExtensionsManager;
import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions;
import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions;
import net.neoforged.neoforge.client.extensions.common.IClientMobEffectExtensions;
Expand Down Expand Up @@ -1003,6 +1004,7 @@ public static void initClientHooks(Minecraft mc, ReloadableResourceManager resou
}
initializedClientHooks = true;

ClientExtensionsManager.init();
GameTestHooks.registerGametests();
registerSpriteSourceTypes();
MenuScreens.init();
Expand Down
79 changes: 79 additions & 0 deletions src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,31 @@

package net.neoforged.neoforge.client;

import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BiomeColors;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.material.FluidState;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.client.event.ModelEvent;
import net.neoforged.neoforge.client.event.RegisterClientReloadListenersEvent;
import net.neoforged.neoforge.client.event.RegisterNamedRenderTypesEvent;
import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions;
import net.neoforged.neoforge.client.extensions.common.RegisterClientExtensionsEvent;
import net.neoforged.neoforge.client.model.CompositeModel;
import net.neoforged.neoforge.client.model.DynamicFluidContainerModel;
import net.neoforged.neoforge.client.model.ElementsModel;
import net.neoforged.neoforge.client.model.EmptyModel;
import net.neoforged.neoforge.client.model.ItemLayerModel;
import net.neoforged.neoforge.client.model.SeparateTransformsModel;
import net.neoforged.neoforge.client.model.obj.ObjLoader;
import net.neoforged.neoforge.common.NeoForgeMod;
import net.neoforged.neoforge.internal.versions.neoforge.NeoForgeVersion;

@Mod(value = "neoforge", dist = Dist.CLIENT)
public class ClientNeoForgeMod {
Expand Down Expand Up @@ -51,4 +60,74 @@ static void onRegisterReloadListeners(RegisterClientReloadListenersEvent event)
static void onRegisterNamedRenderTypes(RegisterNamedRenderTypesEvent event) {
event.register(ResourceLocation.fromNamespaceAndPath("neoforge", "item_unlit"), RenderType.translucent(), NeoForgeRenderTypes.ITEM_UNSORTED_UNLIT_TRANSLUCENT.get());
}

@SubscribeEvent
static void onRegisterClientExtensions(RegisterClientExtensionsEvent event) {
event.registerFluidType(new IClientFluidTypeExtensions() {
private static final ResourceLocation UNDERWATER_LOCATION = ResourceLocation.withDefaultNamespace("textures/misc/underwater.png");
private static final ResourceLocation WATER_STILL = ResourceLocation.withDefaultNamespace("block/water_still");
private static final ResourceLocation WATER_FLOW = ResourceLocation.withDefaultNamespace("block/water_flow");
private static final ResourceLocation WATER_OVERLAY = ResourceLocation.withDefaultNamespace("block/water_overlay");

@Override
public ResourceLocation getStillTexture() {
return WATER_STILL;
}

@Override
public ResourceLocation getFlowingTexture() {
return WATER_FLOW;
}

@Override
public ResourceLocation getOverlayTexture() {
return WATER_OVERLAY;
}

@Override
public ResourceLocation getRenderOverlayTexture(Minecraft mc) {
return UNDERWATER_LOCATION;
}

@Override
public int getTintColor() {
return 0xFF3F76E4;
}

@Override
public int getTintColor(FluidState state, BlockAndTintGetter getter, BlockPos pos) {
return BiomeColors.getAverageWaterColor(getter, pos) | 0xFF000000;
}
}, NeoForgeMod.WATER_TYPE.value());

event.registerFluidType(new IClientFluidTypeExtensions() {
private static final ResourceLocation LAVA_STILL = ResourceLocation.withDefaultNamespace("block/lava_still");
private static final ResourceLocation LAVA_FLOW = ResourceLocation.withDefaultNamespace("block/lava_flow");

@Override
public ResourceLocation getStillTexture() {
return LAVA_STILL;
}

@Override
public ResourceLocation getFlowingTexture() {
return LAVA_FLOW;
}
}, NeoForgeMod.LAVA_TYPE.value());

NeoForgeMod.MILK_TYPE.asOptional().ifPresent(milkType -> event.registerFluidType(new IClientFluidTypeExtensions() {
private static final ResourceLocation MILK_STILL = ResourceLocation.fromNamespaceAndPath(NeoForgeVersion.MOD_ID, "block/milk_still");
private static final ResourceLocation MILK_FLOW = ResourceLocation.fromNamespaceAndPath(NeoForgeVersion.MOD_ID, "block/milk_flowing");

@Override
public ResourceLocation getStillTexture() {
return MILK_STILL;
}

@Override
public ResourceLocation getFlowingTexture() {
return MILK_FLOW;
}
}, milkType));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforge.client.extensions.common;

import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
import net.neoforged.fml.ModLoader;
import net.neoforged.neoforge.data.loading.DatagenModLoader;
import net.neoforged.neoforge.fluids.FluidType;
import net.neoforged.neoforge.registries.NeoForgeRegistries;
import org.jetbrains.annotations.ApiStatus;

@ApiStatus.Internal
public final class ClientExtensionsManager {
static final Map<Block, IClientBlockExtensions> BLOCK_EXTENSIONS = new Reference2ObjectOpenHashMap<>();
static final Map<Item, IClientItemExtensions> ITEM_EXTENSIONS = new Reference2ObjectOpenHashMap<>();
static final Map<MobEffect, IClientMobEffectExtensions> MOB_EFFECT_EXTENSIONS = new Reference2ObjectOpenHashMap<>();
static final Map<FluidType, IClientFluidTypeExtensions> FLUID_TYPE_EXTENSIONS = new Reference2ObjectOpenHashMap<>();
private static boolean earlyInitialized = false;
private static boolean initialized = false;

private ClientExtensionsManager() {}

@SafeVarargs
static <T, E> void register(E extensions, Map<T, E> target, T... objects) {
if (objects.length == 0) {
throw new IllegalArgumentException("At least one target must be provided");
}
Objects.requireNonNull(extensions, "Extensions must not be null");

for (T object : objects) {
Objects.requireNonNull(objects, "Target must not be null");
E oldExtensions = target.put(object, extensions);
if (oldExtensions != null) {
throw new IllegalStateException(String.format(
Locale.ROOT,
"Duplicate client extensions registration for %s (old: %s, new: %s)",
object,
oldExtensions,
extensions));
}
}
}

@Deprecated(forRemoval = true, since = "1.21")
public static void earlyInit() {
// Minecraft instance isn't available in datagen, so don't initialize client extensions in datagen
if (DatagenModLoader.isRunningDataGen()) return;

if (earlyInitialized) {
throw new IllegalStateException("Duplicate early initialization of ClientExtensionsManager");
}

earlyInitialized = true;
BuiltInRegistries.BLOCK.forEach(block -> block.initializeClient(ext -> register(ext, BLOCK_EXTENSIONS, block)));
BuiltInRegistries.ITEM.forEach(item -> item.initializeClient(ext -> register(ext, ITEM_EXTENSIONS, item)));
BuiltInRegistries.MOB_EFFECT.forEach(mobEffect -> mobEffect.initializeClient(ext -> register(ext, MOB_EFFECT_EXTENSIONS, mobEffect)));
NeoForgeRegistries.FLUID_TYPES.forEach(fluidType -> fluidType.initializeClient(ext -> register(ext, FLUID_TYPE_EXTENSIONS, fluidType)));
}

public static void init() {
// Minecraft instance isn't available in datagen, so don't initialize client extensions in datagen
if (DatagenModLoader.isRunningDataGen()) return;

if (initialized) {
throw new IllegalStateException("Duplicate initialization of ClientExtensionsManager");
}

initialized = true;
ModLoader.postEvent(new RegisterClientExtensionsEvent());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ static IClientBlockExtensions of(BlockState state) {
}

static IClientBlockExtensions of(Block block) {
return block.getRenderPropertiesInternal() instanceof IClientBlockExtensions e ? e : DEFAULT;
return ClientExtensionsManager.BLOCK_EXTENSIONS.getOrDefault(block, DEFAULT);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ static IClientFluidTypeExtensions of(Fluid fluid) {
}

static IClientFluidTypeExtensions of(FluidType type) {
return type.getRenderPropertiesInternal() instanceof IClientFluidTypeExtensions props ? props : DEFAULT;
return ClientExtensionsManager.FLUID_TYPE_EXTENSIONS.getOrDefault(type, DEFAULT);
}

/* Default Accessors */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ static IClientItemExtensions of(ItemStack stack) {
}

static IClientItemExtensions of(Item item) {
return item.getRenderPropertiesInternal() instanceof IClientItemExtensions e ? e : DEFAULT;
return ClientExtensionsManager.ITEM_EXTENSIONS.getOrDefault(item, DEFAULT);
}

/**
Expand Down
Loading

0 comments on commit 6e420c9

Please sign in to comment.