Skip to content

Commit ad75b1b

Browse files
committed
Rewrite remaining Neo platform code in Java
- Kitchen sink code cleaned up slightly (using convenience methods from FluidTank) - DistExecutor replaced with a FMLEnvironment.dist check
1 parent b6fcd38 commit ad75b1b

File tree

76 files changed

+1310
-1095
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+1310
-1095
lines changed

common/src/main/java/juuxel/adorn/block/entity/BrewerBlockEntity.java

+3
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,10 @@ public int calculateComparatorOutput() {
125125
return MathHelper.ceil(level);
126126
}
127127

128+
/** {@return true if you can extract the fluid container as an item} */
128129
protected abstract boolean canExtractFluidContainer();
130+
131+
/** Extract the fluid from the container, if possible. */
129132
protected abstract void tryExtractFluidContainer();
130133

131134
private boolean isActive() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package juuxel.adorn.block.variant;
2+
3+
import java.util.Arrays;
4+
import java.util.List;
5+
import java.util.function.Function;
6+
7+
public abstract class CompatBlockVariantSet implements BlockVariantSet {
8+
protected abstract String getModId();
9+
10+
protected List<BlockVariant> createVariants(Function<String, BlockVariant> factory, String... variants) {
11+
return Arrays.stream(variants).map(variant -> factory.apply(getModId() + '/' + variant)).toList();
12+
}
13+
}

common/src/main/kotlin/juuxel/adorn/block/variant/BlockVariantSet.kt

+8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package juuxel.adorn.block.variant
22

3+
import java.util.function.Function
4+
35
interface BlockVariantSet {
46
val woodVariants: List<BlockVariant> get() = emptyList()
57
val stoneVariants: List<BlockVariant> get() = emptyList()
@@ -12,6 +14,12 @@ interface BlockVariantSet {
1214
// No custom sorting by default.
1315
}
1416

17+
companion object {
18+
@JvmStatic
19+
fun createVariants(prefix: String, factory: Function<String, BlockVariant>, vararg variants: String): List<BlockVariant> =
20+
variants.map { factory.apply("$prefix/$it") }
21+
}
22+
1523
fun interface CustomVariantConsumer {
1624
fun add(variant: BlockVariant, kinds: List<BlockKind>)
1725
}

common/src/main/kotlin/juuxel/adorn/item/group/AdornItemGroups.kt

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import net.minecraft.util.DyeColor
2222
import net.minecraft.util.Util
2323

2424
object AdornItemGroups {
25+
@JvmField
2526
val ITEM_GROUPS: Registrar<ItemGroup> = RegistrarFactory.get().create(RegistryKeys.ITEM_GROUP)
2627

2728
// Block kinds for each vanilla item group

common/src/main/kotlin/juuxel/adorn/menu/AdornMenus.kt

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import net.minecraft.registry.RegistryKeys
1010
import net.minecraft.resource.featuretoggle.FeatureFlags
1111

1212
object AdornMenus {
13+
@JvmField
1314
val MENUS = RegistrarFactory.get().create(RegistryKeys.SCREEN_HANDLER)
1415
val DRAWER: MenuType<DrawerMenu> by MENUS.register("drawer") { createType(DrawerMenu::load) }
1516
val KITCHEN_CUPBOARD: MenuType<KitchenCupboardMenu> by MENUS.register("kitchen_cupboard") { createType(KitchenCupboardMenu::load) }

common/src/main/kotlin/juuxel/adorn/platform/ItemGroupBridge.kt

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ interface ItemGroupBridge {
1313
@InlineServices
1414
companion object {
1515
private val instance: ItemGroupBridge by lazy { loadService() }
16+
17+
@JvmStatic
1618
fun get(): ItemGroupBridge = instance
1719
}
1820
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package juuxel.adorn.platform.forge;
2+
3+
import juuxel.adorn.AdornCommon;
4+
import juuxel.adorn.block.variant.BlockVariantSets;
5+
import juuxel.adorn.config.ConfigManager;
6+
import juuxel.adorn.criterion.AdornCriteria;
7+
import juuxel.adorn.item.group.AdornItemGroups;
8+
import juuxel.adorn.lib.AdornStats;
9+
import juuxel.adorn.lib.registry.Registrar;
10+
import juuxel.adorn.loot.AdornLootConditionTypes;
11+
import juuxel.adorn.loot.AdornLootFunctionTypes;
12+
import juuxel.adorn.menu.AdornMenus;
13+
import juuxel.adorn.platform.forge.client.AdornClient;
14+
import juuxel.adorn.platform.forge.compat.Compat;
15+
import juuxel.adorn.platform.forge.event.ItemEvents;
16+
import juuxel.adorn.platform.forge.networking.AdornNetworking;
17+
import juuxel.adorn.platform.forge.registrar.ForgeRegistrar;
18+
import juuxel.adorn.recipe.AdornRecipes;
19+
import net.neoforged.api.distmarker.Dist;
20+
import net.neoforged.bus.api.IEventBus;
21+
import net.neoforged.fml.ModLoadingContext;
22+
import net.neoforged.fml.common.Mod;
23+
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
24+
import net.neoforged.fml.loading.FMLEnvironment;
25+
import net.neoforged.neoforge.common.NeoForgeMod;
26+
27+
@Mod(AdornCommon.NAMESPACE)
28+
public final class Adorn {
29+
public Adorn() {
30+
var modBus = ModLoadingContext.get().getActiveContainer().getEventBus();
31+
ConfigManager.get().init();
32+
modBus.addListener(this::init);
33+
new EventsImplementedInJava().register(modBus);
34+
AdornItemGroups.init();
35+
registerToBus(AdornItemGroups.ITEM_GROUPS, modBus);
36+
AdornRecipes.init();
37+
registerToBus(AdornMenus.MENUS, modBus);
38+
registerToBus(AdornRecipes.RECIPE_SERIALIZERS, modBus);
39+
registerToBus(AdornRecipes.RECIPE_TYPES, modBus);
40+
registerToBus(AdornLootConditionTypes.LOOT_CONDITION_TYPES, modBus);
41+
registerToBus(AdornLootFunctionTypes.LOOT_FUNCTION_TYPES, modBus);
42+
modBus.addListener(AdornNetworking::register);
43+
AdornCriteria.init();
44+
registerToBus(AdornCriteria.CRITERIA, modBus);
45+
ItemEvents.register(modBus);
46+
modBus.addListener(AdornCapabilities::register);
47+
Compat.init(modBus);
48+
BlockVariantSets.register();
49+
NeoForgeMod.enableMilkFluid();
50+
51+
if (FMLEnvironment.dist == Dist.CLIENT) {
52+
AdornClient.init(modBus);
53+
}
54+
}
55+
56+
private void registerToBus(Registrar<?> registrar, IEventBus modBus) {
57+
((ForgeRegistrar<?>) registrar).hook(modBus);
58+
}
59+
60+
private void init(FMLCommonSetupEvent event) {
61+
AdornStats.init();
62+
ConfigManager.get().finalize();
63+
}
64+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package juuxel.adorn.platform.forge;
2+
3+
import juuxel.adorn.block.AdornBlockEntities;
4+
import juuxel.adorn.block.variant.BlockKind;
5+
import juuxel.adorn.block.variant.BlockVariantSets;
6+
import juuxel.adorn.platform.forge.block.entity.BlockEntityWithFluidTank;
7+
import net.minecraft.block.entity.BlockEntity;
8+
import net.minecraft.inventory.Inventory;
9+
import net.minecraft.inventory.SidedInventory;
10+
import net.minecraft.util.math.Direction;
11+
import net.neoforged.neoforge.capabilities.Capabilities;
12+
import net.neoforged.neoforge.capabilities.IBlockCapabilityProvider;
13+
import net.neoforged.neoforge.capabilities.ICapabilityProvider;
14+
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent;
15+
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
16+
import net.neoforged.neoforge.items.IItemHandler;
17+
import net.neoforged.neoforge.items.wrapper.InvWrapper;
18+
import net.neoforged.neoforge.items.wrapper.SidedInvWrapper;
19+
import org.jetbrains.annotations.Nullable;
20+
21+
public final class AdornCapabilities {
22+
private static final IBlockCapabilityProvider<IItemHandler, @Nullable Direction> INVENTORY_WRAPPER_FOR_BLOCK =
23+
(world, pos, state, blockEntity, side) -> blockEntity instanceof Inventory inventory ? getInventoryWrapper(inventory, side) : null;
24+
private static final ICapabilityProvider<BlockEntity, @Nullable Direction, IItemHandler> INVENTORY_WRAPPER_FOR_BLOCK_ENTITY =
25+
(blockEntity, side) -> blockEntity instanceof Inventory inventory ? getInventoryWrapper(inventory, side) : null;
26+
private static final IBlockCapabilityProvider<IFluidHandler, @Nullable Direction> FLUID_TANK_FOR_BLOCK =
27+
(world, pos, state, blockEntity, side) -> blockEntity instanceof BlockEntityWithFluidTank withTank ? withTank.getTank() : null;
28+
private static final ICapabilityProvider<BlockEntity, @Nullable Direction, IFluidHandler> FLUID_TANK_FOR_BLOCK_ENTITY =
29+
(blockEntity, side) -> blockEntity instanceof BlockEntityWithFluidTank withTank ? withTank.getTank() : null;
30+
31+
public static void register(RegisterCapabilitiesEvent event) {
32+
event.registerBlockEntity(Capabilities.ItemHandler.BLOCK, AdornBlockEntities.BREWER.get(), INVENTORY_WRAPPER_FOR_BLOCK_ENTITY);
33+
34+
var containerBlockKinds = new BlockKind[] {
35+
BlockKind.DRAWER,
36+
BlockKind.KITCHEN_CUPBOARD,
37+
BlockKind.SHELF,
38+
};
39+
40+
for (var kind : containerBlockKinds) {
41+
for (var block : BlockVariantSets.get(kind)) {
42+
event.registerBlock(Capabilities.ItemHandler.BLOCK, INVENTORY_WRAPPER_FOR_BLOCK, block.get());
43+
}
44+
}
45+
46+
event.registerBlockEntity(Capabilities.FluidHandler.BLOCK, AdornBlockEntities.BREWER.get(), FLUID_TANK_FOR_BLOCK_ENTITY);
47+
48+
for (var kitchenSink : BlockVariantSets.get(BlockKind.KITCHEN_SINK)) {
49+
event.registerBlock(Capabilities.FluidHandler.BLOCK, FLUID_TANK_FOR_BLOCK, kitchenSink.get());
50+
}
51+
}
52+
53+
private static IItemHandler getInventoryWrapper(Inventory inventory, @Nullable Direction side) {
54+
return side != null && inventory instanceof SidedInventory sided ? new SidedInvWrapper(sided, side) : new InvWrapper(inventory);
55+
}
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package juuxel.adorn.platform.forge;
2+
3+
import juuxel.adorn.block.entity.BrewerBlockEntity;
4+
import juuxel.adorn.block.entity.KitchenSinkBlockEntity;
5+
import juuxel.adorn.platform.BlockEntityBridge;
6+
import juuxel.adorn.platform.forge.block.entity.BrewerBlockEntityForge;
7+
import juuxel.adorn.platform.forge.block.entity.KitchenSinkBlockEntityForge;
8+
import net.minecraft.block.BlockState;
9+
import net.minecraft.util.math.BlockPos;
10+
11+
public final class BlockEntityBridgeForge implements BlockEntityBridge {
12+
public static final BlockEntityBridgeForge INSTANCE = new BlockEntityBridgeForge();
13+
14+
@Override
15+
public BrewerBlockEntity createBrewer(BlockPos pos, BlockState state) {
16+
return new BrewerBlockEntityForge(pos, state);
17+
}
18+
19+
@Override
20+
public KitchenSinkBlockEntity createKitchenSink(BlockPos pos, BlockState state) {
21+
return new KitchenSinkBlockEntityForge(pos, state);
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package juuxel.adorn.platform.forge;
2+
3+
import juuxel.adorn.block.SofaBlock;
4+
import juuxel.adorn.block.variant.BlockVariant;
5+
import juuxel.adorn.platform.BlockFactory;
6+
import juuxel.adorn.platform.forge.block.SofaBlockForge;
7+
8+
public final class BlockFactoryImpl implements BlockFactory {
9+
public static final BlockFactoryImpl INSTANCE = new BlockFactoryImpl();
10+
11+
@Override
12+
public SofaBlock createSofa(BlockVariant variant) {
13+
return new SofaBlockForge(variant);
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package juuxel.adorn.platform.forge;
2+
3+
import juuxel.adorn.config.ConfigManager;
4+
import net.neoforged.fml.loading.FMLPaths;
5+
6+
import java.nio.file.Path;
7+
8+
public final class ConfigManagerImpl extends ConfigManager {
9+
@Override
10+
protected Path getConfigDirectory() {
11+
return FMLPaths.CONFIGDIR.get();
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package juuxel.adorn.platform.forge;
2+
3+
import juuxel.adorn.AdornCommon;
4+
import juuxel.adorn.entity.SeatEntity;
5+
import juuxel.adorn.platform.EntityBridge;
6+
import net.minecraft.entity.EntityType;
7+
import net.minecraft.entity.SpawnGroup;
8+
9+
public final class EntityBridgeImpl implements EntityBridge {
10+
public static final EntityBridgeImpl INSTANCE = new EntityBridgeImpl();
11+
12+
@Override
13+
public EntityType<SeatEntity> createSeatType() {
14+
return EntityType.Builder.create(SeatEntity::new, SpawnGroup.MISC)
15+
.setDimensions(0, 0)
16+
.build(AdornCommon.NAMESPACE + ":seat");
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package juuxel.adorn.platform.forge;
2+
3+
import juuxel.adorn.fluid.FluidAmountPredicate;
4+
import juuxel.adorn.fluid.FluidUnit;
5+
import juuxel.adorn.fluid.FluidVolume;
6+
import juuxel.adorn.platform.FluidBridge;
7+
import juuxel.adorn.platform.forge.util.FluidTankReference;
8+
import net.minecraft.block.BlockState;
9+
import net.minecraft.fluid.Fluid;
10+
import net.minecraft.util.math.BlockPos;
11+
import net.minecraft.util.math.Direction;
12+
import net.minecraft.world.World;
13+
import net.neoforged.neoforge.capabilities.Capabilities;
14+
import net.neoforged.neoforge.fluids.FluidStack;
15+
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
16+
import org.jetbrains.annotations.Nullable;
17+
18+
public final class FluidBridgeForge implements FluidBridge {
19+
@Override
20+
public FluidUnit getFluidUnit() {
21+
return FluidUnit.LITRE;
22+
}
23+
24+
@Nullable
25+
@Override
26+
public FluidVolume drain(World world, BlockPos pos, @Nullable BlockState state, Direction side, Fluid fluid, FluidAmountPredicate amountPredicate) {
27+
// This method is a port of the Fabric fluid bridge code.
28+
var fluidHandler = world.getCapability(Capabilities.FluidHandler.BLOCK, pos, state, null, side);
29+
30+
if (fluidHandler != null) {
31+
var upperBound = amountPredicate.getUpperBound();
32+
int maxAmount = (int) FluidUnit.convert(upperBound.getAmount(), upperBound.getUnit(), FluidUnit.LITRE);
33+
var max = new FluidStack(fluid, maxAmount);
34+
var extracted = fluidHandler.drain(max, IFluidHandler.FluidAction.SIMULATE);
35+
36+
if (!extracted.isEmpty() && amountPredicate.test(extracted.getAmount(), FluidUnit.LITRE)) {
37+
fluidHandler.drain(extracted, IFluidHandler.FluidAction.EXECUTE);
38+
return FluidTankReference.toFluidVolume(extracted);
39+
}
40+
}
41+
42+
return null;
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package juuxel.adorn.platform.forge;
2+
3+
import com.mojang.datafixers.util.Pair;
4+
import juuxel.adorn.item.group.ItemGroupModifyContext;
5+
import juuxel.adorn.platform.ItemGroupBridge;
6+
import kotlin.Unit;
7+
import kotlin.jvm.functions.Function1;
8+
import net.minecraft.item.ItemConvertible;
9+
import net.minecraft.item.ItemGroup;
10+
import net.minecraft.item.ItemStack;
11+
import net.minecraft.registry.RegistryKey;
12+
import net.neoforged.bus.api.SubscribeEvent;
13+
import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent;
14+
15+
import java.util.ArrayList;
16+
import java.util.List;
17+
18+
public final class ItemGroupBridgeForge implements ItemGroupBridge {
19+
private static final ItemGroup.StackVisibility DEFAULT_STACK_VISIBILITY = ItemGroup.StackVisibility.PARENT_AND_SEARCH_TABS;
20+
private final List<Pair<RegistryKey<ItemGroup>, Function1<? super ItemGroupModifyContext, Unit>>> additions = new ArrayList<>();
21+
22+
@Override
23+
public ItemGroup.Builder builder() {
24+
return ItemGroup.builder();
25+
}
26+
27+
@Override
28+
public void addItems(RegistryKey<ItemGroup> group, Function1<? super ItemGroupModifyContext, Unit> configurator) {
29+
additions.add(new Pair<>(group, configurator));
30+
}
31+
32+
@SubscribeEvent
33+
public void addToGroups(BuildCreativeModeTabContentsEvent event) {
34+
for (var entry : additions) {
35+
var group = entry.getFirst();
36+
var configurator = entry.getSecond();
37+
var context = new ItemGroupModifyContext() {
38+
@Override
39+
public void add(ItemConvertible item) {
40+
if (event.getTabKey().equals(group)) {
41+
event.add(item);
42+
}
43+
}
44+
45+
@Override
46+
public void addAfter(ItemConvertible after, List<? extends ItemConvertible> items) {
47+
if (event.getTabKey().equals(group)) {
48+
var afterStack = new ItemStack(after);
49+
for (ItemConvertible item : items) {
50+
var stack = new ItemStack(item);
51+
event.getEntries().putAfter(afterStack, stack, DEFAULT_STACK_VISIBILITY);
52+
afterStack = stack;
53+
}
54+
}
55+
}
56+
};
57+
configurator.invoke(context);
58+
}
59+
}
60+
}

0 commit comments

Comments
 (0)