Compiles!
This commit is contained in:
parent
6e0f636950
commit
2b7645e231
14
build.gradle
14
build.gradle
|
|
@ -4,7 +4,7 @@ plugins {
|
||||||
id 'net.neoforged.gradle.userdev' version '7.0.80'
|
id 'net.neoforged.gradle.userdev' version '7.0.80'
|
||||||
}
|
}
|
||||||
|
|
||||||
version = '1.26'
|
version = '2.0'
|
||||||
group = 'thedarkcolour.exdeorum'
|
group = 'thedarkcolour.exdeorum'
|
||||||
base {
|
base {
|
||||||
archivesName = 'exdeorum'
|
archivesName = 'exdeorum'
|
||||||
|
|
@ -103,18 +103,18 @@ dependencies {
|
||||||
// JEI OPTIONAL
|
// JEI OPTIONAL
|
||||||
compileOnly("mezz.jei:jei-${mc_version}-common-api:${jei_version}")
|
compileOnly("mezz.jei:jei-${mc_version}-common-api:${jei_version}")
|
||||||
compileOnly("mezz.jei:jei-${mc_version}-neoforge-api:${jei_version}")
|
compileOnly("mezz.jei:jei-${mc_version}-neoforge-api:${jei_version}")
|
||||||
compileOnly("mezz.jei:jei-${mc_version}-neoforge:${jei_version}")
|
runtimeOnly("mezz.jei:jei-${mc_version}-neoforge:${jei_version}")
|
||||||
// REI OPTIONAL
|
// REI OPTIONAL todo add
|
||||||
implementation("me.shedaniel:RoughlyEnoughItems-forge:${rei_version}")
|
compileOnly("me.shedaniel:RoughlyEnoughItems-forge:${rei_version}")
|
||||||
implementation("me.shedaniel.cloth:cloth-config-neoforge:${cloth_config_version}")
|
compileOnly("me.shedaniel.cloth:cloth-config-neoforge:${cloth_config_version}")
|
||||||
implementation("curse.maven:reipc-521393:4837449")
|
//implementation("curse.maven:reipc-521393:4837449")
|
||||||
// KubeJS OPTIONAL todo add when KubeJS updates
|
// KubeJS OPTIONAL todo add when KubeJS updates
|
||||||
//implementation("dev.architectury:architectury-neoforge:${architectury_version}")
|
//implementation("dev.architectury:architectury-neoforge:${architectury_version}")
|
||||||
//implementation("dev.latvian.mods:rhino-neoforge:${rhino_version}")
|
//implementation("dev.latvian.mods:rhino-neoforge:${rhino_version}")
|
||||||
//implementation("dev.latvian.mods:kubejs-neoforge:${kubejs_version}")
|
//implementation("dev.latvian.mods:kubejs-neoforge:${kubejs_version}")
|
||||||
|
|
||||||
// ModKit DEV ONLY
|
// ModKit DEV ONLY
|
||||||
implementation('com.github.thedarkcolour:Modkit:f4039e5b6b')
|
implementation('com.github.thedarkcolour:Modkit:e9334176e0')
|
||||||
|
|
||||||
// Oculus + Embeddium OPTIONAL
|
// Oculus + Embeddium OPTIONAL
|
||||||
compileOnly('maven.modrinth:oculus:1.20.1-1.6.9')
|
compileOnly('maven.modrinth:oculus:1.20.1-1.6.9')
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ org.gradle.jvmargs=-Xmx3G
|
||||||
org.gradle.parallel=true
|
org.gradle.parallel=true
|
||||||
|
|
||||||
mc_version=1.20.4
|
mc_version=1.20.4
|
||||||
neo_version=20.4.80-beta
|
neo_version=20.4.198
|
||||||
neo_version_range=[20.4,)
|
neo_version_range=[20.4,)
|
||||||
loader_version_range=[2,)
|
loader_version_range=[2,)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,19 +18,22 @@
|
||||||
|
|
||||||
package thedarkcolour.exdeorum;
|
package thedarkcolour.exdeorum;
|
||||||
|
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.neoforged.api.distmarker.Dist;
|
||||||
import net.minecraftforge.common.ForgeMod;
|
import net.neoforged.bus.api.IEventBus;
|
||||||
import net.minecraftforge.data.loading.DatagenModLoader;
|
import net.neoforged.fml.ModList;
|
||||||
import net.minecraftforge.fml.DistExecutor;
|
import net.neoforged.fml.ModLoadingContext;
|
||||||
import net.minecraftforge.fml.ModList;
|
import net.neoforged.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.ModLoadingContext;
|
import net.neoforged.fml.config.ModConfig;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.neoforged.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
import net.minecraftforge.fml.config.ModConfig;
|
import net.neoforged.fml.loading.FMLEnvironment;
|
||||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
import net.neoforged.neoforge.common.NeoForgeMod;
|
||||||
|
import net.neoforged.neoforge.data.loading.DatagenModLoader;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import thedarkcolour.exdeorum.client.ClientHandler;
|
import thedarkcolour.exdeorum.client.ClientHandler;
|
||||||
import thedarkcolour.exdeorum.config.EConfig;
|
import thedarkcolour.exdeorum.config.EConfig;
|
||||||
|
import thedarkcolour.exdeorum.data.Data;
|
||||||
|
import thedarkcolour.exdeorum.data.ModCompatData;
|
||||||
import thedarkcolour.exdeorum.event.EventHandler;
|
import thedarkcolour.exdeorum.event.EventHandler;
|
||||||
import thedarkcolour.exdeorum.material.DefaultMaterials;
|
import thedarkcolour.exdeorum.material.DefaultMaterials;
|
||||||
import thedarkcolour.exdeorum.network.NetworkHandler;
|
import thedarkcolour.exdeorum.network.NetworkHandler;
|
||||||
|
|
@ -45,28 +48,29 @@ public class ExDeorum {
|
||||||
public static final boolean DEBUG = ModList.get().isLoaded("modkit");
|
public static final boolean DEBUG = ModList.get().isLoaded("modkit");
|
||||||
public static final boolean IS_JUNE = Calendar.getInstance().get(Calendar.MONTH) == Calendar.JUNE;
|
public static final boolean IS_JUNE = Calendar.getInstance().get(Calendar.MONTH) == Calendar.JUNE;
|
||||||
|
|
||||||
public ExDeorum() {
|
public ExDeorum(IEventBus modBus) {
|
||||||
createRegistries();
|
createRegistries(modBus);
|
||||||
NetworkHandler.register();
|
|
||||||
|
|
||||||
// Still enabled in Dev environment because KubeJS enables milk fluid
|
// Still enabled in Dev environment because KubeJS enables milk fluid
|
||||||
if (DatagenModLoader.isRunningDataGen()) {
|
if (DatagenModLoader.isRunningDataGen()) {
|
||||||
ForgeMod.enableMilkFluid();
|
NeoForgeMod.enableMilkFluid();
|
||||||
|
ModCompatData.registerModData(modBus);
|
||||||
|
modBus.addListener(Data::generateData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Game Events
|
// Game Events
|
||||||
EventHandler.register();
|
EventHandler.register(modBus);
|
||||||
// Client init
|
// Client init (todo test that this doesn't crash servers)
|
||||||
DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> ClientHandlerRegistrar::register);
|
if (FMLEnvironment.dist == Dist.CLIENT) {
|
||||||
|
ClientHandler.register(modBus);
|
||||||
|
}
|
||||||
// Config init
|
// Config init
|
||||||
ModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, EConfig.SERVER_SPEC);
|
ModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, EConfig.SERVER_SPEC);
|
||||||
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, EConfig.COMMON_SPEC);
|
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, EConfig.COMMON_SPEC);
|
||||||
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, EConfig.CLIENT_SPEC);
|
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, EConfig.CLIENT_SPEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void createRegistries() {
|
private static void createRegistries(IEventBus modBus) {
|
||||||
var modBus = FMLJavaModLoadingContext.get().getModEventBus();
|
|
||||||
|
|
||||||
EBlocks.BLOCKS.register(modBus);
|
EBlocks.BLOCKS.register(modBus);
|
||||||
EBlockEntities.BLOCK_ENTITIES.register(modBus);
|
EBlockEntities.BLOCK_ENTITIES.register(modBus);
|
||||||
EChunkGenerators.CHUNK_GENERATORS.register(modBus);
|
EChunkGenerators.CHUNK_GENERATORS.register(modBus);
|
||||||
|
|
@ -82,10 +86,4 @@ public class ExDeorum {
|
||||||
ENumberProviders.NUMBER_PROVIDERS.register(modBus);
|
ENumberProviders.NUMBER_PROVIDERS.register(modBus);
|
||||||
DefaultMaterials.registerMaterials();
|
DefaultMaterials.registerMaterials();
|
||||||
}
|
}
|
||||||
|
|
||||||
private interface ClientHandlerRegistrar {
|
|
||||||
private static void register() {
|
|
||||||
ClientHandler.register();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import thedarkcolour.exdeorum.voidworld.VoidChunkGenerator;
|
||||||
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
|
// todo test that all of these patches still work properly
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public final class ASMHooks {
|
public final class ASMHooks {
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -45,9 +45,11 @@ public abstract class AbstractCrucibleBlock extends EBlock {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getLightEmission(BlockState state, BlockGetter level, BlockPos pos) {
|
public int getLightEmission(BlockState state, BlockGetter level, BlockPos pos) {
|
||||||
if (level.getExistingBlockEntity(pos) instanceof AbstractCrucibleBlockEntity crucible) {
|
// todo look at auxiliary light manager
|
||||||
return crucible.getTank().getFluid().getFluid().getFluidType().getLightLevel();
|
//if (level.getBlockEntity(pos) instanceof AbstractCrucibleBlockEntity crucible) {
|
||||||
}
|
// return crucible.getTank().getFluid().getFluid().getFluidType().getLightLevel();
|
||||||
|
//}
|
||||||
|
//return pos == BlockPos.ZERO ? 1 : 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||||
import net.minecraft.world.level.BlockGetter;
|
import net.minecraft.world.level.BlockGetter;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.LevelReader;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.EntityBlock;
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
import net.minecraft.world.level.block.LeavesBlock;
|
import net.minecraft.world.level.block.LeavesBlock;
|
||||||
|
|
@ -70,7 +71,7 @@ public class InfestedLeavesBlock extends LeavesBlock implements EntityBlock {
|
||||||
public void setPlacedBy(Level level, BlockPos pos, BlockState pState, @Nullable LivingEntity player, ItemStack pStack) {
|
public void setPlacedBy(Level level, BlockPos pos, BlockState pState, @Nullable LivingEntity player, ItemStack pStack) {
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
if (!level.isClientSide && level.getBlockEntity(pos) instanceof InfestedLeavesBlockEntity leaves) {
|
if (!level.isClientSide && level.getBlockEntity(pos) instanceof InfestedLeavesBlockEntity leaves) {
|
||||||
leaves.setProgress(1.0f);
|
leaves.setProgress(InfestedLeavesBlockEntity.MAX_PROGRESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -89,7 +90,7 @@ public class InfestedLeavesBlock extends LeavesBlock implements EntityBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemStack getCloneItemStack(BlockState state, HitResult target, BlockGetter level, BlockPos pos, Player player) {
|
public ItemStack getCloneItemStack(BlockState state, HitResult target, LevelReader level, BlockPos pos, Player player) {
|
||||||
if (level.getBlockEntity(pos) instanceof InfestedLeavesBlockEntity leaves) {
|
if (level.getBlockEntity(pos) instanceof InfestedLeavesBlockEntity leaves) {
|
||||||
return leaves.getMimic().getCloneItemStack(target, level, pos, player);
|
return leaves.getMimic().getCloneItemStack(target, level, pos, player);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,10 +39,9 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.block.state.StateDefinition;
|
import net.minecraft.world.level.block.state.StateDefinition;
|
||||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||||
import net.minecraftforge.items.ItemStackHandler;
|
import net.neoforged.neoforge.items.ItemStackHandler;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import thedarkcolour.exdeorum.blockentity.MechanicalHammerBlockEntity;
|
import thedarkcolour.exdeorum.blockentity.MechanicalHammerBlockEntity;
|
||||||
import thedarkcolour.exdeorum.blockentity.MechanicalSieveBlockEntity;
|
|
||||||
import thedarkcolour.exdeorum.config.EConfig;
|
import thedarkcolour.exdeorum.config.EConfig;
|
||||||
import thedarkcolour.exdeorum.data.TranslationKeys;
|
import thedarkcolour.exdeorum.data.TranslationKeys;
|
||||||
import thedarkcolour.exdeorum.registry.EBlockEntities;
|
import thedarkcolour.exdeorum.registry.EBlockEntities;
|
||||||
|
|
@ -88,7 +87,7 @@ public class MechanicalHammerBlock extends EBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void playerWillDestroy(Level level, BlockPos pos, BlockState pState, Player player) {
|
public BlockState playerWillDestroy(Level level, BlockPos pos, BlockState pState, Player player) {
|
||||||
if (!level.isClientSide && player.isCreative() && level.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) {
|
if (!level.isClientSide && player.isCreative() && level.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) {
|
||||||
if (level.getBlockEntity(pos) instanceof MechanicalHammerBlockEntity sieve) {
|
if (level.getBlockEntity(pos) instanceof MechanicalHammerBlockEntity sieve) {
|
||||||
if (!sieve.inventory.getStackInSlot(MechanicalHammerBlockEntity.HAMMER_SLOT).isEmpty()) {
|
if (!sieve.inventory.getStackInSlot(MechanicalHammerBlockEntity.HAMMER_SLOT).isEmpty()) {
|
||||||
|
|
@ -101,7 +100,7 @@ public class MechanicalHammerBlock extends EBlock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.playerWillDestroy(level, pos, pState, player);
|
return super.playerWillDestroy(level, pos, pState, player);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ import net.minecraft.world.level.pathfinder.PathComputationType;
|
||||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||||
import net.minecraft.world.phys.shapes.Shapes;
|
import net.minecraft.world.phys.shapes.Shapes;
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
import net.minecraftforge.items.ItemStackHandler;
|
import net.neoforged.neoforge.items.ItemStackHandler;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import thedarkcolour.exdeorum.blockentity.MechanicalSieveBlockEntity;
|
import thedarkcolour.exdeorum.blockentity.MechanicalSieveBlockEntity;
|
||||||
import thedarkcolour.exdeorum.config.EConfig;
|
import thedarkcolour.exdeorum.config.EConfig;
|
||||||
|
|
@ -90,7 +90,7 @@ public class MechanicalSieveBlock extends EBlock {
|
||||||
|
|
||||||
// Drops the item for creative mode players
|
// Drops the item for creative mode players
|
||||||
@Override
|
@Override
|
||||||
public void playerWillDestroy(Level level, BlockPos pos, BlockState pState, Player player) {
|
public BlockState playerWillDestroy(Level level, BlockPos pos, BlockState pState, Player player) {
|
||||||
if (!level.isClientSide && player.isCreative() && level.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) {
|
if (!level.isClientSide && player.isCreative() && level.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) {
|
||||||
if (level.getBlockEntity(pos) instanceof MechanicalSieveBlockEntity sieve) {
|
if (level.getBlockEntity(pos) instanceof MechanicalSieveBlockEntity sieve) {
|
||||||
if (!sieve.getLogic().getMesh().isEmpty()) {
|
if (!sieve.getLogic().getMesh().isEmpty()) {
|
||||||
|
|
@ -103,7 +103,7 @@ public class MechanicalSieveBlock extends EBlock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.playerWillDestroy(level, pos, pState, player);
|
return super.playerWillDestroy(level, pos, pState, player);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ import net.minecraft.world.level.ServerLevelAccessor;
|
||||||
import net.minecraft.world.level.block.LiquidBlock;
|
import net.minecraft.world.level.block.LiquidBlock;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.material.FlowingFluid;
|
import net.minecraft.world.level.material.FlowingFluid;
|
||||||
import net.minecraftforge.event.ForgeEventFactory;
|
import net.neoforged.neoforge.event.EventHooks;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import thedarkcolour.exdeorum.config.EConfig;
|
import thedarkcolour.exdeorum.config.EConfig;
|
||||||
|
|
||||||
|
|
@ -70,7 +70,7 @@ public class WitchWaterBlock extends LiquidBlock {
|
||||||
zombieVillager.setTradeOffers(villager.getOffers().createTag());
|
zombieVillager.setTradeOffers(villager.getOffers().createTag());
|
||||||
zombieVillager.setVillagerXp(villager.getVillagerXp());
|
zombieVillager.setVillagerXp(villager.getVillagerXp());
|
||||||
|
|
||||||
net.minecraftforge.event.ForgeEventFactory.onLivingConvert(villager, zombieVillager);
|
EventHooks.onLivingConvert(villager, zombieVillager);
|
||||||
|
|
||||||
villager.discard();
|
villager.discard();
|
||||||
}
|
}
|
||||||
|
|
@ -123,7 +123,7 @@ public class WitchWaterBlock extends LiquidBlock {
|
||||||
if (newEntity != null) {
|
if (newEntity != null) {
|
||||||
var serverLevel = (ServerLevelAccessor) level;
|
var serverLevel = (ServerLevelAccessor) level;
|
||||||
newEntity.copyPosition(entity);
|
newEntity.copyPosition(entity);
|
||||||
ForgeEventFactory.onFinalizeSpawn(newEntity, serverLevel, level.getCurrentDifficultyAt(entity.blockPosition()), MobSpawnType.CONVERSION, null, null);
|
EventHooks.onFinalizeSpawn(newEntity, serverLevel, level.getCurrentDifficultyAt(entity.blockPosition()), MobSpawnType.CONVERSION, null, null);
|
||||||
newEntity.setNoAi(newEntity.isNoAi());
|
newEntity.setNoAi(newEntity.isNoAi());
|
||||||
|
|
||||||
if (entity.hasCustomName()) {
|
if (entity.hasCustomName()) {
|
||||||
|
|
@ -132,7 +132,7 @@ public class WitchWaterBlock extends LiquidBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
newEntity.setPersistenceRequired();
|
newEntity.setPersistenceRequired();
|
||||||
net.minecraftforge.event.ForgeEventFactory.onLivingConvert((LivingEntity) entity, newEntity);
|
EventHooks.onLivingConvert((LivingEntity) entity, newEntity);
|
||||||
serverLevel.addFreshEntityWithPassengers(newEntity);
|
serverLevel.addFreshEntityWithPassengers(newEntity);
|
||||||
entity.discard();
|
entity.discard();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@
|
||||||
package thedarkcolour.exdeorum.blockentity;
|
package thedarkcolour.exdeorum.blockentity;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
|
@ -39,17 +38,14 @@ import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.material.Fluid;
|
import net.minecraft.world.level.material.Fluid;
|
||||||
import net.minecraft.world.level.material.Fluids;
|
import net.minecraft.world.level.material.Fluids;
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
import net.neoforged.neoforge.common.util.Lazy;
|
||||||
import net.minecraftforge.common.util.Lazy;
|
import net.neoforged.neoforge.fluids.FluidStack;
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.neoforged.neoforge.fluids.FluidUtil;
|
||||||
import net.minecraftforge.fluids.FluidStack;
|
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
|
||||||
import net.minecraftforge.fluids.FluidUtil;
|
import net.neoforged.neoforge.fluids.capability.templates.FluidTank;
|
||||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
import net.neoforged.neoforge.items.IItemHandler;
|
||||||
import net.minecraftforge.fluids.capability.templates.FluidTank;
|
import net.neoforged.neoforge.items.ItemStackHandler;
|
||||||
import net.minecraftforge.items.IItemHandler;
|
|
||||||
import net.minecraftforge.items.ItemStackHandler;
|
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import thedarkcolour.exdeorum.blockentity.helper.FluidHelper;
|
import thedarkcolour.exdeorum.blockentity.helper.FluidHelper;
|
||||||
|
|
@ -61,7 +57,6 @@ import thedarkcolour.exdeorum.registry.EItems;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public abstract class AbstractCrucibleBlockEntity extends EBlockEntity {
|
public abstract class AbstractCrucibleBlockEntity extends EBlockEntity {
|
||||||
public static final Lazy<HashMap<Item, Block>> MELT_OVERRIDES = Lazy.concurrentOf(() -> {
|
public static final Lazy<HashMap<Item, Block>> MELT_OVERRIDES = Lazy.concurrentOf(() -> {
|
||||||
var map = new HashMap<Item, Block>();
|
var map = new HashMap<Item, Block>();
|
||||||
|
|
@ -73,9 +68,6 @@ public abstract class AbstractCrucibleBlockEntity extends EBlockEntity {
|
||||||
|
|
||||||
private final AbstractCrucibleBlockEntity.ItemHandler item = new AbstractCrucibleBlockEntity.ItemHandler();
|
private final AbstractCrucibleBlockEntity.ItemHandler item = new AbstractCrucibleBlockEntity.ItemHandler();
|
||||||
private final AbstractCrucibleBlockEntity.FluidHandler tank = new AbstractCrucibleBlockEntity.FluidHandler();
|
private final AbstractCrucibleBlockEntity.FluidHandler tank = new AbstractCrucibleBlockEntity.FluidHandler();
|
||||||
// Capabilities
|
|
||||||
private final LazyOptional<IItemHandler> itemHandler = LazyOptional.of(() -> this.item);
|
|
||||||
private final LazyOptional<IFluidHandler> fluidHandler = LazyOptional.of(() -> this.tank);
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private Block lastMelted;
|
private Block lastMelted;
|
||||||
|
|
@ -88,35 +80,18 @@ public abstract class AbstractCrucibleBlockEntity extends EBlockEntity {
|
||||||
super(type, pos, state);
|
super(type, pos, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
|
|
||||||
if (!this.remove) {
|
|
||||||
if (cap == ForgeCapabilities.FLUID_HANDLER) {
|
|
||||||
return this.fluidHandler.cast();
|
|
||||||
} else if (cap == ForgeCapabilities.ITEM_HANDLER) {
|
|
||||||
return this.itemHandler.cast();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.getCapability(cap, side);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateCaps() {
|
|
||||||
super.invalidateCaps();
|
|
||||||
this.fluidHandler.invalidate();
|
|
||||||
this.itemHandler.invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
// NBT
|
// NBT
|
||||||
@Override
|
@Override
|
||||||
public void saveAdditional(CompoundTag nbt) {
|
public void saveAdditional(CompoundTag nbt) {
|
||||||
super.saveAdditional(nbt);
|
super.saveAdditional(nbt);
|
||||||
|
|
||||||
nbt.put("Tank", this.tank.writeToNBT(new CompoundTag()));
|
nbt.put("Tank", this.tank.writeToNBT(new CompoundTag()));
|
||||||
nbt.putString("LastMelted", ForgeRegistries.BLOCKS.getKey(this.lastMelted).toString());
|
if (this.lastMelted != null) {
|
||||||
nbt.putString("Fluid", ForgeRegistries.FLUIDS.getKey(this.fluid).toString());
|
nbt.putString("LastMelted", BuiltInRegistries.BLOCK.getKey(this.lastMelted).toString());
|
||||||
|
}
|
||||||
|
if (this.fluid != null) {
|
||||||
|
nbt.putString("Fluid", BuiltInRegistries.FLUID.getKey(this.fluid).toString());
|
||||||
|
}
|
||||||
nbt.putShort("Solids", this.solids);
|
nbt.putShort("Solids", this.solids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -125,8 +100,8 @@ public abstract class AbstractCrucibleBlockEntity extends EBlockEntity {
|
||||||
super.load(nbt);
|
super.load(nbt);
|
||||||
|
|
||||||
this.tank.readFromNBT(nbt.getCompound("Tank"));
|
this.tank.readFromNBT(nbt.getCompound("Tank"));
|
||||||
this.lastMelted = ForgeRegistries.BLOCKS.getValue(new ResourceLocation(nbt.getString("LastMelted")));
|
this.lastMelted = BuiltInRegistries.BLOCK.get(new ResourceLocation(nbt.getString("LastMelted")));
|
||||||
this.fluid = ForgeRegistries.FLUIDS.getValue(new ResourceLocation(nbt.getString("Fluid")));
|
this.fluid = BuiltInRegistries.FLUID.get(new ResourceLocation(nbt.getString("Fluid")));
|
||||||
this.solids = nbt.getShort("Solids");
|
this.solids = nbt.getShort("Solids");
|
||||||
this.needsLightUpdate = true;
|
this.needsLightUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
@ -156,7 +131,7 @@ public abstract class AbstractCrucibleBlockEntity extends EBlockEntity {
|
||||||
public InteractionResult use(Level level, Player player, InteractionHand hand) {
|
public InteractionResult use(Level level, Player player, InteractionHand hand) {
|
||||||
var playerItem = player.getItemInHand(hand);
|
var playerItem = player.getItemInHand(hand);
|
||||||
|
|
||||||
if (playerItem.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).isPresent()) {
|
if (playerItem.getCapability(Capabilities.FluidHandler.ITEM) != null) {
|
||||||
return FluidUtil.interactWithFluidHandler(player, hand, this.tank) ? InteractionResult.sidedSuccess(level.isClientSide) : InteractionResult.PASS;
|
return FluidUtil.interactWithFluidHandler(player, hand, this.tank) ? InteractionResult.sidedSuccess(level.isClientSide) : InteractionResult.PASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -247,6 +222,10 @@ public abstract class AbstractCrucibleBlockEntity extends EBlockEntity {
|
||||||
return this.tank;
|
return this.tank;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IItemHandler getItem() {
|
||||||
|
return this.item;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract Block getDefaultMeltBlock();
|
public abstract Block getDefaultMeltBlock();
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|
@ -254,13 +233,6 @@ public abstract class AbstractCrucibleBlockEntity extends EBlockEntity {
|
||||||
return this.lastMelted;
|
return this.lastMelted;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setRemoved() {
|
|
||||||
this.itemHandler.invalidate();
|
|
||||||
this.fluidHandler.invalidate();
|
|
||||||
super.setRemoved();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void addMeltOverrides(HashMap<Item, Block> overrides) {
|
private static void addMeltOverrides(HashMap<Item, Block> overrides) {
|
||||||
overrides.put(Items.OAK_SAPLING, Blocks.OAK_LEAVES);
|
overrides.put(Items.OAK_SAPLING, Blocks.OAK_LEAVES);
|
||||||
overrides.put(Items.SPRUCE_SAPLING, Blocks.SPRUCE_LEAVES);
|
overrides.put(Items.SPRUCE_SAPLING, Blocks.SPRUCE_LEAVES);
|
||||||
|
|
@ -277,14 +249,15 @@ public abstract class AbstractCrucibleBlockEntity extends EBlockEntity {
|
||||||
overrides.put(EItems.WARPED_NYLIUM_SPORES.get(), Blocks.WARPED_NYLIUM);
|
overrides.put(EItems.WARPED_NYLIUM_SPORES.get(), Blocks.WARPED_NYLIUM);
|
||||||
overrides.put(EItems.CRIMSON_NYLIUM_SPORES.get(), Blocks.CRIMSON_NYLIUM);
|
overrides.put(EItems.CRIMSON_NYLIUM_SPORES.get(), Blocks.CRIMSON_NYLIUM);
|
||||||
|
|
||||||
for (var sapling : ForgeRegistries.BLOCKS.getEntries()) {
|
for (var sapling : BuiltInRegistries.BLOCK.entrySet()) {
|
||||||
var item = sapling.getValue().asItem();
|
var item = sapling.getValue().asItem();
|
||||||
|
|
||||||
if (!overrides.containsKey(item)) {
|
if (!overrides.containsKey(item)) {
|
||||||
var key = sapling.getKey().location();
|
var key = sapling.getKey().location();
|
||||||
|
|
||||||
if (key.getPath().endsWith("sapling")) {
|
if (key.getPath().endsWith("sapling")) {
|
||||||
try {
|
try {
|
||||||
overrides.put(item, ForgeRegistries.BLOCKS.getValue(new ResourceLocation(key.getNamespace(), key.getPath().replace("sapling", "leaves"))));
|
overrides.put(item, BuiltInRegistries.BLOCK.get(new ResourceLocation(key.getNamespace(), key.getPath().replace("sapling", "leaves"))));
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@
|
||||||
package thedarkcolour.exdeorum.blockentity;
|
package thedarkcolour.exdeorum.blockentity;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.util.Mth;
|
import net.minecraft.util.Mth;
|
||||||
|
|
@ -31,16 +30,12 @@ import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityTicker;
|
import net.minecraft.world.level.block.entity.BlockEntityTicker;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import net.neoforged.neoforge.energy.IEnergyStorage;
|
||||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
import net.neoforged.neoforge.items.IItemHandler;
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
|
||||||
import net.minecraftforge.energy.EnergyStorage;
|
|
||||||
import net.minecraftforge.network.NetworkHooks;
|
|
||||||
import thedarkcolour.exdeorum.blockentity.helper.EnergyHelper;
|
import thedarkcolour.exdeorum.blockentity.helper.EnergyHelper;
|
||||||
import thedarkcolour.exdeorum.blockentity.helper.ItemHelper;
|
import thedarkcolour.exdeorum.blockentity.helper.ItemHelper;
|
||||||
import thedarkcolour.exdeorum.client.screen.RedstoneControlWidget;
|
import thedarkcolour.exdeorum.client.screen.RedstoneControlWidget;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public abstract class AbstractMachineBlockEntity<M extends AbstractMachineBlockEntity<M>> extends EBlockEntity implements MenuProvider {
|
public abstract class AbstractMachineBlockEntity<M extends AbstractMachineBlockEntity<M>> extends EBlockEntity implements MenuProvider {
|
||||||
|
|
@ -50,18 +45,12 @@ public abstract class AbstractMachineBlockEntity<M extends AbstractMachineBlockE
|
||||||
// not saved to NBT
|
// not saved to NBT
|
||||||
protected boolean hasRedstonePower;
|
protected boolean hasRedstonePower;
|
||||||
|
|
||||||
private final LazyOptional<ItemHelper> capabilityInventory;
|
|
||||||
private final LazyOptional<EnergyStorage> capabilityEnergy;
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public AbstractMachineBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state, Function<M, ItemHelper> inventory, int maxEnergy) {
|
public AbstractMachineBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state, Function<M, ItemHelper> inventory, int maxEnergy) {
|
||||||
super(type, pos, state);
|
super(type, pos, state);
|
||||||
|
|
||||||
this.inventory = inventory.apply((M) this);
|
this.inventory = inventory.apply((M) this);
|
||||||
this.energy = new EnergyHelper(maxEnergy);
|
this.energy = new EnergyHelper(maxEnergy);
|
||||||
|
|
||||||
this.capabilityInventory = LazyOptional.of(() -> this.inventory);
|
|
||||||
this.capabilityEnergy = LazyOptional.of(() -> this.energy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -99,31 +88,10 @@ public abstract class AbstractMachineBlockEntity<M extends AbstractMachineBlockE
|
||||||
return this.redstoneMode;
|
return this.redstoneMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("NullableProblems")
|
|
||||||
@Override
|
|
||||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @javax.annotation.Nullable Direction side) {
|
|
||||||
if (cap == ForgeCapabilities.ENERGY) {
|
|
||||||
return this.capabilityEnergy.cast();
|
|
||||||
} else if (cap == ForgeCapabilities.ITEM_HANDLER) {
|
|
||||||
return this.capabilityInventory.cast();
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.getCapability(cap, side);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateCaps() {
|
|
||||||
super.invalidateCaps();
|
|
||||||
|
|
||||||
this.capabilityEnergy.invalidate();
|
|
||||||
this.capabilityInventory.invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InteractionResult use(Level level, Player player, InteractionHand hand) {
|
public InteractionResult use(Level level, Player player, InteractionHand hand) {
|
||||||
if (player instanceof ServerPlayer serverPlayer) {
|
if (player instanceof ServerPlayer serverPlayer) {
|
||||||
NetworkHooks.openScreen(serverPlayer, this, buffer -> {
|
serverPlayer.openMenu(this, buffer -> {
|
||||||
buffer.writeBlockPos(getBlockPos());
|
buffer.writeBlockPos(getBlockPos());
|
||||||
buffer.writeByte(this.redstoneMode);
|
buffer.writeByte(this.redstoneMode);
|
||||||
});
|
});
|
||||||
|
|
@ -151,6 +119,14 @@ public abstract class AbstractMachineBlockEntity<M extends AbstractMachineBlockE
|
||||||
|
|
||||||
protected void noEnergyTick() {}
|
protected void noEnergyTick() {}
|
||||||
|
|
||||||
|
public IItemHandler getItemHandler() {
|
||||||
|
return this.inventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnergyStorage getEnergyStorage() {
|
||||||
|
return this.energy;
|
||||||
|
}
|
||||||
|
|
||||||
public static class ServerTicker<M extends AbstractMachineBlockEntity<M>> implements BlockEntityTicker<M> {
|
public static class ServerTicker<M extends AbstractMachineBlockEntity<M>> implements BlockEntityTicker<M> {
|
||||||
@Override
|
@Override
|
||||||
public void tick(Level level, BlockPos pos, BlockState state, M machine) {
|
public void tick(Level level, BlockPos pos, BlockState state, M machine) {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@
|
||||||
package thedarkcolour.exdeorum.blockentity;
|
package thedarkcolour.exdeorum.blockentity;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.core.particles.ParticleTypes;
|
import net.minecraft.core.particles.ParticleTypes;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
|
@ -43,18 +42,16 @@ import net.minecraft.world.level.block.entity.BlockEntityTicker;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.material.FlowingFluid;
|
import net.minecraft.world.level.material.FlowingFluid;
|
||||||
import net.minecraft.world.level.material.Fluids;
|
import net.minecraft.world.level.material.Fluids;
|
||||||
import net.minecraftforge.common.ForgeMod;
|
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import net.neoforged.neoforge.common.NeoForgeMod;
|
||||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
import net.neoforged.neoforge.fluids.FluidStack;
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.neoforged.neoforge.fluids.FluidType;
|
||||||
import net.minecraftforge.fluids.FluidStack;
|
import net.neoforged.neoforge.fluids.FluidUtil;
|
||||||
import net.minecraftforge.fluids.FluidType;
|
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
|
||||||
import net.minecraftforge.fluids.FluidUtil;
|
import net.neoforged.neoforge.fluids.capability.templates.FluidTank;
|
||||||
import net.minecraftforge.fluids.IFluidTank;
|
import net.neoforged.neoforge.items.IItemHandler;
|
||||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
import net.neoforged.neoforge.items.ItemHandlerHelper;
|
||||||
import net.minecraftforge.items.IItemHandler;
|
import net.neoforged.neoforge.items.ItemStackHandler;
|
||||||
import net.minecraftforge.items.ItemHandlerHelper;
|
|
||||||
import net.minecraftforge.items.ItemStackHandler;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import thedarkcolour.exdeorum.block.BarrelBlock;
|
import thedarkcolour.exdeorum.block.BarrelBlock;
|
||||||
import thedarkcolour.exdeorum.blockentity.helper.FluidHelper;
|
import thedarkcolour.exdeorum.blockentity.helper.FluidHelper;
|
||||||
|
|
@ -84,33 +81,12 @@ public class BarrelBlockEntity extends EBlockEntity {
|
||||||
@Nullable
|
@Nullable
|
||||||
public FluidTransformationRecipe currentTransformRecipe = null;
|
public FluidTransformationRecipe currentTransformRecipe = null;
|
||||||
|
|
||||||
private final LazyOptional<IItemHandler> itemHandler = LazyOptional.of(() -> this.item);
|
|
||||||
private final LazyOptional<IFluidHandler> fluidHandler = LazyOptional.of(() -> this.tank);
|
|
||||||
|
|
||||||
public BarrelBlockEntity(BlockPos pos, BlockState state) {
|
public BarrelBlockEntity(BlockPos pos, BlockState state) {
|
||||||
super(EBlockEntities.BARREL.get(), pos, state);
|
super(EBlockEntities.BARREL.get(), pos, state);
|
||||||
|
|
||||||
this.transparent = BarrelMaterial.TRANSPARENT_BARRELS.contains(state.getBlock());
|
this.transparent = BarrelMaterial.TRANSPARENT_BARRELS.contains(state.getBlock());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
|
|
||||||
if (cap == ForgeCapabilities.FLUID_HANDLER) {
|
|
||||||
return this.fluidHandler.cast();
|
|
||||||
} else if (cap == ForgeCapabilities.ITEM_HANDLER) {
|
|
||||||
return this.itemHandler.cast();
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.getCapability(cap, side);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateCaps() {
|
|
||||||
super.invalidateCaps();
|
|
||||||
this.fluidHandler.invalidate();
|
|
||||||
this.itemHandler.invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveAdditional(CompoundTag nbt) {
|
public void saveAdditional(CompoundTag nbt) {
|
||||||
super.saveAdditional(nbt);
|
super.saveAdditional(nbt);
|
||||||
|
|
@ -177,6 +153,7 @@ public class BarrelBlockEntity extends EBlockEntity {
|
||||||
return this.compost <= 0 && this.item.getStackInSlot(0).isEmpty();
|
return this.compost <= 0 && this.item.getStackInSlot(0).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public boolean hasFullWater() {
|
public boolean hasFullWater() {
|
||||||
return this.tank.getFluidAmount() == 1000 && this.tank.getFluid().getFluid().is(FluidTags.WATER);
|
return this.tank.getFluidAmount() == 1000 && this.tank.getFluid().getFluid().is(FluidTags.WATER);
|
||||||
}
|
}
|
||||||
|
|
@ -187,15 +164,15 @@ public class BarrelBlockEntity extends EBlockEntity {
|
||||||
return fluidType.getTemperature() > 575;
|
return fluidType.getTemperature() > 575;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void spawnParticlesIfBurning() {
|
private void spawnParticlesIfBurning(Level level) {
|
||||||
if (isBurning()) {
|
if (isBurning()) {
|
||||||
BlockPos pos = getBlockPos();
|
BlockPos pos = getBlockPos();
|
||||||
int burnTicks = (int) (this.progress * 300);
|
int burnTicks = (int) (this.progress * 300);
|
||||||
|
|
||||||
if (burnTicks % 30 == 0) {
|
if (burnTicks % 30 == 0) {
|
||||||
this.level.addParticle(ParticleTypes.LARGE_SMOKE, pos.getX() + Math.random(), pos.getY() + 1.2, pos.getZ() + Math.random(), 0.0, 0.0, 0.0);
|
level.addParticle(ParticleTypes.LARGE_SMOKE, pos.getX() + Math.random(), pos.getY() + 1.2, pos.getZ() + Math.random(), 0.0, 0.0, 0.0);
|
||||||
} else if (burnTicks % 5 == 0) {
|
} else if (burnTicks % 5 == 0) {
|
||||||
this.level.addParticle(ParticleTypes.SMOKE, pos.getX() + Math.random(), pos.getY() + 1.2, pos.getZ() + Math.random(), 0.0, 0.0, 0.0);
|
level.addParticle(ParticleTypes.SMOKE, pos.getX() + Math.random(), pos.getY() + 1.2, pos.getZ() + Math.random(), 0.0, 0.0, 0.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -208,7 +185,7 @@ public class BarrelBlockEntity extends EBlockEntity {
|
||||||
this.item.setStackInSlot(0, item);
|
this.item.setStackInSlot(0, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IFluidTank getTank() {
|
public FluidTank getTank() {
|
||||||
return this.tank;
|
return this.tank;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -264,19 +241,18 @@ public class BarrelBlockEntity extends EBlockEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, mix the item's fluid into the barrel's fluid
|
// Otherwise, mix the item's fluid into the barrel's fluid
|
||||||
var itemFluidCapOptional = playerItem.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).resolve();
|
var itemFluidCap = playerItem.getCapability(Capabilities.FluidHandler.ITEM);
|
||||||
if (itemFluidCapOptional.isPresent()) {
|
if (itemFluidCap != null) {
|
||||||
var itemFluidCap = itemFluidCapOptional.get();
|
|
||||||
var itemFluid = itemFluidCap.drain(1000, IFluidHandler.FluidAction.SIMULATE);
|
var itemFluid = itemFluidCap.drain(1000, IFluidHandler.FluidAction.SIMULATE);
|
||||||
BarrelFluidMixingRecipe recipe = RecipeUtil.getFluidMixingRecipe(this.tank.getFluid(), itemFluid.getFluid());
|
BarrelFluidMixingRecipe recipe = RecipeUtil.getFluidMixingRecipe(this.tank.getFluid(), itemFluid.getFluid());
|
||||||
|
|
||||||
// If draining item fluid was possible and tank has enough fluid to mix...
|
// If draining item fluid was possible and tank has enough fluid to mix...
|
||||||
if (recipe != null && this.tank.getFluidAmount() >= recipe.baseFluidAmount && itemFluid.getAmount() == 1000) {
|
if (recipe != null && this.tank.getFluidAmount() >= recipe.baseFluidAmount() && itemFluid.getAmount() == 1000) {
|
||||||
if (!level.isClientSide) {
|
if (!level.isClientSide) {
|
||||||
this.tank.drain(recipe.baseFluidAmount, IFluidHandler.FluidAction.EXECUTE);
|
this.tank.drain(recipe.baseFluidAmount(), IFluidHandler.FluidAction.EXECUTE);
|
||||||
setItem(new ItemStack(recipe.result));
|
setItem(new ItemStack(recipe.result()));
|
||||||
|
|
||||||
if (recipe.consumesAdditive) {
|
if (recipe.consumesAdditive()) {
|
||||||
itemFluidCap.drain(1000, IFluidHandler.FluidAction.EXECUTE);
|
itemFluidCap.drain(1000, IFluidHandler.FluidAction.EXECUTE);
|
||||||
player.setItemInHand(hand, itemFluidCap.getContainer());
|
player.setItemInHand(hand, itemFluidCap.getContainer());
|
||||||
}
|
}
|
||||||
|
|
@ -443,14 +419,14 @@ public class BarrelBlockEntity extends EBlockEntity {
|
||||||
if (recipe != null) {
|
if (recipe != null) {
|
||||||
// If additive is not consumed, just craft
|
// If additive is not consumed, just craft
|
||||||
// If additive is consumed, check that the additive can be consumed before crafting
|
// If additive is consumed, check that the additive can be consumed before crafting
|
||||||
if (!recipe.consumesAdditive) {
|
if (!recipe.consumesAdditive()) {
|
||||||
this.tank.drain(recipe.baseFluidAmount, IFluidHandler.FluidAction.EXECUTE);
|
this.tank.drain(recipe.baseFluidAmount(), IFluidHandler.FluidAction.EXECUTE);
|
||||||
setItem(new ItemStack(recipe.result));
|
setItem(new ItemStack(recipe.result()));
|
||||||
} else if (aboveBlockState.getBlock() instanceof BucketPickup pickup) {
|
} else if (aboveBlockState.getBlock() instanceof BucketPickup pickup) {
|
||||||
// If something was picked up, we can craft
|
// If something was picked up, we can craft
|
||||||
if (!pickup.pickupBlock(this.level, abovePos, aboveBlockState).isEmpty()) {
|
if (!pickup.pickupBlock(null, this.level, abovePos, aboveBlockState).isEmpty()) {
|
||||||
this.tank.drain(recipe.baseFluidAmount, IFluidHandler.FluidAction.EXECUTE);
|
this.tank.drain(recipe.baseFluidAmount(), IFluidHandler.FluidAction.EXECUTE);
|
||||||
setItem(new ItemStack(recipe.result));
|
setItem(new ItemStack(recipe.result()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -468,7 +444,7 @@ public class BarrelBlockEntity extends EBlockEntity {
|
||||||
this.currentTransformRecipe = RecipeUtil.getFluidTransformationRecipe(this.tank.getFluid().getFluid(), belowState);
|
this.currentTransformRecipe = RecipeUtil.getFluidTransformationRecipe(this.tank.getFluid().getFluid(), belowState);
|
||||||
|
|
||||||
if (this.currentTransformRecipe != null) {
|
if (this.currentTransformRecipe != null) {
|
||||||
var color = this.currentTransformRecipe.resultColor;
|
var color = this.currentTransformRecipe.resultColor();
|
||||||
this.r = (short) ((color >> 16) & 0xff);
|
this.r = (short) ((color >> 16) & 0xff);
|
||||||
this.g = (short) ((color >> 8) & 0xff);
|
this.g = (short) ((color >> 8) & 0xff);
|
||||||
this.b = (short) ((color) & 0xff);
|
this.b = (short) ((color) & 0xff);
|
||||||
|
|
@ -479,6 +455,10 @@ public class BarrelBlockEntity extends EBlockEntity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IItemHandler getItemHandler() {
|
||||||
|
return this.item;
|
||||||
|
}
|
||||||
|
|
||||||
public static class Ticker implements BlockEntityTicker<BarrelBlockEntity> {
|
public static class Ticker implements BlockEntityTicker<BarrelBlockEntity> {
|
||||||
@Override
|
@Override
|
||||||
public void tick(Level level, BlockPos pos, BlockState state, BarrelBlockEntity barrel) {
|
public void tick(Level level, BlockPos pos, BlockState state, BarrelBlockEntity barrel) {
|
||||||
|
|
@ -503,17 +483,17 @@ public class BarrelBlockEntity extends EBlockEntity {
|
||||||
var catalysts = 0;
|
var catalysts = 0;
|
||||||
|
|
||||||
for (var cursor : BlockPos.betweenClosed(pos.getX() - 1, pos.getY() - 1, pos.getZ() - 1, pos.getX() + 1, pos.getY() - 1, pos.getZ() + 1)) {
|
for (var cursor : BlockPos.betweenClosed(pos.getX() - 1, pos.getY() - 1, pos.getZ() - 1, pos.getX() + 1, pos.getY() - 1, pos.getZ() + 1)) {
|
||||||
if (recipe.catalyst.test(level.getBlockState(cursor))) {
|
if (recipe.catalyst().test(level.getBlockState(cursor))) {
|
||||||
catalysts++;
|
catalysts++;
|
||||||
|
|
||||||
if (!recipe.byproducts.isEmpty()) {
|
if (!recipe.byproducts().isEmpty()) {
|
||||||
var rand = level.random;
|
var rand = level.random;
|
||||||
|
|
||||||
if (rand.nextInt(1500) == 0) {
|
if (rand.nextInt(1500) == 0) {
|
||||||
var above = cursor.above();
|
var above = cursor.above();
|
||||||
|
|
||||||
if (level.getBlockState(above).isAir()) {
|
if (level.getBlockState(above).isAir()) {
|
||||||
var byproduct = recipe.byproducts.getRandom(rand);
|
var byproduct = recipe.byproducts().getRandom(rand);
|
||||||
if (byproduct.canSurvive(level, above)) {
|
if (byproduct.canSurvive(level, above)) {
|
||||||
level.setBlockAndUpdate(above, byproduct);
|
level.setBlockAndUpdate(above, byproduct);
|
||||||
}
|
}
|
||||||
|
|
@ -526,7 +506,7 @@ public class BarrelBlockEntity extends EBlockEntity {
|
||||||
if (catalysts == 0) {
|
if (catalysts == 0) {
|
||||||
barrel.currentTransformRecipe = null;
|
barrel.currentTransformRecipe = null;
|
||||||
} else {
|
} else {
|
||||||
barrel.progress += catalysts * (1.0f / barrel.currentTransformRecipe.duration);
|
barrel.progress += catalysts * (1.0f / barrel.currentTransformRecipe.duration());
|
||||||
if (barrel.progress >= 1.0f - Mth.EPSILON) {
|
if (barrel.progress >= 1.0f - Mth.EPSILON) {
|
||||||
// Reset progress
|
// Reset progress
|
||||||
barrel.progress = 0.0f;
|
barrel.progress = 0.0f;
|
||||||
|
|
@ -537,7 +517,7 @@ public class BarrelBlockEntity extends EBlockEntity {
|
||||||
barrel.markUpdated();
|
barrel.markUpdated();
|
||||||
}
|
}
|
||||||
} else if (barrel.hasFullWater()) {
|
} else if (barrel.hasFullWater()) {
|
||||||
if (barrel.tank.getFluid().getFluid().getFluidType() == ForgeMod.WATER_TYPE.get()) {
|
if (barrel.tank.getFluid().getFluid().getFluidType() == NeoForgeMod.WATER_TYPE.value()) {
|
||||||
var rand = level.random;
|
var rand = level.random;
|
||||||
// Leak water to create moss (only wooden barrels do this)
|
// Leak water to create moss (only wooden barrels do this)
|
||||||
if (state.ignitedByLava() && rand.nextInt(500) == 0) {
|
if (state.ignitedByLava() && rand.nextInt(500) == 0) {
|
||||||
|
|
@ -553,7 +533,7 @@ public class BarrelBlockEntity extends EBlockEntity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
barrel.spawnParticlesIfBurning();
|
barrel.spawnParticlesIfBurning(level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,22 +30,24 @@ import net.minecraft.world.level.block.Blocks;
|
||||||
import net.minecraft.world.level.block.LeavesBlock;
|
import net.minecraft.world.level.block.LeavesBlock;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityTicker;
|
import net.minecraft.world.level.block.entity.BlockEntityTicker;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraftforge.client.model.data.ModelData;
|
import net.neoforged.neoforge.client.model.data.ModelData;
|
||||||
import net.minecraftforge.client.model.data.ModelProperty;
|
import net.neoforged.neoforge.client.model.data.ModelProperty;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import thedarkcolour.exdeorum.block.InfestedLeavesBlock;
|
import thedarkcolour.exdeorum.block.InfestedLeavesBlock;
|
||||||
import thedarkcolour.exdeorum.registry.EBlockEntities;
|
import thedarkcolour.exdeorum.registry.EBlockEntities;
|
||||||
import thedarkcolour.exdeorum.registry.EBlocks;
|
import thedarkcolour.exdeorum.registry.EBlocks;
|
||||||
|
|
||||||
public class InfestedLeavesBlockEntity extends EBlockEntity {
|
public class InfestedLeavesBlockEntity extends EBlockEntity {
|
||||||
public static final float PROGRESS_INTERVAL = 0.005f;
|
// progress is a short between 0 and 16000 (why? because that's what the shader uses, also avoids float errors)
|
||||||
|
public static final short MAX_PROGRESS = 16000;
|
||||||
|
// 0.005 * 16000 = 80
|
||||||
|
public static final short PROGRESS_INTERVAL = 80;
|
||||||
public static final int SPREAD_INTERVAL = 40;
|
public static final int SPREAD_INTERVAL = 40;
|
||||||
|
|
||||||
public static final ModelProperty<BlockState> MIMIC_PROPERTY = new ModelProperty<>();
|
public static final ModelProperty<BlockState> MIMIC_PROPERTY = new ModelProperty<>();
|
||||||
|
|
||||||
// A percentage of how much this leaf is infested
|
// value between 0 and 16000 representing infestation progress
|
||||||
// todo change this to a short between 0 and 16000
|
private short progress;
|
||||||
private float progress;
|
|
||||||
// A timer that determines when this block should try to spread
|
// A timer that determines when this block should try to spread
|
||||||
private int spreadTimer;
|
private int spreadTimer;
|
||||||
// The state this block should render as
|
// The state this block should render as
|
||||||
|
|
@ -57,33 +59,33 @@ public class InfestedLeavesBlockEntity extends EBlockEntity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeVisualData(FriendlyByteBuf buffer) {
|
public void writeVisualData(FriendlyByteBuf buffer) {
|
||||||
buffer.writeFloat(this.progress);
|
buffer.writeShort(this.progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readVisualData(FriendlyByteBuf buffer) {
|
public void readVisualData(FriendlyByteBuf buffer) {
|
||||||
buffer.readFloat();
|
buffer.readShort();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to convert a leaf block within 1 block radius around this block
|
// Attempt to convert a leaf block within 1 block radius around this block
|
||||||
private void trySpread() {
|
private void trySpread(Level level) {
|
||||||
// Get random offset
|
// Get random offset
|
||||||
int x = this.level.random.nextInt(3) - 1;
|
int x = level.random.nextInt(3) - 1;
|
||||||
int y = this.level.random.nextInt(3) - 1;
|
int y = level.random.nextInt(3) - 1;
|
||||||
int z = this.level.random.nextInt(3) - 1;
|
int z = level.random.nextInt(3) - 1;
|
||||||
|
|
||||||
// Get the block in the world
|
// Get the block in the world
|
||||||
BlockPos targetPos = getBlockPos().offset(x, y, z);
|
BlockPos targetPos = getBlockPos().offset(x, y, z);
|
||||||
BlockState state = this.level.getBlockState(targetPos);
|
BlockState state = level.getBlockState(targetPos);
|
||||||
|
|
||||||
// DO NOT SPREAD TO ALREADY INFESTED LEAVES
|
// DO NOT SPREAD TO ALREADY INFESTED LEAVES
|
||||||
if (state.is(BlockTags.LEAVES) && state.getBlock() != EBlocks.INFESTED_LEAVES.get()) {
|
if (state.is(BlockTags.LEAVES) && state.getBlock() != EBlocks.INFESTED_LEAVES.get()) {
|
||||||
// Spread and keep distance/persistent properties
|
// Spread and keep distance/persistent properties
|
||||||
this.level.setBlock(targetPos, EBlocks.INFESTED_LEAVES.get().defaultBlockState()
|
level.setBlock(targetPos, EBlocks.INFESTED_LEAVES.get().defaultBlockState()
|
||||||
.setValue(LeavesBlock.DISTANCE, state.getValue(LeavesBlock.DISTANCE))
|
.setValue(LeavesBlock.DISTANCE, state.getValue(LeavesBlock.DISTANCE))
|
||||||
.setValue(LeavesBlock.PERSISTENT, state.getValue(LeavesBlock.PERSISTENT)),
|
.setValue(LeavesBlock.PERSISTENT, state.getValue(LeavesBlock.PERSISTENT)),
|
||||||
2);
|
2);
|
||||||
var te = this.level.getBlockEntity(targetPos);
|
var te = level.getBlockEntity(targetPos);
|
||||||
|
|
||||||
// Set mimic state of other block
|
// Set mimic state of other block
|
||||||
if (te instanceof InfestedLeavesBlockEntity leaves) {
|
if (te instanceof InfestedLeavesBlockEntity leaves) {
|
||||||
|
|
@ -98,10 +100,9 @@ public class InfestedLeavesBlockEntity extends EBlockEntity {
|
||||||
super.load(nbt);
|
super.load(nbt);
|
||||||
|
|
||||||
// From PistonMovingBlockEntity
|
// From PistonMovingBlockEntity
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
var holderLookup = this.level != null ? this.level.holderLookup(Registries.BLOCK) : BuiltInRegistries.BLOCK.asLookup();
|
var holderLookup = this.level != null ? this.level.holderLookup(Registries.BLOCK) : BuiltInRegistries.BLOCK.asLookup();
|
||||||
this.mimic = NbtUtils.readBlockState(holderLookup, nbt.getCompound("mimic"));
|
this.mimic = NbtUtils.readBlockState(holderLookup, nbt.getCompound("mimic"));
|
||||||
this.progress = nbt.getFloat("progress");
|
this.progress = nbt.getShort("progress");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -115,11 +116,11 @@ public class InfestedLeavesBlockEntity extends EBlockEntity {
|
||||||
nbt.putFloat("progress", this.progress);
|
nbt.putFloat("progress", this.progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getProgress() {
|
public int getProgress() {
|
||||||
return this.progress;
|
return this.progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProgress(float progress) {
|
public void setProgress(short progress) {
|
||||||
this.progress = progress;
|
this.progress = progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,8 +141,8 @@ public class InfestedLeavesBlockEntity extends EBlockEntity {
|
||||||
@Override
|
@Override
|
||||||
public void tick(Level level, BlockPos pos, BlockState state, InfestedLeavesBlockEntity leaves) {
|
public void tick(Level level, BlockPos pos, BlockState state, InfestedLeavesBlockEntity leaves) {
|
||||||
// Do progress
|
// Do progress
|
||||||
if (leaves.progress < 1.0f) {
|
if (leaves.progress < MAX_PROGRESS) {
|
||||||
leaves.progress = Math.min(1.0f, leaves.progress + PROGRESS_INTERVAL);
|
leaves.progress = (short) Math.min(MAX_PROGRESS, leaves.progress + PROGRESS_INTERVAL);
|
||||||
|
|
||||||
if (leaves.progress == 1.0f) {
|
if (leaves.progress == 1.0f) {
|
||||||
level.setBlock(pos, state.setValue(InfestedLeavesBlock.FULLY_INFESTED, true), 1);
|
level.setBlock(pos, state.setValue(InfestedLeavesBlock.FULLY_INFESTED, true), 1);
|
||||||
|
|
@ -154,7 +155,7 @@ public class InfestedLeavesBlockEntity extends EBlockEntity {
|
||||||
|
|
||||||
// Attempt to spread and reset the timer
|
// Attempt to spread and reset the timer
|
||||||
if (leaves.spreadTimer >= SPREAD_INTERVAL) {
|
if (leaves.spreadTimer >= SPREAD_INTERVAL) {
|
||||||
leaves.trySpread();
|
leaves.trySpread(level);
|
||||||
leaves.spreadTimer = level.random.nextInt(10);
|
leaves.spreadTimer = level.random.nextInt(10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ import thedarkcolour.exdeorum.blockentity.helper.ItemHelper;
|
||||||
import thedarkcolour.exdeorum.config.EConfig;
|
import thedarkcolour.exdeorum.config.EConfig;
|
||||||
import thedarkcolour.exdeorum.data.TranslationKeys;
|
import thedarkcolour.exdeorum.data.TranslationKeys;
|
||||||
import thedarkcolour.exdeorum.loot.HammerLootModifier;
|
import thedarkcolour.exdeorum.loot.HammerLootModifier;
|
||||||
|
import thedarkcolour.exdeorum.menu.MechanicalHammerMenu;
|
||||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
||||||
import thedarkcolour.exdeorum.recipe.hammer.HammerRecipe;
|
import thedarkcolour.exdeorum.recipe.hammer.HammerRecipe;
|
||||||
import thedarkcolour.exdeorum.registry.EBlockEntities;
|
import thedarkcolour.exdeorum.registry.EBlockEntities;
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraftforge.items.ItemHandlerHelper;
|
import net.neoforged.neoforge.items.ItemHandlerHelper;
|
||||||
import thedarkcolour.exdeorum.blockentity.helper.ItemHelper;
|
import thedarkcolour.exdeorum.blockentity.helper.ItemHelper;
|
||||||
import thedarkcolour.exdeorum.blockentity.logic.SieveLogic;
|
import thedarkcolour.exdeorum.blockentity.logic.SieveLogic;
|
||||||
import thedarkcolour.exdeorum.config.EConfig;
|
import thedarkcolour.exdeorum.config.EConfig;
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraftforge.common.util.FakePlayer;
|
import net.neoforged.neoforge.common.util.FakePlayer;
|
||||||
import thedarkcolour.exdeorum.blockentity.logic.SieveLogic;
|
import thedarkcolour.exdeorum.blockentity.logic.SieveLogic;
|
||||||
import thedarkcolour.exdeorum.config.EConfig;
|
import thedarkcolour.exdeorum.config.EConfig;
|
||||||
import thedarkcolour.exdeorum.registry.EBlockEntities;
|
import thedarkcolour.exdeorum.registry.EBlockEntities;
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.blockentity.helper;
|
package thedarkcolour.exdeorum.blockentity.helper;
|
||||||
|
|
||||||
import net.minecraftforge.energy.EnergyStorage;
|
import net.neoforged.neoforge.energy.EnergyStorage;
|
||||||
|
|
||||||
public class EnergyHelper extends EnergyStorage {
|
public class EnergyHelper extends EnergyStorage {
|
||||||
public EnergyHelper(int capacity) {
|
public EnergyHelper(int capacity) {
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,8 @@
|
||||||
package thedarkcolour.exdeorum.blockentity.helper;
|
package thedarkcolour.exdeorum.blockentity.helper;
|
||||||
|
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraftforge.fluids.FluidStack;
|
import net.neoforged.neoforge.fluids.FluidStack;
|
||||||
import net.minecraftforge.fluids.capability.templates.FluidTank;
|
import net.neoforged.neoforge.fluids.capability.templates.FluidTank;
|
||||||
|
|
||||||
// Changed behavior from FluidTank:
|
// Changed behavior from FluidTank:
|
||||||
// - fluid stacks read from NBT are clamped.
|
// - fluid stacks read from NBT are clamped.
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@ package thedarkcolour.exdeorum.blockentity.helper;
|
||||||
|
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraftforge.items.ItemStackHandler;
|
import net.neoforged.neoforge.items.ItemStackHandler;
|
||||||
import net.minecraftforge.items.SlotItemHandler;
|
import net.neoforged.neoforge.items.SlotItemHandler;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
// Has same behavior as ItemStackHandler but is more customizable.
|
// Has same behavior as ItemStackHandler but is more customizable.
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,7 @@ public class SieveLogic {
|
||||||
|
|
||||||
public void saveNbt(CompoundTag nbt) {
|
public void saveNbt(CompoundTag nbt) {
|
||||||
if (!this.contents.isEmpty()) {
|
if (!this.contents.isEmpty()) {
|
||||||
nbt.put("contents", this.contents.serializeNBT());
|
nbt.put("contents", this.contents.save(new CompoundTag()));
|
||||||
}
|
}
|
||||||
if (this.saveMesh && !this.mesh.isEmpty()) {
|
if (this.saveMesh && !this.mesh.isEmpty()) {
|
||||||
nbt.put("mesh", this.mesh.save(new CompoundTag()));
|
nbt.put("mesh", this.mesh.save(new CompoundTag()));
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ package thedarkcolour.exdeorum.client;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.screens.MenuScreens;
|
|
||||||
import net.minecraft.client.gui.screens.worldselection.CreateWorldScreen;
|
import net.minecraft.client.gui.screens.worldselection.CreateWorldScreen;
|
||||||
import net.minecraft.client.gui.screens.worldselection.WorldCreationUiState;
|
import net.minecraft.client.gui.screens.worldselection.WorldCreationUiState;
|
||||||
import net.minecraft.client.renderer.ItemBlockRenderTypes;
|
import net.minecraft.client.renderer.ItemBlockRenderTypes;
|
||||||
|
|
@ -30,18 +29,13 @@ import net.minecraft.client.renderer.ShaderInstance;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.util.Unit;
|
import net.minecraft.util.Unit;
|
||||||
import net.minecraftforge.client.event.ClientPlayerNetworkEvent;
|
import net.neoforged.bus.api.IEventBus;
|
||||||
import net.minecraftforge.client.event.EntityRenderersEvent;
|
import net.neoforged.fml.ModList;
|
||||||
import net.minecraftforge.client.event.ModelEvent;
|
import net.neoforged.fml.event.config.ModConfigEvent;
|
||||||
import net.minecraftforge.client.event.RegisterClientReloadListenersEvent;
|
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
|
||||||
import net.minecraftforge.client.event.RegisterShadersEvent;
|
import net.neoforged.neoforge.client.event.*;
|
||||||
import net.minecraftforge.client.event.ScreenEvent;
|
import net.neoforged.neoforge.common.NeoForge;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.neoforged.neoforge.event.TagsUpdatedEvent;
|
||||||
import net.minecraftforge.event.TagsUpdatedEvent;
|
|
||||||
import net.minecraftforge.fml.ModList;
|
|
||||||
import net.minecraftforge.fml.event.config.ModConfigEvent;
|
|
||||||
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
|
||||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
|
||||||
import thedarkcolour.exdeorum.ExDeorum;
|
import thedarkcolour.exdeorum.ExDeorum;
|
||||||
import thedarkcolour.exdeorum.client.screen.MechanicalHammerScreen;
|
import thedarkcolour.exdeorum.client.screen.MechanicalHammerScreen;
|
||||||
import thedarkcolour.exdeorum.client.screen.MechanicalSieveScreen;
|
import thedarkcolour.exdeorum.client.screen.MechanicalSieveScreen;
|
||||||
|
|
@ -66,11 +60,11 @@ public class ClientHandler {
|
||||||
// This is set to true whenever the server tells a client to do so, then set back to false after cache is refreshed.
|
// This is set to true whenever the server tells a client to do so, then set back to false after cache is refreshed.
|
||||||
public static boolean needsRecipeCacheRefresh;
|
public static boolean needsRecipeCacheRefresh;
|
||||||
|
|
||||||
public static void register() {
|
public static void register(IEventBus modBus) {
|
||||||
var modBus = FMLJavaModLoadingContext.get().getModEventBus();
|
var fmlBus = NeoForge.EVENT_BUS;
|
||||||
var fmlBus = MinecraftForge.EVENT_BUS;
|
|
||||||
|
|
||||||
modBus.addListener(ClientHandler::clientSetup);
|
modBus.addListener(ClientHandler::clientSetup);
|
||||||
|
modBus.addListener(ClientHandler::registerMenuScreens);
|
||||||
modBus.addListener(ClientHandler::registerRenderers);
|
modBus.addListener(ClientHandler::registerRenderers);
|
||||||
modBus.addListener(ClientHandler::registerShaders);
|
modBus.addListener(ClientHandler::registerShaders);
|
||||||
modBus.addListener(ClientHandler::addClientReloadListeners);
|
modBus.addListener(ClientHandler::addClientReloadListeners);
|
||||||
|
|
@ -99,11 +93,12 @@ public class ClientHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void clientSetup(FMLClientSetupEvent event) {
|
private static void clientSetup(FMLClientSetupEvent event) {
|
||||||
event.enqueueWork(() -> {
|
event.enqueueWork(ClientHandler::setRenderLayers);
|
||||||
setRenderLayers();
|
}
|
||||||
MenuScreens.register(EMenus.MECHANICAL_SIEVE.get(), MechanicalSieveScreen::new);
|
|
||||||
MenuScreens.register(EMenus.MECHANICAL_HAMMER.get(), MechanicalHammerScreen::new);
|
private static void registerMenuScreens(RegisterMenuScreensEvent event) {
|
||||||
});
|
event.register(EMenus.MECHANICAL_SIEVE.get(), MechanicalSieveScreen::new);
|
||||||
|
event.register(EMenus.MECHANICAL_HAMMER.get(), MechanicalHammerScreen::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setRenderLayers() {
|
private static void setRenderLayers() {
|
||||||
|
|
|
||||||
|
|
@ -28,17 +28,17 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectSet;
|
import it.unimi.dsi.fastutil.objects.ObjectSet;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.util.GsonHelper;
|
import net.minecraft.util.GsonHelper;
|
||||||
import net.minecraft.world.inventory.InventoryMenu;
|
import net.minecraft.world.inventory.InventoryMenu;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.Items;
|
import net.minecraft.world.item.Items;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.neoforged.api.distmarker.Dist;
|
||||||
import net.minecraftforge.client.model.data.ModelData;
|
import net.neoforged.fml.ModList;
|
||||||
import net.minecraftforge.fml.ModList;
|
import net.neoforged.fml.loading.FMLEnvironment;
|
||||||
import net.minecraftforge.fml.loading.FMLEnvironment;
|
import net.neoforged.neoforge.client.model.data.ModelData;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.joml.Vector3i;
|
import org.joml.Vector3i;
|
||||||
|
|
@ -54,11 +54,7 @@ import java.io.InputStreamReader;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.NoSuchElementException;
|
|
||||||
import java.util.StringTokenizer;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
// ExDeorum comes with a precomputed list of vanilla colors, since textures don't exist on the server.
|
// ExDeorum comes with a precomputed list of vanilla colors, since textures don't exist on the server.
|
||||||
|
|
@ -109,8 +105,7 @@ public class CompostColors {
|
||||||
// alpha doesn't matter, only RGB
|
// alpha doesn't matter, only RGB
|
||||||
image.downloadTexture(0, false);
|
image.downloadTexture(0, false);
|
||||||
|
|
||||||
for (var entry : ForgeRegistries.ITEMS.getEntries()) {
|
for (var item : BuiltInRegistries.ITEM) {
|
||||||
var item = entry.getValue();
|
|
||||||
var model = Minecraft.getInstance().getItemRenderer().getItemModelShaper().getItemModel(item);
|
var model = Minecraft.getInstance().getItemRenderer().getItemModelShaper().getItemModel(item);
|
||||||
|
|
||||||
if (model != null) {
|
if (model != null) {
|
||||||
|
|
@ -147,11 +142,12 @@ public class CompostColors {
|
||||||
private static void loadModded() {
|
private static void loadModded() {
|
||||||
var readMods = readModdedColorFiles();
|
var readMods = readModdedColorFiles();
|
||||||
|
|
||||||
for (var entry : ForgeRegistries.ITEMS.getEntries()) {
|
for (var entry : BuiltInRegistries.ITEM.entrySet()) {
|
||||||
var modid = entry.getKey().location().getNamespace();
|
var key = entry.getKey().location();
|
||||||
|
var modid = key.getNamespace();
|
||||||
|
|
||||||
if (!readMods.contains(modid)) {
|
if (!readMods.contains(modid)) {
|
||||||
var id = entry.getKey().location().getPath();
|
var id = key.getPath();
|
||||||
var modFile = ModList.get().getModFileById(modid);
|
var modFile = ModList.get().getModFileById(modid);
|
||||||
if (modFile == null)
|
if (modFile == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -209,8 +205,10 @@ public class CompostColors {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("DataFlowIssue")
|
// todo should i sort the registry before iterating it, or should I keep the sort here?
|
||||||
var entries = COLORS.keySet().stream().sorted(Comparator.comparing(ForgeRegistries.ITEMS::getKey)).collect(Collectors.groupingBy(item -> ForgeRegistries.ITEMS.getKey(item).getNamespace()));
|
Map<String, List<Item>> entries = COLORS.keySet().stream()
|
||||||
|
.sorted(Comparator.comparing(BuiltInRegistries.ITEM::getKey))
|
||||||
|
.collect(Collectors.groupingBy(item -> BuiltInRegistries.ITEM.getKey(item).getNamespace()));
|
||||||
|
|
||||||
for (var entry : entries.entrySet()) {
|
for (var entry : entries.entrySet()) {
|
||||||
if (!readMods.contains(entry.getKey())) {
|
if (!readMods.contains(entry.getKey())) {
|
||||||
|
|
@ -317,11 +315,11 @@ public class CompostColors {
|
||||||
var tokenizer = new StringTokenizer(line, ", #");
|
var tokenizer = new StringTokenizer(line, ", #");
|
||||||
try {
|
try {
|
||||||
var id = new ResourceLocation(modid, tokenizer.nextToken());
|
var id = new ResourceLocation(modid, tokenizer.nextToken());
|
||||||
var item = ForgeRegistries.ITEMS.getValue(id);
|
var item = BuiltInRegistries.ITEM.get(id);
|
||||||
String token = tokenizer.nextToken();
|
String token = tokenizer.nextToken();
|
||||||
var color = Integer.parseInt(token, 16);
|
var color = Integer.parseInt(token, 16);
|
||||||
|
|
||||||
if (item != null && item != Items.AIR) {
|
if (item != Items.AIR) {
|
||||||
readColors++;
|
readColors++;
|
||||||
|
|
||||||
COLORS.put(item, new Vector3i(
|
COLORS.put(item, new Vector3i(
|
||||||
|
|
@ -353,9 +351,8 @@ public class CompostColors {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("DataFlowIssue")
|
|
||||||
public static void export(String modid) {
|
public static void export(String modid) {
|
||||||
export(modid, COLORS.keySet().stream().filter(key -> ForgeRegistries.ITEMS.getKey(key).getNamespace().equals(modid)).sorted(Comparator.comparing(ForgeRegistries.ITEMS::getKey)).toList());
|
export(modid, COLORS.keySet().stream().filter(key -> BuiltInRegistries.ITEM.getKey(key).getNamespace().equals(modid)).sorted(Comparator.comparing(BuiltInRegistries.ITEM::getKey)).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
// The given list should be sorted
|
// The given list should be sorted
|
||||||
|
|
@ -370,13 +367,13 @@ public class CompostColors {
|
||||||
try (var writer = new BufferedWriter(fileWriter)) {
|
try (var writer = new BufferedWriter(fileWriter)) {
|
||||||
// sort file entries alphabetically
|
// sort file entries alphabetically
|
||||||
var alphabeticalItems = new ArrayList<>(sortedToExport);
|
var alphabeticalItems = new ArrayList<>(sortedToExport);
|
||||||
alphabeticalItems.sort(Comparator.comparing(item -> ForgeRegistries.ITEMS.getKey(item).getPath()));
|
alphabeticalItems.sort(Comparator.comparing(item -> BuiltInRegistries.ITEM.getKey(item).getPath()));
|
||||||
|
|
||||||
writer.write("// Compost colors for " + modid + ". You may add your own colors, change existing ones, or remove colors that aren't needed.\n");
|
writer.write("// Compost colors for " + modid + ". You may add your own colors, change existing ones, or remove colors that aren't needed.\n");
|
||||||
|
|
||||||
for (var item : alphabeticalItems) {
|
for (var item : alphabeticalItems) {
|
||||||
if (COLORS.containsKey(item)) {
|
if (COLORS.containsKey(item)) {
|
||||||
writer.write(ForgeRegistries.ITEMS.getKey(item).getPath());
|
writer.write(BuiltInRegistries.ITEM.getKey(item).getPath());
|
||||||
writer.write(", #");
|
writer.write(", #");
|
||||||
var colorVec = COLORS.get(item);
|
var colorVec = COLORS.get(item);
|
||||||
writer.write(Integer.toHexString(new Color(colorVec.x, colorVec.y, colorVec.z).getRGB() & 0xffffff));
|
writer.write(Integer.toHexString(new Color(colorVec.x, colorVec.y, colorVec.z).getRGB() & 0xffffff));
|
||||||
|
|
@ -393,7 +390,7 @@ public class CompostColors {
|
||||||
|
|
||||||
ExDeorum.LOGGER.error("Unable to save compost colors for mod \"{}\"", modid);
|
ExDeorum.LOGGER.error("Unable to save compost colors for mod \"{}\"", modid);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
ExDeorum.LOGGER.error("Encountered exception while trying to save compost colors for mod \"{}\"", modid, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
// todo consider getting rid of this interface
|
||||||
public interface RenderFace {
|
public interface RenderFace {
|
||||||
void renderFlatSpriteLerp(MultiBufferSource buffers, PoseStack stack, float percentage, int r, int g, int b, int light, float edge, float yStart, float yEnd);
|
void renderFlatSpriteLerp(MultiBufferSource buffers, PoseStack stack, float percentage, int r, int g, int b, int light, float edge, float yStart, float yEnd);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ import net.minecraft.client.renderer.texture.TextureAtlas;
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
import net.minecraft.client.resources.model.BakedModel;
|
import net.minecraft.client.resources.model.BakedModel;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.util.Mth;
|
import net.minecraft.util.Mth;
|
||||||
import net.minecraft.util.RandomSource;
|
import net.minecraft.util.RandomSource;
|
||||||
|
|
@ -45,11 +46,9 @@ import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.levelgen.LegacyRandomSource;
|
import net.minecraft.world.level.levelgen.LegacyRandomSource;
|
||||||
import net.minecraft.world.level.material.Fluid;
|
import net.minecraft.world.level.material.Fluid;
|
||||||
import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions;
|
import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions;
|
||||||
import net.minecraftforge.client.model.CompositeModel;
|
import net.neoforged.neoforge.client.model.CompositeModel;
|
||||||
import net.minecraftforge.client.model.data.ModelData;
|
import net.neoforged.neoforge.client.model.data.ModelData;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
|
||||||
import org.joml.Matrix4f;
|
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
import thedarkcolour.exdeorum.ExDeorum;
|
import thedarkcolour.exdeorum.ExDeorum;
|
||||||
import thedarkcolour.exdeorum.client.ter.SieveRenderer;
|
import thedarkcolour.exdeorum.client.ter.SieveRenderer;
|
||||||
|
|
@ -148,7 +147,7 @@ public class RenderUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TextureAtlasSprite getTopTexture(Block block, BakedModel model) {
|
private static TextureAtlasSprite getTopTexture(Block block, BakedModel model) {
|
||||||
var registryName = ForgeRegistries.BLOCKS.getKey(block);
|
var registryName = BuiltInRegistries.BLOCK.getKey(block);
|
||||||
var sprite = blockAtlas.getSprite(registryName.withPrefix("block/"));
|
var sprite = blockAtlas.getSprite(registryName.withPrefix("block/"));
|
||||||
// for stuff like azalea bush, retry to get the top texture
|
// for stuff like azalea bush, retry to get the top texture
|
||||||
if (isMissingTexture(sprite)) {
|
if (isMissingTexture(sprite)) {
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import net.minecraft.util.Mth;
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import thedarkcolour.exdeorum.ExDeorum;
|
import thedarkcolour.exdeorum.ExDeorum;
|
||||||
import thedarkcolour.exdeorum.blockentity.MechanicalHammerMenu;
|
import thedarkcolour.exdeorum.menu.MechanicalHammerMenu;
|
||||||
import thedarkcolour.exdeorum.config.EConfig;
|
import thedarkcolour.exdeorum.config.EConfig;
|
||||||
import thedarkcolour.exdeorum.data.TranslationKeys;
|
import thedarkcolour.exdeorum.data.TranslationKeys;
|
||||||
|
|
||||||
|
|
@ -79,7 +79,7 @@ public class MechanicalHammerScreen extends AbstractContainerScreen<MechanicalHa
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(GuiGraphics graphics, int mx, int my, float pPartialTick) {
|
public void render(GuiGraphics graphics, int mx, int my, float pPartialTick) {
|
||||||
renderBackground(graphics);
|
renderBackground(graphics, mx, my, pPartialTick);
|
||||||
super.render(graphics, mx, my, pPartialTick);
|
super.render(graphics, mx, my, pPartialTick);
|
||||||
renderTooltip(graphics, mx, my);
|
renderTooltip(graphics, mx, my);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ public class MechanicalSieveScreen extends AbstractContainerScreen<MechanicalSie
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(GuiGraphics graphics, int mx, int my, float partialTicks) {
|
public void render(GuiGraphics graphics, int mx, int my, float partialTicks) {
|
||||||
renderBackground(graphics);
|
renderBackground(graphics, mx, my, partialTicks);
|
||||||
super.render(graphics, mx, my, partialTicks);
|
super.render(graphics, mx, my, partialTicks);
|
||||||
renderTooltip(graphics, mx, my);
|
renderTooltip(graphics, mx, my);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,13 +33,13 @@ import net.minecraft.util.Mth;
|
||||||
import net.minecraft.world.inventory.InventoryMenu;
|
import net.minecraft.world.inventory.InventoryMenu;
|
||||||
import net.minecraft.world.item.BlockItem;
|
import net.minecraft.world.item.BlockItem;
|
||||||
import net.minecraft.world.item.ItemDisplayContext;
|
import net.minecraft.world.item.ItemDisplayContext;
|
||||||
import net.minecraft.world.level.material.Fluid;
|
import net.neoforged.neoforge.client.model.data.ModelData;
|
||||||
import net.minecraftforge.client.model.data.ModelData;
|
|
||||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
|
||||||
import thedarkcolour.exdeorum.ExDeorum;
|
import thedarkcolour.exdeorum.ExDeorum;
|
||||||
import thedarkcolour.exdeorum.blockentity.BarrelBlockEntity;
|
import thedarkcolour.exdeorum.blockentity.BarrelBlockEntity;
|
||||||
import thedarkcolour.exdeorum.client.RenderUtil;
|
import thedarkcolour.exdeorum.client.RenderUtil;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class BarrelRenderer implements BlockEntityRenderer<BarrelBlockEntity> {
|
public class BarrelRenderer implements BlockEntityRenderer<BarrelBlockEntity> {
|
||||||
public static final ResourceLocation COMPOST_DIRT_TEXTURE = new ResourceLocation(ExDeorum.ID, "block/compost_dirt");
|
public static final ResourceLocation COMPOST_DIRT_TEXTURE = new ResourceLocation(ExDeorum.ID, "block/compost_dirt");
|
||||||
private final BlockRenderDispatcher blockRenderer;
|
private final BlockRenderDispatcher blockRenderer;
|
||||||
|
|
@ -63,6 +63,7 @@ public class BarrelRenderer implements BlockEntityRenderer<BarrelBlockEntity> {
|
||||||
stack.translate(2 / 16f, 2 / 16f, 2 / 16f);
|
stack.translate(2 / 16f, 2 / 16f, 2 / 16f);
|
||||||
stack.scale(12 / 16f, 12 / 16f, 12 / 16f);
|
stack.scale(12 / 16f, 12 / 16f, 12 / 16f);
|
||||||
|
|
||||||
|
//noinspection DataFlowIssue
|
||||||
this.blockRenderer.renderSingleBlock(state, stack, buffers, light, overlay, ModelData.EMPTY, null);
|
this.blockRenderer.renderSingleBlock(state, stack, buffers, light, overlay, ModelData.EMPTY, null);
|
||||||
|
|
||||||
stack.popPose();
|
stack.popPose();
|
||||||
|
|
@ -74,37 +75,36 @@ public class BarrelRenderer implements BlockEntityRenderer<BarrelBlockEntity> {
|
||||||
stack.popPose();
|
stack.popPose();
|
||||||
}
|
}
|
||||||
|
|
||||||
barrel.getCapability(ForgeCapabilities.FLUID_HANDLER).ifPresent(tank -> {
|
var tank = barrel.getTank();
|
||||||
var fluidStack = tank.getFluidInTank(0);
|
var fluidStack = tank.getFluidInTank(0);
|
||||||
|
|
||||||
if (!fluidStack.isEmpty()) { // Get texture
|
if (!fluidStack.isEmpty()) { // Get texture
|
||||||
var fluid = fluidStack.getFluid();
|
var fluid = fluidStack.getFluid();
|
||||||
var level = barrel.getLevel();
|
var level = Objects.requireNonNull(barrel.getLevel());
|
||||||
var pos = barrel.getBlockPos();
|
var pos = barrel.getBlockPos();
|
||||||
var percentage = fluidStack.getAmount() / 1000.0f;
|
var percentage = fluidStack.getAmount() / 1000.0f;
|
||||||
var y = Mth.lerp(percentage, 1.0f, 14.0f) / 16f;
|
var y = Mth.lerp(percentage, 1.0f, 14.0f) / 16f;
|
||||||
var inputFluidColor = RenderUtil.getFluidColor(fluid, level, pos);
|
var inputFluidColor = RenderUtil.getFluidColor(fluid, level, pos);
|
||||||
// Split into RGB components
|
// Split into RGB components
|
||||||
var r = (inputFluidColor >> 16) & 0xff;
|
var r = (inputFluidColor >> 16) & 0xff;
|
||||||
var g = (inputFluidColor >> 8) & 0xff;
|
var g = (inputFluidColor >> 8) & 0xff;
|
||||||
var b = inputFluidColor & 0xff;
|
var b = inputFluidColor & 0xff;
|
||||||
|
|
||||||
if (barrel.isBrewing()) {
|
if (barrel.isBrewing()) {
|
||||||
float progress = barrel.progress;
|
float progress = barrel.progress;
|
||||||
|
|
||||||
// Transition between water color and witch water color (200B41)
|
// Transition between water color and witch water color (200B41)
|
||||||
r = (int) Mth.lerp(progress, r, barrel.r);
|
r = (int) Mth.lerp(progress, r, barrel.r);
|
||||||
g = (int) Mth.lerp(progress, g, barrel.g);
|
g = (int) Mth.lerp(progress, g, barrel.g);
|
||||||
b = (int) Mth.lerp(progress, b, barrel.b);
|
b = (int) Mth.lerp(progress, b, barrel.b);
|
||||||
}
|
|
||||||
|
|
||||||
if (barrel.transparent) {
|
|
||||||
RenderUtil.renderFluidCube(buffers, stack, level, pos, 1 / 16f, y, 2.0f, light, r, g, b, fluid);
|
|
||||||
} else {
|
|
||||||
RenderUtil.renderFlatFluidSprite(buffers, stack, level, pos, y, 2.0f, light, r, g, b, fluid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
if (barrel.transparent) {
|
||||||
|
RenderUtil.renderFluidCube(buffers, stack, level, pos, 1 / 16f, y, 2.0f, light, r, g, b, fluid);
|
||||||
|
} else {
|
||||||
|
RenderUtil.renderFlatFluidSprite(buffers, stack, level, pos, y, 2.0f, light, r, g, b, fluid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// render compost
|
// render compost
|
||||||
if (barrel.compost > 0) {
|
if (barrel.compost > 0) {
|
||||||
|
|
@ -126,9 +126,9 @@ public class BarrelRenderer implements BlockEntityRenderer<BarrelBlockEntity> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transition between default green and dirt brown
|
// Transition between default green and dirt brown
|
||||||
r = (int) Mth.lerp(compostProgress, r, 238); // default green is
|
r = (int) Mth.lerp(compostProgress, r, 238); // default green is
|
||||||
g = (int) Mth.lerp(compostProgress, g, 169); // default green is
|
g = (int) Mth.lerp(compostProgress, g, 169); // default green is
|
||||||
b = (int) Mth.lerp(compostProgress, b, 109); // default green is
|
b = (int) Mth.lerp(compostProgress, b, 109); // default green is
|
||||||
|
|
||||||
RenderUtil.renderFlatSpriteLerp(builder, stack, barrel.compost / 1000.0f, r, g, b, sprite, light, 2.0f, 1.0f, 14.0f);
|
RenderUtil.renderFlatSpriteLerp(builder, stack, barrel.compost / 1000.0f, r, g, b, sprite, light, 2.0f, 1.0f, 14.0f);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,51 +23,48 @@ import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.MultiBufferSource;
|
import net.minecraft.client.renderer.MultiBufferSource;
|
||||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
||||||
import net.minecraft.util.Mth;
|
import net.minecraft.util.Mth;
|
||||||
import net.minecraft.world.level.block.Block;
|
|
||||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
|
||||||
import thedarkcolour.exdeorum.blockentity.AbstractCrucibleBlockEntity;
|
import thedarkcolour.exdeorum.blockentity.AbstractCrucibleBlockEntity;
|
||||||
import thedarkcolour.exdeorum.client.RenderUtil;
|
import thedarkcolour.exdeorum.client.RenderUtil;
|
||||||
|
|
||||||
public class CrucibleRenderer implements BlockEntityRenderer<AbstractCrucibleBlockEntity> {
|
public class CrucibleRenderer implements BlockEntityRenderer<AbstractCrucibleBlockEntity> {
|
||||||
@Override
|
@Override
|
||||||
public void render(AbstractCrucibleBlockEntity crucible, float partialTicks, PoseStack stack, MultiBufferSource buffers, int light, int overlay) {
|
public void render(AbstractCrucibleBlockEntity crucible, float partialTicks, PoseStack stack, MultiBufferSource buffers, int light, int overlay) {
|
||||||
crucible.getCapability(ForgeCapabilities.FLUID_HANDLER).ifPresent(tank -> {
|
var tank = crucible.getTank();
|
||||||
var level = crucible.getLevel();
|
var level = crucible.getLevel();
|
||||||
if (level == null) return;
|
if (level == null) return;
|
||||||
|
|
||||||
var fluidStack = tank.getFluidInTank(0);
|
var fluidStack = tank.getFluidInTank(0);
|
||||||
|
|
||||||
// These are percentages
|
// These are percentages
|
||||||
var solids = (float) crucible.getSolids() / (float) AbstractCrucibleBlockEntity.MAX_SOLIDS;
|
var solids = (float) crucible.getSolids() / (float) AbstractCrucibleBlockEntity.MAX_SOLIDS;
|
||||||
var liquid = (float) fluidStack.getAmount() / (float) tank.getTankCapacity(0);
|
var liquid = (float) fluidStack.getAmount() / (float) tank.getTankCapacity(0);
|
||||||
|
|
||||||
if (solids != 0 || liquid != 0) {
|
if (solids != 0 || liquid != 0) {
|
||||||
var pos = crucible.getBlockPos();
|
var pos = crucible.getBlockPos();
|
||||||
|
|
||||||
if (liquid != 0) {
|
if (liquid != 0) {
|
||||||
var fluid = fluidStack.getFluid();
|
var fluid = fluidStack.getFluid();
|
||||||
var color = RenderUtil.getFluidColor(fluid, level, pos);
|
var color = RenderUtil.getFluidColor(fluid, level, pos);
|
||||||
float y = Mth.lerp(liquid, 4.0f, 14.0f) / 16f;
|
float y = Mth.lerp(liquid, 4.0f, 14.0f) / 16f;
|
||||||
|
|
||||||
RenderUtil.renderFlatFluidSprite(buffers, stack, level, pos, y, 2.0f, light, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff, fluid);
|
RenderUtil.renderFlatFluidSprite(buffers, stack, level, pos, y, 2.0f, light, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff, fluid);
|
||||||
}
|
|
||||||
if (solids != 0) {
|
|
||||||
// eating my words rn :(
|
|
||||||
var lastMelted = crucible.getLastMelted();
|
|
||||||
if (lastMelted == null) {
|
|
||||||
lastMelted = crucible.getDefaultMeltBlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
var face = RenderUtil.getTopFaceOrDefault(lastMelted, crucible.getDefaultMeltBlock());
|
|
||||||
|
|
||||||
var color = Minecraft.getInstance().getBlockColors().getColor(lastMelted.defaultBlockState(), level, pos, 0);
|
|
||||||
|
|
||||||
if (color == -1) color = 0xffffff;
|
|
||||||
|
|
||||||
face.renderFlatSpriteLerp(buffers, stack, solids, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff, light, 2.0f, 4.0f, 14.0f);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
if (solids != 0) {
|
||||||
|
// eating my words rn :(
|
||||||
|
var lastMelted = crucible.getLastMelted();
|
||||||
|
if (lastMelted == null) {
|
||||||
|
lastMelted = crucible.getDefaultMeltBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
var face = RenderUtil.getTopFaceOrDefault(lastMelted, crucible.getDefaultMeltBlock());
|
||||||
|
|
||||||
|
var color = Minecraft.getInstance().getBlockColors().getColor(lastMelted.defaultBlockState(), level, pos, 0);
|
||||||
|
|
||||||
|
if (color == -1) color = 0xffffff;
|
||||||
|
|
||||||
|
face.renderFlatSpriteLerp(buffers, stack, solids, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff, light, 2.0f, 4.0f, 14.0f);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.MultiBufferSource;
|
import net.minecraft.client.renderer.MultiBufferSource;
|
||||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
import net.minecraftforge.client.model.data.ModelData;
|
import net.neoforged.neoforge.client.model.data.ModelData;
|
||||||
import thedarkcolour.exdeorum.blockentity.InfestedLeavesBlockEntity;
|
import thedarkcolour.exdeorum.blockentity.InfestedLeavesBlockEntity;
|
||||||
import thedarkcolour.exdeorum.client.RenderUtil;
|
import thedarkcolour.exdeorum.client.RenderUtil;
|
||||||
import thedarkcolour.exdeorum.config.EConfig;
|
import thedarkcolour.exdeorum.config.EConfig;
|
||||||
|
|
@ -46,7 +46,7 @@ public class InfestedLeavesRenderer implements BlockEntityRenderer<InfestedLeave
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get infested percentage
|
// Get infested percentage
|
||||||
int progress = Math.min((int) (te.getProgress() * 16000), 16000);
|
int progress = Math.min(te.getProgress(), 16000);
|
||||||
// Render
|
// Render
|
||||||
var model = mc.getBlockRenderer().getBlockModel(state);
|
var model = mc.getBlockRenderer().getBlockModel(state);
|
||||||
var pos = te.getBlockPos();
|
var pos = te.getBlockPos();
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,6 @@ public class SieveRenderer<T extends EBlockEntity & SieveLogic.Owner> implements
|
||||||
if (MESH_TEXTURES.containsKey(meshItem)) {
|
if (MESH_TEXTURES.containsKey(meshItem)) {
|
||||||
meshSprite = MESH_TEXTURES.get(meshItem);
|
meshSprite = MESH_TEXTURES.get(meshItem);
|
||||||
} else {
|
} else {
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
ResourceLocation registryName = BuiltInRegistries.ITEM.getKey(meshItem);
|
ResourceLocation registryName = BuiltInRegistries.ITEM.getKey(meshItem);
|
||||||
ResourceLocation textureLoc = registryName.withPrefix("item/mesh/");
|
ResourceLocation textureLoc = registryName.withPrefix("item/mesh/");
|
||||||
meshSprite = RenderUtil.blockAtlas.getSprite(textureLoc);
|
meshSprite = RenderUtil.blockAtlas.getSprite(textureLoc);
|
||||||
|
|
|
||||||
|
|
@ -18,15 +18,25 @@
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.compat;
|
package thedarkcolour.exdeorum.compat;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.world.Container;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraftforge.fml.ModList;
|
import net.minecraft.world.item.crafting.Recipe;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeHolder;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeType;
|
||||||
|
import net.neoforged.fml.ModList;
|
||||||
import thedarkcolour.exdeorum.material.DefaultMaterials;
|
import thedarkcolour.exdeorum.material.DefaultMaterials;
|
||||||
|
import thedarkcolour.exdeorum.recipe.sieve.SieveRecipe;
|
||||||
import thedarkcolour.exdeorum.registry.EItems;
|
import thedarkcolour.exdeorum.registry.EItems;
|
||||||
|
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class CompatHelper {
|
public class CompatUtil {
|
||||||
public static List<Item> getAvailableBarrels(boolean registered) {
|
public static List<Item> getAvailableBarrels(boolean registered) {
|
||||||
List<Item> barrels = new ArrayList<>();
|
List<Item> barrels = new ArrayList<>();
|
||||||
for (var material : DefaultMaterials.BARRELS) {
|
for (var material : DefaultMaterials.BARRELS) {
|
||||||
|
|
@ -72,7 +82,15 @@ public class CompatHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return waterCrucibles;
|
return waterCrucibles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <C extends Container, R extends Recipe<C>, T> List<T> collectAllRecipes(RecipeType<R> recipeType, Function<R, T> mapper) {
|
||||||
|
var byType = Objects.requireNonNull(Minecraft.getInstance().level).getRecipeManager().byType(recipeType).values();
|
||||||
|
List<T> recipes = new ObjectArrayList<>(byType.size());
|
||||||
|
for (RecipeHolder<R> value : byType) {
|
||||||
|
recipes.add(mapper.apply(value.value()));
|
||||||
|
}
|
||||||
|
return recipes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -21,23 +21,27 @@ package thedarkcolour.exdeorum.compat;
|
||||||
import com.google.common.collect.ArrayListMultimap;
|
import com.google.common.collect.ArrayListMultimap;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.util.Mth;
|
import net.minecraft.util.Mth;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.crafting.Ingredient;
|
import net.minecraft.world.item.crafting.Ingredient;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeHolder;
|
||||||
import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
|
import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
|
||||||
import net.minecraft.world.level.storage.loot.providers.number.NumberProvider;
|
import net.minecraft.world.level.storage.loot.providers.number.NumberProvider;
|
||||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
||||||
import thedarkcolour.exdeorum.recipe.sieve.SieveRecipe;
|
import thedarkcolour.exdeorum.recipe.sieve.SieveRecipe;
|
||||||
import thedarkcolour.exdeorum.registry.EItems;
|
import thedarkcolour.exdeorum.registry.EItems;
|
||||||
|
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
||||||
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
// Since no JEI code is used here, this can be reused for REI
|
// Since no JEI code is used here, this can be reused for REI
|
||||||
public record GroupedSieveRecipe(Ingredient ingredient, ItemStack mesh, List<Result> results) {
|
public record GroupedSieveRecipe(Ingredient ingredient, ItemStack mesh, List<Result> results) {
|
||||||
|
|
@ -46,8 +50,7 @@ public record GroupedSieveRecipe(Ingredient ingredient, ItemStack mesh, List<Res
|
||||||
public static ImmutableList<GroupedSieveRecipe> getAllRecipesGrouped() {
|
public static ImmutableList<GroupedSieveRecipe> getAllRecipesGrouped() {
|
||||||
maxSieveRows = 1;
|
maxSieveRows = 1;
|
||||||
|
|
||||||
// copy the list so we can do removals
|
var recipes = CompatUtil.collectAllRecipes(ERecipeTypes.SIEVE.value(), Function.identity());
|
||||||
List<SieveRecipe> recipes = new ArrayList<>(Objects.requireNonNull(Minecraft.getInstance().level).getRecipeManager().getAllRecipesFor(ERecipeTypes.SIEVE.get()));
|
|
||||||
Multimap<Ingredient, SieveRecipe> ingredientGrouper = ArrayListMultimap.create();
|
Multimap<Ingredient, SieveRecipe> ingredientGrouper = ArrayListMultimap.create();
|
||||||
|
|
||||||
for (int i = 0; i < recipes.size(); i++) {
|
for (int i = 0; i < recipes.size(); i++) {
|
||||||
|
|
@ -91,7 +94,7 @@ public record GroupedSieveRecipe(Ingredient ingredient, ItemStack mesh, List<Res
|
||||||
var results = new ArrayList<Result>(meshRecipes.size());
|
var results = new ArrayList<Result>(meshRecipes.size());
|
||||||
|
|
||||||
for (var recipe : meshRecipes) {
|
for (var recipe : meshRecipes) {
|
||||||
int resultCount = recipe.resultAmount instanceof ConstantValue constant ? Math.round(constant.value) : 1;
|
int resultCount = recipe.resultAmount instanceof ConstantValue constant ? Math.round(constant.value()) : 1;
|
||||||
results.add(new Result(new ItemStack(recipe.result, resultCount), recipe.resultAmount, recipe.byHandOnly));
|
results.add(new Result(new ItemStack(recipe.result, resultCount), recipe.resultAmount, recipe.byHandOnly));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -109,7 +112,6 @@ public record GroupedSieveRecipe(Ingredient ingredient, ItemStack mesh, List<Res
|
||||||
return jeiRecipes.build();
|
return jeiRecipes.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
private static int meshOrder(Item mesh) {
|
private static int meshOrder(Item mesh) {
|
||||||
if (mesh == EItems.STRING_MESH.get()) {
|
if (mesh == EItems.STRING_MESH.get()) {
|
||||||
return -5;
|
return -5;
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,8 @@ import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.tags.TagKey;
|
import net.minecraft.tags.TagKey;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.Items;
|
import net.minecraft.world.item.Items;
|
||||||
import net.minecraftforge.common.ForgeConfigSpec;
|
import net.neoforged.fml.ModList;
|
||||||
import net.minecraftforge.fml.ModList;
|
import net.neoforged.neoforge.common.ModConfigSpec;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
|
||||||
import thedarkcolour.exdeorum.ExDeorum;
|
import thedarkcolour.exdeorum.ExDeorum;
|
||||||
import thedarkcolour.exdeorum.config.EConfig;
|
import thedarkcolour.exdeorum.config.EConfig;
|
||||||
import thedarkcolour.exdeorum.tag.EItemTags;
|
import thedarkcolour.exdeorum.tag.EItemTags;
|
||||||
|
|
@ -67,13 +66,12 @@ public class PreferredOres {
|
||||||
* @param config A config which holds an override value chosen by the user. Could even be something that isn't an ore.
|
* @param config A config which holds an override value chosen by the user. Could even be something that isn't an ore.
|
||||||
* @param defaultOre The default ore choice, picked by Ex Deorum based on which mod is the "best" choice according to thedarkcolour.
|
* @param defaultOre The default ore choice, picked by Ex Deorum based on which mod is the "best" choice according to thedarkcolour.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
private static void putPreferredOre(TagKey<Item> tag, ModConfigSpec.ConfigValue<String> config, Item defaultOre) {
|
||||||
private static void putPreferredOre(TagKey<Item> tag, ForgeConfigSpec.ConfigValue<String> config, Item defaultOre) {
|
var item = BuiltInRegistries.ITEM.get(new ResourceLocation(config.get()));
|
||||||
var item = ForgeRegistries.ITEMS.getValue(new ResourceLocation(config.get()));
|
|
||||||
|
|
||||||
if (item == Items.AIR) {
|
if (item == Items.AIR) {
|
||||||
item = defaultOre;
|
item = defaultOre;
|
||||||
ExDeorum.LOGGER.debug("No preferred ore was set for tag {}. Using default choice {}", tag.location(), item.builtInRegistryHolder().key().location());
|
ExDeorum.LOGGER.debug("No preferred ore was set for tag {}. Using default choice {}", tag.location(), BuiltInRegistries.ITEM.getKey(item));
|
||||||
}
|
}
|
||||||
PREFERRED_ORE_ITEMS.put(tag, defaultOre);
|
PREFERRED_ORE_ITEMS.put(tag, defaultOre);
|
||||||
}
|
}
|
||||||
|
|
@ -84,7 +82,6 @@ public class PreferredOres {
|
||||||
* @return The preferred (as specified by config, or by alphabetical order)
|
* @return The preferred (as specified by config, or by alphabetical order)
|
||||||
* item from the given tag or {@link Items#AIR} if the tag is empty.
|
* item from the given tag or {@link Items#AIR} if the tag is empty.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public static Item getPreferredOre(TagKey<Item> tag) {
|
public static Item getPreferredOre(TagKey<Item> tag) {
|
||||||
Item preferred = PREFERRED_ORE_ITEMS.get(tag);
|
Item preferred = PREFERRED_ORE_ITEMS.get(tag);
|
||||||
|
|
||||||
|
|
@ -96,10 +93,10 @@ public class PreferredOres {
|
||||||
if (collection.isEmpty()) {
|
if (collection.isEmpty()) {
|
||||||
return Items.AIR;
|
return Items.AIR;
|
||||||
} else {
|
} else {
|
||||||
collection.sort(Comparator.comparing(holder -> BuiltInRegistries.ITEM.getKey(holder.get())));
|
collection.sort(Comparator.comparing(holder -> BuiltInRegistries.ITEM.getKey(holder.value())));
|
||||||
|
|
||||||
// todo should the PREFERRED_ORE map be updated with this value?
|
// todo should the PREFERRED_ORE map be updated with this value?
|
||||||
return collection.get(0).get();
|
return collection.get(0).value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -175,9 +172,9 @@ public class PreferredOres {
|
||||||
|
|
||||||
if (modId != null) {
|
if (modId != null) {
|
||||||
if (modId.equals(ModIds.FACTORIUM)) {
|
if (modId.equals(ModIds.FACTORIUM)) {
|
||||||
return ForgeRegistries.ITEMS.getValue(new ResourceLocation(modId, "mat_" + path));
|
return BuiltInRegistries.ITEM.get(new ResourceLocation(modId, "mat_" + path));
|
||||||
} else {
|
} else {
|
||||||
return ForgeRegistries.ITEMS.getValue(new ResourceLocation(modId, path));
|
return BuiltInRegistries.ITEM.get(new ResourceLocation(modId, path));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Items.AIR;
|
return Items.AIR;
|
||||||
|
|
|
||||||
|
|
@ -108,12 +108,12 @@ public abstract class BarrelMixingCategory<T> implements IRecipeCategory<T> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setRecipe(IRecipeLayoutBuilder builder, BarrelFluidMixingRecipe recipe, IFocusGroup focuses) {
|
public void setRecipe(IRecipeLayoutBuilder builder, BarrelFluidMixingRecipe recipe, IFocusGroup focuses) {
|
||||||
builder.addSlot(RecipeIngredientRole.INPUT, 1, 1).addFluidStack(recipe.baseFluid, recipe.baseFluidAmount).setFluidRenderer(1000, false, 16, 16);
|
builder.addSlot(RecipeIngredientRole.INPUT, 1, 1).addFluidStack(recipe.baseFluid(), recipe.baseFluidAmount()).setFluidRenderer(1000, false, 16, 16);
|
||||||
IRecipeSlotBuilder additiveSlot = builder.addSlot(RecipeIngredientRole.INPUT, 33, 1).addFluidStack(recipe.additiveFluid, 1000).setFluidRenderer(1000, false, 16, 16);
|
IRecipeSlotBuilder additiveSlot = builder.addSlot(RecipeIngredientRole.INPUT, 33, 1).addFluidStack(recipe.additiveFluid(), 1000).setFluidRenderer(1000, false, 16, 16);
|
||||||
if (recipe.consumesAdditive) {
|
if (recipe.consumesAdditive()) {
|
||||||
additiveSlot.addTooltipCallback((view, tooltip) -> tooltip.add(CONTENTS_ARE_CONSUMED_TOOLTIP));
|
additiveSlot.addTooltipCallback((view, tooltip) -> tooltip.add(CONTENTS_ARE_CONSUMED_TOOLTIP));
|
||||||
}
|
}
|
||||||
builder.addSlot(RecipeIngredientRole.OUTPUT, 79, 1).addItemStack(new ItemStack(recipe.result));
|
builder.addSlot(RecipeIngredientRole.OUTPUT, 79, 1).addItemStack(new ItemStack(recipe.result()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -125,7 +125,7 @@ public abstract class BarrelMixingCategory<T> implements IRecipeCategory<T> {
|
||||||
public void draw(BarrelFluidMixingRecipe recipe, IRecipeSlotsView recipeSlotsView, GuiGraphics graphics, double mouseX, double mouseY) {
|
public void draw(BarrelFluidMixingRecipe recipe, IRecipeSlotsView recipeSlotsView, GuiGraphics graphics, double mouseX, double mouseY) {
|
||||||
super.draw(recipe, recipeSlotsView, graphics, mouseX, mouseY);
|
super.draw(recipe, recipeSlotsView, graphics, mouseX, mouseY);
|
||||||
|
|
||||||
if (recipe.consumesAdditive) {
|
if (recipe.consumesAdditive()) {
|
||||||
ClientJeiUtil.renderAsterisk(graphics, 18 + 3 + 3 + 8, 0);
|
ClientJeiUtil.renderAsterisk(graphics, 18 + 3 + 3 + 8, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.mojang.blaze3d.vertex.Tesselator;
|
import com.mojang.blaze3d.vertex.Tesselator;
|
||||||
import com.mojang.math.Axis;
|
import com.mojang.math.Axis;
|
||||||
import me.shedaniel.rei.api.client.view.ViewSearchBuilder;
|
import me.shedaniel.rei.api.client.view.ViewSearchBuilder;
|
||||||
import me.shedaniel.rei.jeicompat.JEIPluginDetector;
|
|
||||||
import mezz.jei.api.ingredients.IIngredientRenderer;
|
import mezz.jei.api.ingredients.IIngredientRenderer;
|
||||||
import mezz.jei.api.ingredients.IIngredientType;
|
import mezz.jei.api.ingredients.IIngredientType;
|
||||||
import mezz.jei.api.ingredients.ITypedIngredient;
|
import mezz.jei.api.ingredients.ITypedIngredient;
|
||||||
|
|
@ -62,8 +61,8 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.lighting.LevelLightEngine;
|
import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||||
import net.minecraft.world.level.material.FluidState;
|
import net.minecraft.world.level.material.FluidState;
|
||||||
import net.minecraft.world.level.material.Fluids;
|
import net.minecraft.world.level.material.Fluids;
|
||||||
import net.minecraftforge.fluids.FluidStack;
|
import net.neoforged.fml.ModList;
|
||||||
import net.minecraftforge.fml.ModList;
|
import net.neoforged.neoforge.fluids.FluidStack;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
@ -194,31 +193,33 @@ class ClientJeiUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Required due to broken JEI implementation in REI plugin compatibility
|
// Required due to broken JEI implementation in REI plugin compatibility
|
||||||
public static <T> void checkTypedIngredient(IIngredientManager manager, IIngredientType<T> ingredientType, T uncheckedIngredient, Consumer<ITypedIngredient<T>> action) {
|
static <T> void checkTypedIngredient(IIngredientManager manager, IIngredientType<T> ingredientType, @Nullable T uncheckedIngredient, Consumer<ITypedIngredient<T>> action) {
|
||||||
if ((uncheckedIngredient instanceof ItemStack stack && !stack.isEmpty()) || (uncheckedIngredient instanceof FluidStack fluidStack && !fluidStack.isEmpty())) {
|
if ((uncheckedIngredient instanceof ItemStack stack && !stack.isEmpty()) || (uncheckedIngredient instanceof FluidStack fluidStack && !fluidStack.isEmpty())) {
|
||||||
manager.createTypedIngredient(ingredientType, uncheckedIngredient).ifPresent(action);
|
manager.createTypedIngredient(ingredientType, uncheckedIngredient).ifPresent(action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> void showRecipes(IFocusFactory focusFactory, ITypedIngredient<T> ingredient) {
|
static <T> void showRecipes(IFocusFactory focusFactory, ITypedIngredient<T> ingredient) {
|
||||||
if (Minecraft.getInstance().screen instanceof IRecipesGui recipesGui) {
|
if (Minecraft.getInstance().screen instanceof IRecipesGui recipesGui) {
|
||||||
recipesGui.show(focusFactory.createFocus(RecipeIngredientRole.OUTPUT, ingredient));
|
recipesGui.show(focusFactory.createFocus(RecipeIngredientRole.OUTPUT, ingredient));
|
||||||
} else if (ModList.get().isLoaded(ModIds.REI_PC)) {
|
} else if (ModList.get().isLoaded(ModIds.REI_PC)) {
|
||||||
ViewSearchBuilder.builder().addRecipesFor(JEIPluginDetector.unwrapStack(ingredient)).open();
|
// todo fix when REIPC is on 1.20.4
|
||||||
|
//ViewSearchBuilder.builder().addRecipesFor(JEIPluginDetector.unwrapStack(ingredient)).open();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> void showUsages(IFocusFactory focusFactory, ITypedIngredient<T> ingredient) {
|
static <T> void showUsages(IFocusFactory focusFactory, ITypedIngredient<T> ingredient) {
|
||||||
if (Minecraft.getInstance().screen instanceof IRecipesGui recipesGui) {
|
if (Minecraft.getInstance().screen instanceof IRecipesGui recipesGui) {
|
||||||
// input + catalyst
|
// input + catalyst
|
||||||
recipesGui.show(List.of(focusFactory.createFocus(RecipeIngredientRole.INPUT, ingredient), focusFactory.createFocus(RecipeIngredientRole.CATALYST, ingredient)));
|
recipesGui.show(List.of(focusFactory.createFocus(RecipeIngredientRole.INPUT, ingredient), focusFactory.createFocus(RecipeIngredientRole.CATALYST, ingredient)));
|
||||||
} else if (ModList.get().isLoaded(ModIds.REI_PC)) {
|
} else if (ModList.get().isLoaded(ModIds.REI_PC)) {
|
||||||
ViewSearchBuilder.builder().addUsagesFor(JEIPluginDetector.unwrapStack(ingredient)).open();
|
// todo fix when REIPC is on 1.20.4
|
||||||
|
//ViewSearchBuilder.builder().addUsagesFor(JEIPluginDetector.unwrapStack(ingredient)).open();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes a decimal probability and returns a user-friendly percentage value
|
// Takes a decimal probability and returns a user-friendly percentage value
|
||||||
public static Component formatChance(double probability) {
|
static Component formatChance(double probability) {
|
||||||
var chance = FORMATTER.format(probability * 100);
|
var chance = FORMATTER.format(probability * 100);
|
||||||
return Component.translatable(TranslationKeys.SIEVE_RECIPE_CHANCE, chance).withStyle(ChatFormatting.GRAY);
|
return Component.translatable(TranslationKeys.SIEVE_RECIPE_CHANCE, chance).withStyle(ChatFormatting.GRAY);
|
||||||
}
|
}
|
||||||
|
|
@ -239,6 +240,7 @@ class ClientJeiUtil {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("DataFlowIssue")
|
||||||
@Override
|
@Override
|
||||||
public LevelLightEngine getLightEngine() {
|
public LevelLightEngine getLightEngine() {
|
||||||
return Minecraft.getInstance().level.getLightEngine();
|
return Minecraft.getInstance().level.getLightEngine();
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,8 @@ import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.util.RandomSource;
|
import net.minecraft.util.RandomSource;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraftforge.client.RenderTypeHelper;
|
import net.neoforged.neoforge.client.RenderTypeHelper;
|
||||||
import net.minecraftforge.client.model.data.ModelData;
|
import net.neoforged.neoforge.client.model.data.ModelData;
|
||||||
import thedarkcolour.exdeorum.data.TranslationKeys;
|
import thedarkcolour.exdeorum.data.TranslationKeys;
|
||||||
import thedarkcolour.exdeorum.registry.EBlocks;
|
import thedarkcolour.exdeorum.registry.EBlocks;
|
||||||
import thedarkcolour.exdeorum.registry.EItems;
|
import thedarkcolour.exdeorum.registry.EItems;
|
||||||
|
|
@ -124,7 +124,8 @@ public class CrookCategory implements IRecipeCategory<CrookJeiRecipe> {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
ClientJeiUtil.renderBlock(graphics, state, 28, 18, 10, 20f, (block, poseStack, buffers) -> {
|
ClientJeiUtil.renderBlock(graphics, state, 28, 18, 10, 20f, (block, poseStack, buffers) -> {
|
||||||
Minecraft.getInstance().getBlockRenderer().renderSingleBlock(block, poseStack, buffers, 15728880, OverlayTexture.NO_OVERLAY);
|
//noinspection DataFlowIssue
|
||||||
|
Minecraft.getInstance().getBlockRenderer().renderSingleBlock(block, poseStack, buffers, 15728880, OverlayTexture.NO_OVERLAY, ModelData.EMPTY, null);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,11 @@ package thedarkcolour.exdeorum.compat.jei;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
import com.mojang.serialization.JsonOps;
|
||||||
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
|
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
|
||||||
import mezz.jei.api.recipe.RecipeIngredientRole;
|
import mezz.jei.api.recipe.RecipeIngredientRole;
|
||||||
import net.minecraft.ChatFormatting;
|
import net.minecraft.ChatFormatting;
|
||||||
|
import net.minecraft.advancements.critereon.StatePropertiesPredicate;
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.tags.TagKey;
|
import net.minecraft.tags.TagKey;
|
||||||
|
|
@ -34,6 +36,7 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import thedarkcolour.exdeorum.recipe.BlockPredicate;
|
import thedarkcolour.exdeorum.recipe.BlockPredicate;
|
||||||
|
import thedarkcolour.exdeorum.recipe.CodecUtil;
|
||||||
import thedarkcolour.exdeorum.recipe.crook.CrookRecipe;
|
import thedarkcolour.exdeorum.recipe.crook.CrookRecipe;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
@ -99,7 +102,7 @@ public sealed abstract class CrookJeiRecipe {
|
||||||
|
|
||||||
ImmutableList.Builder<Component> requirements = ImmutableList.builder();
|
ImmutableList.Builder<Component> requirements = ImmutableList.builder();
|
||||||
if (predicate != null) {
|
if (predicate != null) {
|
||||||
var json = predicate.properties().serializeToJson();
|
var json = CodecUtil.encode(StatePropertiesPredicate.CODEC, predicate.properties());
|
||||||
if (json instanceof JsonObject obj) {
|
if (json instanceof JsonObject obj) {
|
||||||
for (var entry : obj.entrySet()) {
|
for (var entry : obj.entrySet()) {
|
||||||
requirements.add(Component.literal(" " + entry.getKey() + "=" + entry.getValue().toString()).withStyle(ChatFormatting.GRAY));
|
requirements.add(Component.literal(" " + entry.getKey() + "=" + entry.getValue().toString()).withStyle(ChatFormatting.GRAY));
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ final class CrucibleHeatSourceRecipe {
|
||||||
@Nullable
|
@Nullable
|
||||||
private final Object ingredient;
|
private final Object ingredient;
|
||||||
|
|
||||||
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
CrucibleHeatSourceRecipe(int meltRate, BlockState blockState, @Nullable IIngredientType ingredientType, @Nullable Object ingredient) {
|
CrucibleHeatSourceRecipe(int meltRate, BlockState blockState, @Nullable IIngredientType ingredientType, @Nullable Object ingredient) {
|
||||||
this.meltRate = meltRate;
|
this.meltRate = meltRate;
|
||||||
this.blockState = blockState;
|
this.blockState = blockState;
|
||||||
|
|
|
||||||
|
|
@ -34,10 +34,10 @@ import mezz.jei.api.runtime.IIngredientManager;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.GuiGraphics;
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||||
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.TooltipFlag;
|
import net.minecraft.world.item.TooltipFlag;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
|
||||||
import thedarkcolour.exdeorum.data.TranslationKeys;
|
import thedarkcolour.exdeorum.data.TranslationKeys;
|
||||||
import thedarkcolour.exdeorum.material.DefaultMaterials;
|
import thedarkcolour.exdeorum.material.DefaultMaterials;
|
||||||
|
|
||||||
|
|
@ -88,7 +88,7 @@ class CrucibleHeatSourcesCategory implements IRecipeCategory<CrucibleHeatSourceR
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setRecipe(IRecipeLayoutBuilder builder, CrucibleHeatSourceRecipe recipe, IFocusGroup focuses) {
|
public void setRecipe(IRecipeLayoutBuilder builder, CrucibleHeatSourceRecipe recipe, IFocusGroup focuses) {
|
||||||
if (recipe.ingredientType() != null) {
|
if (recipe.ingredientType() != null && recipe.ingredient() != null) {
|
||||||
builder.addInvisibleIngredients(RecipeIngredientRole.INPUT).addIngredient(recipe.ingredientType(), recipe.ingredient());
|
builder.addInvisibleIngredients(RecipeIngredientRole.INPUT).addIngredient(recipe.ingredientType(), recipe.ingredient());
|
||||||
} else {
|
} else {
|
||||||
builder.addInvisibleIngredients(RecipeIngredientRole.INPUT).addIngredient(VanillaTypes.ITEM_STACK, ItemStack.EMPTY);
|
builder.addInvisibleIngredients(RecipeIngredientRole.INPUT).addIngredient(VanillaTypes.ITEM_STACK, ItemStack.EMPTY);
|
||||||
|
|
@ -104,6 +104,7 @@ class CrucibleHeatSourcesCategory implements IRecipeCategory<CrucibleHeatSourceR
|
||||||
graphics.drawString(font, volumeLabel, 60 - font.width(volumeLabel) / 2, 5, 0xff808080, false);
|
graphics.drawString(font, volumeLabel, 60 - font.width(volumeLabel) / 2, 5, 0xff808080, false);
|
||||||
|
|
||||||
ClientJeiUtil.renderBlock(graphics, recipe.blockState(), 60, 24, 10, 20F, (block, poseStack, buffers) -> {
|
ClientJeiUtil.renderBlock(graphics, recipe.blockState(), 60, 24, 10, 20F, (block, poseStack, buffers) -> {
|
||||||
|
//noinspection deprecation
|
||||||
Minecraft.getInstance().getBlockRenderer().renderSingleBlock(block, poseStack, buffers, 15728880, OverlayTexture.NO_OVERLAY);
|
Minecraft.getInstance().getBlockRenderer().renderSingleBlock(block, poseStack, buffers, 15728880, OverlayTexture.NO_OVERLAY);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -111,12 +112,12 @@ class CrucibleHeatSourcesCategory implements IRecipeCategory<CrucibleHeatSourceR
|
||||||
@Override
|
@Override
|
||||||
public List<Component> getTooltipStrings(CrucibleHeatSourceRecipe recipe, IRecipeSlotsView recipeSlotsView, double mouseX, double mouseY) {
|
public List<Component> getTooltipStrings(CrucibleHeatSourceRecipe recipe, IRecipeSlotsView recipeSlotsView, double mouseX, double mouseY) {
|
||||||
if (44.0 < mouseX && mouseX < 76.0 && 16 < mouseY && mouseY < 48) {
|
if (44.0 < mouseX && mouseX < 76.0 && 16 < mouseY && mouseY < 48) {
|
||||||
if (recipe.ingredientType() != null) {
|
if (recipe.ingredientType() != null && recipe.ingredient() != null) {
|
||||||
var tooltip = this.ingredientManager.getIngredientRenderer(recipe.ingredientType()).getTooltip(recipe.ingredient(), Minecraft.getInstance().options.advancedItemTooltips ? TooltipFlag.ADVANCED : TooltipFlag.NORMAL);
|
var tooltip = this.ingredientManager.getIngredientRenderer(recipe.ingredientType()).getTooltip(recipe.ingredient(), Minecraft.getInstance().options.advancedItemTooltips ? TooltipFlag.ADVANCED : TooltipFlag.NORMAL);
|
||||||
return this.modIdHelper.addModNameToIngredientTooltip(tooltip, recipe.ingredient(), this.ingredientManager.getIngredientHelper(recipe.ingredientType()));
|
return this.modIdHelper.addModNameToIngredientTooltip(tooltip, recipe.ingredient(), this.ingredientManager.getIngredientHelper(recipe.ingredientType()));
|
||||||
} else {
|
} else {
|
||||||
var block = recipe.blockState().getBlock();
|
var block = recipe.blockState().getBlock();
|
||||||
var modId = ForgeRegistries.BLOCKS.getKey(block).getNamespace();
|
var modId = BuiltInRegistries.BLOCK.getKey(block).getNamespace();
|
||||||
return List.of(Component.translatable(block.getDescriptionId()), Component.literal(this.modIdHelper.getFormattedModNameForModId(modId)));
|
return List.of(Component.translatable(block.getDescriptionId()), Component.literal(this.modIdHelper.getFormattedModNameForModId(modId)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,9 @@ import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||||
import mezz.jei.api.IModPlugin;
|
import mezz.jei.api.IModPlugin;
|
||||||
import mezz.jei.api.JeiPlugin;
|
import mezz.jei.api.JeiPlugin;
|
||||||
import mezz.jei.api.constants.VanillaTypes;
|
import mezz.jei.api.constants.VanillaTypes;
|
||||||
import mezz.jei.api.forge.ForgeTypes;
|
|
||||||
import mezz.jei.api.gui.handlers.IGuiClickableArea;
|
import mezz.jei.api.gui.handlers.IGuiClickableArea;
|
||||||
import mezz.jei.api.gui.handlers.IGuiContainerHandler;
|
import mezz.jei.api.gui.handlers.IGuiContainerHandler;
|
||||||
|
import mezz.jei.api.neoforge.NeoForgeTypes;
|
||||||
import mezz.jei.api.recipe.RecipeType;
|
import mezz.jei.api.recipe.RecipeType;
|
||||||
import mezz.jei.api.registration.IGuiHandlerRegistration;
|
import mezz.jei.api.registration.IGuiHandlerRegistration;
|
||||||
import mezz.jei.api.registration.IRecipeCatalystRegistration;
|
import mezz.jei.api.registration.IRecipeCatalystRegistration;
|
||||||
|
|
@ -42,11 +42,11 @@ import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
import net.minecraft.world.level.block.LiquidBlock;
|
import net.minecraft.world.level.block.LiquidBlock;
|
||||||
import net.minecraft.world.level.block.WallTorchBlock;
|
import net.minecraft.world.level.block.WallTorchBlock;
|
||||||
import net.minecraftforge.fluids.FluidStack;
|
import net.neoforged.neoforge.fluids.FluidStack;
|
||||||
import thedarkcolour.exdeorum.ExDeorum;
|
import thedarkcolour.exdeorum.ExDeorum;
|
||||||
import thedarkcolour.exdeorum.client.screen.MechanicalHammerScreen;
|
import thedarkcolour.exdeorum.client.screen.MechanicalHammerScreen;
|
||||||
import thedarkcolour.exdeorum.client.screen.MechanicalSieveScreen;
|
import thedarkcolour.exdeorum.client.screen.MechanicalSieveScreen;
|
||||||
import thedarkcolour.exdeorum.compat.CompatHelper;
|
import thedarkcolour.exdeorum.compat.CompatUtil;
|
||||||
import thedarkcolour.exdeorum.compat.GroupedSieveRecipe;
|
import thedarkcolour.exdeorum.compat.GroupedSieveRecipe;
|
||||||
import thedarkcolour.exdeorum.data.TranslationKeys;
|
import thedarkcolour.exdeorum.data.TranslationKeys;
|
||||||
import thedarkcolour.exdeorum.item.WateringCanItem;
|
import thedarkcolour.exdeorum.item.WateringCanItem;
|
||||||
|
|
@ -65,6 +65,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
@JeiPlugin
|
@JeiPlugin
|
||||||
|
|
@ -105,10 +106,10 @@ public class ExDeorumJeiPlugin implements IModPlugin {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerRecipeCatalysts(IRecipeCatalystRegistration registration) {
|
public void registerRecipeCatalysts(IRecipeCatalystRegistration registration) {
|
||||||
var barrels = CompatHelper.getAvailableBarrels(true);
|
var barrels = CompatUtil.getAvailableBarrels(true);
|
||||||
var sieves = CompatHelper.getAvailableSieves(true, true);
|
var sieves = CompatUtil.getAvailableSieves(true, true);
|
||||||
var lavaCrucibles = CompatHelper.getAvailableLavaCrucibles(true);
|
var lavaCrucibles = CompatUtil.getAvailableLavaCrucibles(true);
|
||||||
var waterCrucibles = CompatHelper.getAvailableWaterCrucibles(true);
|
var waterCrucibles = CompatUtil.getAvailableWaterCrucibles(true);
|
||||||
|
|
||||||
for (var barrel : barrels) {
|
for (var barrel : barrels) {
|
||||||
var stack = new ItemStack(barrel);
|
var stack = new ItemStack(barrel);
|
||||||
|
|
@ -143,12 +144,12 @@ public class ExDeorumJeiPlugin implements IModPlugin {
|
||||||
@Override
|
@Override
|
||||||
public void registerRecipes(IRecipeRegistration registration) {
|
public void registerRecipes(IRecipeRegistration registration) {
|
||||||
registration.addItemStackInfo(List.of(new ItemStack(EItems.INFESTED_LEAVES.get()), new ItemStack(EItems.SILK_WORM.get())), Component.translatable(TranslationKeys.SILK_WORM_JEI_INFO));
|
registration.addItemStackInfo(List.of(new ItemStack(EItems.INFESTED_LEAVES.get()), new ItemStack(EItems.SILK_WORM.get())), Component.translatable(TranslationKeys.SILK_WORM_JEI_INFO));
|
||||||
registration.addItemStackInfo(CompatHelper.getAvailableSieves(true, false).stream().map(ItemStack::new).toList(), Component.translatable(TranslationKeys.SIEVE_JEI_INFO));
|
registration.addItemStackInfo(CompatUtil.getAvailableSieves(true, false).stream().map(ItemStack::new).toList(), Component.translatable(TranslationKeys.SIEVE_JEI_INFO));
|
||||||
registration.addItemStackInfo(List.of(new ItemStack(EItems.STRING_MESH.get()), new ItemStack(EItems.STRING_MESH.get()), new ItemStack(EItems.FLINT_MESH.get()), new ItemStack(EItems.IRON_MESH.get()), new ItemStack(EItems.GOLDEN_MESH.get()), new ItemStack(EItems.DIAMOND_MESH.get()), new ItemStack(EItems.NETHERITE_MESH.get())), Component.translatable(TranslationKeys.SIEVE_MESH_JEI_INFO));
|
registration.addItemStackInfo(List.of(new ItemStack(EItems.STRING_MESH.get()), new ItemStack(EItems.STRING_MESH.get()), new ItemStack(EItems.FLINT_MESH.get()), new ItemStack(EItems.IRON_MESH.get()), new ItemStack(EItems.GOLDEN_MESH.get()), new ItemStack(EItems.DIAMOND_MESH.get()), new ItemStack(EItems.NETHERITE_MESH.get())), Component.translatable(TranslationKeys.SIEVE_MESH_JEI_INFO));
|
||||||
registration.addItemStackInfo(List.of(WateringCanItem.getFull(EItems.WOODEN_WATERING_CAN), WateringCanItem.getFull(EItems.STONE_WATERING_CAN), WateringCanItem.getFull(EItems.IRON_WATERING_CAN), WateringCanItem.getFull(EItems.GOLDEN_WATERING_CAN), WateringCanItem.getFull(EItems.DIAMOND_WATERING_CAN), WateringCanItem.getFull(EItems.NETHERITE_WATERING_CAN)), Component.translatable(TranslationKeys.WATERING_CAN_JEI_INFO));
|
registration.addItemStackInfo(List.of(WateringCanItem.getFull(EItems.WOODEN_WATERING_CAN), WateringCanItem.getFull(EItems.STONE_WATERING_CAN), WateringCanItem.getFull(EItems.IRON_WATERING_CAN), WateringCanItem.getFull(EItems.GOLDEN_WATERING_CAN), WateringCanItem.getFull(EItems.DIAMOND_WATERING_CAN), WateringCanItem.getFull(EItems.NETHERITE_WATERING_CAN)), Component.translatable(TranslationKeys.WATERING_CAN_JEI_INFO));
|
||||||
var witchWaterInfo = Component.translatable(TranslationKeys.WITCH_WATER_JEI_INFO);
|
var witchWaterInfo = Component.translatable(TranslationKeys.WITCH_WATER_JEI_INFO);
|
||||||
registration.addItemStackInfo(List.of(new ItemStack(EItems.WITCH_WATER_BUCKET.get()), new ItemStack(EItems.PORCELAIN_WITCH_WATER_BUCKET.get())), witchWaterInfo);
|
registration.addItemStackInfo(List.of(new ItemStack(EItems.WITCH_WATER_BUCKET.get()), new ItemStack(EItems.PORCELAIN_WITCH_WATER_BUCKET.get())), witchWaterInfo);
|
||||||
registration.addIngredientInfo(new FluidStack(EFluids.WITCH_WATER.get(), 1000), ForgeTypes.FLUID_STACK, witchWaterInfo);
|
registration.addIngredientInfo(new FluidStack(EFluids.WITCH_WATER.get(), 1000), NeoForgeTypes.FLUID_STACK, witchWaterInfo);
|
||||||
registration.addItemStackInfo(new ItemStack(EItems.GRASS_SEEDS.get()), Component.translatable(TranslationKeys.GRASS_SEEDS_JEI_INFO));
|
registration.addItemStackInfo(new ItemStack(EItems.GRASS_SEEDS.get()), Component.translatable(TranslationKeys.GRASS_SEEDS_JEI_INFO));
|
||||||
registration.addItemStackInfo(new ItemStack(EItems.MYCELIUM_SPORES.get()), Component.translatable(TranslationKeys.MYCELIUM_SPORES_JEI_INFO));
|
registration.addItemStackInfo(new ItemStack(EItems.MYCELIUM_SPORES.get()), Component.translatable(TranslationKeys.MYCELIUM_SPORES_JEI_INFO));
|
||||||
registration.addItemStackInfo(new ItemStack(EItems.WARPED_NYLIUM_SPORES.get()), Component.translatable(TranslationKeys.WARPED_NYLIUM_SPORES_JEI_INFO));
|
registration.addItemStackInfo(new ItemStack(EItems.WARPED_NYLIUM_SPORES.get()), Component.translatable(TranslationKeys.WARPED_NYLIUM_SPORES_JEI_INFO));
|
||||||
|
|
@ -187,11 +188,7 @@ public class ExDeorumJeiPlugin implements IModPlugin {
|
||||||
addRecipes(registration, LAVA_CRUCIBLE, ERecipeTypes.LAVA_CRUCIBLE);
|
addRecipes(registration, LAVA_CRUCIBLE, ERecipeTypes.LAVA_CRUCIBLE);
|
||||||
addRecipes(registration, WATER_CRUCIBLE, ERecipeTypes.WATER_CRUCIBLE);
|
addRecipes(registration, WATER_CRUCIBLE, ERecipeTypes.WATER_CRUCIBLE);
|
||||||
addRecipes(registration, HAMMER, ERecipeTypes.HAMMER);
|
addRecipes(registration, HAMMER, ERecipeTypes.HAMMER);
|
||||||
var crookRecipes = new ArrayList<CrookJeiRecipe>();
|
registration.addRecipes(CROOK, CompatUtil.collectAllRecipes(ERecipeTypes.CROOK.get(), CrookJeiRecipe::create));
|
||||||
for (var recipe : Objects.requireNonNull(Minecraft.getInstance().level).getRecipeManager().getAllRecipesFor(ERecipeTypes.CROOK.get())) {
|
|
||||||
crookRecipes.add(CrookJeiRecipe.create(recipe));
|
|
||||||
}
|
|
||||||
registration.addRecipes(CROOK, crookRecipes);
|
|
||||||
registration.addRecipes(SIEVE, GroupedSieveRecipe.getAllRecipesGrouped());
|
registration.addRecipes(SIEVE, GroupedSieveRecipe.getAllRecipesGrouped());
|
||||||
|
|
||||||
addCrucibleHeatSources(registration);
|
addCrucibleHeatSources(registration);
|
||||||
|
|
@ -275,6 +272,6 @@ public class ExDeorumJeiPlugin implements IModPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <C extends Container, T extends Recipe<C>> void addRecipes(IRecipeRegistration registration, RecipeType<T> category, Supplier<net.minecraft.world.item.crafting.RecipeType<T>> type) {
|
private static <C extends Container, T extends Recipe<C>> void addRecipes(IRecipeRegistration registration, RecipeType<T> category, Supplier<net.minecraft.world.item.crafting.RecipeType<T>> type) {
|
||||||
registration.addRecipes(category, Objects.requireNonNull(Minecraft.getInstance().level).getRecipeManager().getAllRecipesFor(type.get()));
|
registration.addRecipes(category, CompatUtil.collectAllRecipes(type.get(), Function.identity()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ import net.minecraft.world.level.storage.loot.providers.number.BinomialDistribut
|
||||||
import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
|
import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
|
||||||
import net.minecraft.world.level.storage.loot.providers.number.NumberProvider;
|
import net.minecraft.world.level.storage.loot.providers.number.NumberProvider;
|
||||||
import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator;
|
import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator;
|
||||||
import net.minecraftforge.common.util.Lazy;
|
import net.neoforged.neoforge.common.util.Lazy;
|
||||||
import thedarkcolour.exdeorum.compat.GroupedSieveRecipe;
|
import thedarkcolour.exdeorum.compat.GroupedSieveRecipe;
|
||||||
import thedarkcolour.exdeorum.data.TranslationKeys;
|
import thedarkcolour.exdeorum.data.TranslationKeys;
|
||||||
import thedarkcolour.exdeorum.loot.SummationGenerator;
|
import thedarkcolour.exdeorum.loot.SummationGenerator;
|
||||||
|
|
@ -110,14 +110,14 @@ class SieveCategory implements IRecipeCategory<GroupedSieveRecipe> {
|
||||||
slot.setCustomRenderer(VanillaTypes.ITEM_STACK, ClientJeiUtil.AsteriskItemRenderer.INSTANCE);
|
slot.setCustomRenderer(VanillaTypes.ITEM_STACK, ClientJeiUtil.AsteriskItemRenderer.INSTANCE);
|
||||||
}
|
}
|
||||||
if (provider instanceof BinomialDistributionGenerator binomial) {
|
if (provider instanceof BinomialDistributionGenerator binomial) {
|
||||||
if (binomial.n instanceof ConstantValue constant && constant.value == 1) {
|
if (binomial.n() instanceof ConstantValue constant && constant.value() == 1) {
|
||||||
var chanceLabel = ClientJeiUtil.formatChance(RecipeUtil.getExpectedValue(binomial.p));
|
var chanceLabel = ClientJeiUtil.formatChance(RecipeUtil.getExpectedValue(binomial.p()));
|
||||||
tooltipLines.add(chanceLabel);
|
tooltipLines.add(chanceLabel);
|
||||||
} else {
|
} else {
|
||||||
addAvgOutput(tooltipLines, RecipeUtil.getExpectedValue(provider));
|
addAvgOutput(tooltipLines, RecipeUtil.getExpectedValue(provider));
|
||||||
}
|
}
|
||||||
|
|
||||||
addMinMaxes(tooltipLines, 0, getMax(binomial.n));
|
addMinMaxes(tooltipLines, 0, getMax(binomial.n()));
|
||||||
} else if (provider.getClass() != ConstantValue.class) {
|
} else if (provider.getClass() != ConstantValue.class) {
|
||||||
var val = RecipeUtil.getExpectedValue(provider);
|
var val = RecipeUtil.getExpectedValue(provider);
|
||||||
if (val != -1.0) {
|
if (val != -1.0) {
|
||||||
|
|
@ -137,9 +137,9 @@ class SieveCategory implements IRecipeCategory<GroupedSieveRecipe> {
|
||||||
|
|
||||||
private static double getMin(NumberProvider provider) {
|
private static double getMin(NumberProvider provider) {
|
||||||
if (provider instanceof ConstantValue value) {
|
if (provider instanceof ConstantValue value) {
|
||||||
return value.value;
|
return value.value();
|
||||||
} else if (provider instanceof UniformGenerator uniform) {
|
} else if (provider instanceof UniformGenerator uniform) {
|
||||||
return getMin(uniform.min);
|
return getMin(uniform.min());
|
||||||
} else if (provider instanceof BinomialDistributionGenerator) {
|
} else if (provider instanceof BinomialDistributionGenerator) {
|
||||||
return 0;
|
return 0;
|
||||||
} else if (provider instanceof SummationGenerator summation) {
|
} else if (provider instanceof SummationGenerator summation) {
|
||||||
|
|
@ -157,11 +157,11 @@ class SieveCategory implements IRecipeCategory<GroupedSieveRecipe> {
|
||||||
|
|
||||||
private static double getMax(NumberProvider provider) {
|
private static double getMax(NumberProvider provider) {
|
||||||
if (provider instanceof ConstantValue value) {
|
if (provider instanceof ConstantValue value) {
|
||||||
return value.value;
|
return value.value();
|
||||||
} else if (provider instanceof UniformGenerator uniform) {
|
} else if (provider instanceof UniformGenerator uniform) {
|
||||||
return getMax(uniform.max);
|
return getMax(uniform.max());
|
||||||
} else if (provider instanceof BinomialDistributionGenerator binomial) {
|
} else if (provider instanceof BinomialDistributionGenerator binomial) {
|
||||||
return getMax(binomial.n);
|
return getMax(binomial.n());
|
||||||
} else if (provider instanceof SummationGenerator summation) {
|
} else if (provider instanceof SummationGenerator summation) {
|
||||||
double sum = 0;
|
double sum = 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ import me.shedaniel.rei.api.common.entry.EntryStack;
|
||||||
import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes;
|
import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes;
|
||||||
import me.shedaniel.rei.forge.REIPluginClient;
|
import me.shedaniel.rei.forge.REIPluginClient;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import thedarkcolour.exdeorum.compat.CompatHelper;
|
import thedarkcolour.exdeorum.compat.CompatUtil;
|
||||||
|
|
||||||
@SuppressWarnings("UnstableApiUsage")
|
@SuppressWarnings("UnstableApiUsage")
|
||||||
@REIPluginClient
|
@REIPluginClient
|
||||||
|
|
@ -35,16 +35,16 @@ public class ExDeorumReiPlugin implements REIClientPlugin {
|
||||||
rule.hide(() -> {
|
rule.hide(() -> {
|
||||||
var builder = EntryIngredient.builder();
|
var builder = EntryIngredient.builder();
|
||||||
|
|
||||||
for (var barrel : CompatHelper.getAvailableBarrels(false)) {
|
for (var barrel : CompatUtil.getAvailableBarrels(false)) {
|
||||||
builder.add(EntryStack.of(VanillaEntryTypes.ITEM, new ItemStack(barrel)));
|
builder.add(EntryStack.of(VanillaEntryTypes.ITEM, new ItemStack(barrel)));
|
||||||
}
|
}
|
||||||
for (var sieve : CompatHelper.getAvailableSieves(false, false)) {
|
for (var sieve : CompatUtil.getAvailableSieves(false, false)) {
|
||||||
builder.add(EntryStack.of(VanillaEntryTypes.ITEM, new ItemStack(sieve)));
|
builder.add(EntryStack.of(VanillaEntryTypes.ITEM, new ItemStack(sieve)));
|
||||||
}
|
}
|
||||||
for (var crucible : CompatHelper.getAvailableLavaCrucibles(false)) {
|
for (var crucible : CompatUtil.getAvailableLavaCrucibles(false)) {
|
||||||
builder.add(EntryStack.of(VanillaEntryTypes.ITEM, new ItemStack(crucible)));
|
builder.add(EntryStack.of(VanillaEntryTypes.ITEM, new ItemStack(crucible)));
|
||||||
}
|
}
|
||||||
for (var crucible : CompatHelper.getAvailableWaterCrucibles(false)) {
|
for (var crucible : CompatUtil.getAvailableWaterCrucibles(false)) {
|
||||||
builder.add(EntryStack.of(VanillaEntryTypes.ITEM, new ItemStack(crucible)));
|
builder.add(EntryStack.of(VanillaEntryTypes.ITEM, new ItemStack(crucible)));
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,11 @@
|
||||||
package thedarkcolour.exdeorum.config;
|
package thedarkcolour.exdeorum.config;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraftforge.common.ForgeConfigSpec;
|
import net.neoforged.neoforge.common.ModConfigSpec;
|
||||||
import net.minecraftforge.common.ForgeConfigSpec.BooleanValue;
|
import net.neoforged.neoforge.common.ModConfigSpec.BooleanValue;
|
||||||
import net.minecraftforge.common.ForgeConfigSpec.ConfigValue;
|
import net.neoforged.neoforge.common.ModConfigSpec.ConfigValue;
|
||||||
import net.minecraftforge.common.ForgeConfigSpec.DoubleValue;
|
import net.neoforged.neoforge.common.ModConfigSpec.IntValue;
|
||||||
import net.minecraftforge.common.ForgeConfigSpec.IntValue;
|
import net.neoforged.neoforge.common.ModConfigSpec.DoubleValue;
|
||||||
import org.apache.commons.lang3.text.WordUtils;
|
import org.apache.commons.lang3.text.WordUtils;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import thedarkcolour.exdeorum.compat.ModIds;
|
import thedarkcolour.exdeorum.compat.ModIds;
|
||||||
|
|
@ -31,9 +31,9 @@ import thedarkcolour.exdeorum.compat.ModIds;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class EConfig {
|
public class EConfig {
|
||||||
public static final ForgeConfigSpec CLIENT_SPEC;
|
public static final ModConfigSpec CLIENT_SPEC;
|
||||||
public static final ForgeConfigSpec COMMON_SPEC;
|
public static final ModConfigSpec COMMON_SPEC;
|
||||||
public static final ForgeConfigSpec SERVER_SPEC;
|
public static final ModConfigSpec SERVER_SPEC;
|
||||||
public static final Client CLIENT;
|
public static final Client CLIENT;
|
||||||
public static final Common COMMON;
|
public static final Common COMMON;
|
||||||
public static final Server SERVER;
|
public static final Server SERVER;
|
||||||
|
|
@ -42,7 +42,7 @@ public class EConfig {
|
||||||
public final BooleanValue useFastInfestedLeaves;
|
public final BooleanValue useFastInfestedLeaves;
|
||||||
public final BooleanValue setVoidWorldAsDefault;
|
public final BooleanValue setVoidWorldAsDefault;
|
||||||
|
|
||||||
public Client(ForgeConfigSpec.Builder builder) {
|
public Client(ModConfigSpec.Builder builder) {
|
||||||
builder.comment("Client configuration for Ex Deorum").push("client");
|
builder.comment("Client configuration for Ex Deorum").push("client");
|
||||||
|
|
||||||
this.useFastInfestedLeaves = builder
|
this.useFastInfestedLeaves = builder
|
||||||
|
|
@ -78,7 +78,7 @@ public class EConfig {
|
||||||
public final BooleanValue voidNetherGeneration;
|
public final BooleanValue voidNetherGeneration;
|
||||||
public final BooleanValue voidEndGeneration;
|
public final BooleanValue voidEndGeneration;
|
||||||
|
|
||||||
public Common(ForgeConfigSpec.Builder builder) {
|
public Common(ModConfigSpec.Builder builder) {
|
||||||
// Preferred items
|
// Preferred items
|
||||||
builder.comment("Common configuration for Ex Deorum").push("common");
|
builder.comment("Common configuration for Ex Deorum").push("common");
|
||||||
|
|
||||||
|
|
@ -138,7 +138,7 @@ public class EConfig {
|
||||||
public final IntValue mechanicalHammerEnergyConsumption;
|
public final IntValue mechanicalHammerEnergyConsumption;
|
||||||
public final IntValue sieveIntervalTicks;
|
public final IntValue sieveIntervalTicks;
|
||||||
|
|
||||||
public Server(ForgeConfigSpec.Builder builder) {
|
public Server(ModConfigSpec.Builder builder) {
|
||||||
builder.comment("Server configuration for Ex Deorum").push("server");
|
builder.comment("Server configuration for Ex Deorum").push("server");
|
||||||
|
|
||||||
this.startingTorch = builder
|
this.startingTorch = builder
|
||||||
|
|
@ -200,7 +200,7 @@ public class EConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
private static ConfigValue<String> preferredOreConfig(ForgeConfigSpec.Builder builder, String name, String defaultId) {
|
private static ConfigValue<String> preferredOreConfig(ModConfigSpec.Builder builder, String name, String defaultId) {
|
||||||
return builder
|
return builder
|
||||||
.comment("The ID of the item to use for Ex Deorum recipes that craft into " + WordUtils.capitalize(name.replace('_', ' ')) + ". Leave as air for default preference, which chooses alphabetically by mod name.")
|
.comment("The ID of the item to use for Ex Deorum recipes that craft into " + WordUtils.capitalize(name.replace('_', ' ')) + ". Leave as air for default preference, which chooses alphabetically by mod name.")
|
||||||
.define(List.of("preferred_" + name), defaultId, o -> o != null && o.getClass() == String.class && ResourceLocation.isValidResourceLocation((String) o));
|
.define(List.of("preferred_" + name), defaultId, o -> o != null && o.getClass() == String.class && ResourceLocation.isValidResourceLocation((String) o));
|
||||||
|
|
@ -208,17 +208,17 @@ public class EConfig {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
{
|
{
|
||||||
Pair<Client, ForgeConfigSpec> specPair = new ForgeConfigSpec.Builder().configure(Client::new);
|
Pair<Client, ModConfigSpec> specPair = new ModConfigSpec.Builder().configure(Client::new);
|
||||||
CLIENT = specPair.getLeft();
|
CLIENT = specPair.getLeft();
|
||||||
CLIENT_SPEC = specPair.getRight();
|
CLIENT_SPEC = specPair.getRight();
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
Pair<Common, ForgeConfigSpec> specPair = new ForgeConfigSpec.Builder().configure(Common::new);
|
Pair<Common, ModConfigSpec> specPair = new ModConfigSpec.Builder().configure(Common::new);
|
||||||
COMMON = specPair.getLeft();
|
COMMON = specPair.getLeft();
|
||||||
COMMON_SPEC = specPair.getRight();
|
COMMON_SPEC = specPair.getRight();
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
Pair<Server, ForgeConfigSpec> specPair = new ForgeConfigSpec.Builder().configure(Server::new);
|
Pair<Server, ModConfigSpec> specPair = new ModConfigSpec.Builder().configure(Server::new);
|
||||||
SERVER = specPair.getLeft();
|
SERVER = specPair.getLeft();
|
||||||
SERVER_SPEC = specPair.getRight();
|
SERVER_SPEC = specPair.getRight();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,16 +18,17 @@
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.data;
|
package thedarkcolour.exdeorum.data;
|
||||||
|
|
||||||
import net.minecraft.advancements.Advancement;
|
import net.minecraft.advancements.AdvancementHolder;
|
||||||
import net.minecraft.advancements.FrameType;
|
import net.minecraft.advancements.AdvancementType;
|
||||||
|
import net.minecraft.advancements.CriteriaTriggers;
|
||||||
import net.minecraft.advancements.critereon.ImpossibleTrigger;
|
import net.minecraft.advancements.critereon.ImpossibleTrigger;
|
||||||
import net.minecraft.core.HolderLookup;
|
import net.minecraft.core.HolderLookup;
|
||||||
import net.minecraft.data.PackOutput;
|
import net.minecraft.data.PackOutput;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
import net.minecraftforge.common.data.ExistingFileHelper;
|
import net.neoforged.neoforge.common.data.AdvancementProvider;
|
||||||
import net.minecraftforge.common.data.ForgeAdvancementProvider;
|
import net.neoforged.neoforge.common.data.ExistingFileHelper;
|
||||||
import thedarkcolour.exdeorum.ExDeorum;
|
import thedarkcolour.exdeorum.ExDeorum;
|
||||||
import thedarkcolour.exdeorum.material.DefaultMaterials;
|
import thedarkcolour.exdeorum.material.DefaultMaterials;
|
||||||
import thedarkcolour.exdeorum.registry.EItems;
|
import thedarkcolour.exdeorum.registry.EItems;
|
||||||
|
|
@ -41,7 +42,7 @@ import static net.minecraft.advancements.Advancement.Builder.advancement;
|
||||||
import static net.minecraft.advancements.critereon.InventoryChangeTrigger.TriggerInstance.hasItems;
|
import static net.minecraft.advancements.critereon.InventoryChangeTrigger.TriggerInstance.hasItems;
|
||||||
import static net.minecraft.advancements.critereon.ItemPredicate.Builder.item;
|
import static net.minecraft.advancements.critereon.ItemPredicate.Builder.item;
|
||||||
|
|
||||||
class Advancements extends ForgeAdvancementProvider {
|
class Advancements extends AdvancementProvider {
|
||||||
public Advancements(PackOutput output, CompletableFuture<HolderLookup.Provider> registries, ExistingFileHelper existingFileHelper) {
|
public Advancements(PackOutput output, CompletableFuture<HolderLookup.Provider> registries, ExistingFileHelper existingFileHelper) {
|
||||||
super(output, registries, existingFileHelper, List.of(new CoreAchievements()));
|
super(output, registries, existingFileHelper, List.of(new CoreAchievements()));
|
||||||
}
|
}
|
||||||
|
|
@ -52,20 +53,20 @@ class Advancements extends ForgeAdvancementProvider {
|
||||||
|
|
||||||
public static class CoreAchievements implements AdvancementGenerator {
|
public static class CoreAchievements implements AdvancementGenerator {
|
||||||
@Override
|
@Override
|
||||||
public void generate(HolderLookup.Provider registries, Consumer<Advancement> saver, ExistingFileHelper helper) {
|
public void generate(HolderLookup.Provider registries, Consumer<AdvancementHolder> saver, ExistingFileHelper helper) {
|
||||||
var root = advancement()
|
var root = advancement()
|
||||||
.display(
|
.display(
|
||||||
Blocks.OAK_SAPLING,
|
Blocks.OAK_SAPLING,
|
||||||
Component.translatable(TranslationKeys.ROOT_ADVANCEMENT_TITLE),
|
Component.translatable(TranslationKeys.ROOT_ADVANCEMENT_TITLE),
|
||||||
Component.translatable(TranslationKeys.ROOT_ADVANCEMENT_DESCRIPTION),
|
Component.translatable(TranslationKeys.ROOT_ADVANCEMENT_DESCRIPTION),
|
||||||
modLoc("textures/gui/advancements/backgrounds/void.png"),
|
modLoc("textures/gui/advancements/backgrounds/void.png"),
|
||||||
FrameType.TASK,
|
AdvancementType.TASK,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
// hardcoded to EventHandler
|
// hardcoded to EventHandler
|
||||||
.addCriterion("in_void_world", new ImpossibleTrigger.TriggerInstance())
|
.addCriterion("in_void_world", CriteriaTriggers.IMPOSSIBLE.createCriterion(new ImpossibleTrigger.TriggerInstance()))
|
||||||
.save(saver, modLoc("core/root"), helper);
|
.save(saver, modLoc("core/root"), helper);
|
||||||
var crook = advancement()
|
var crook = advancement()
|
||||||
.parent(root)
|
.parent(root)
|
||||||
|
|
@ -74,7 +75,7 @@ class Advancements extends ForgeAdvancementProvider {
|
||||||
Component.translatable(TranslationKeys.CROOK_ADVANCEMENT_TITLE),
|
Component.translatable(TranslationKeys.CROOK_ADVANCEMENT_TITLE),
|
||||||
Component.translatable(TranslationKeys.CROOK_ADVANCEMENT_DESCRIPTION),
|
Component.translatable(TranslationKeys.CROOK_ADVANCEMENT_DESCRIPTION),
|
||||||
null,
|
null,
|
||||||
FrameType.TASK,
|
AdvancementType.TASK,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
true
|
true
|
||||||
|
|
@ -88,7 +89,7 @@ class Advancements extends ForgeAdvancementProvider {
|
||||||
Component.translatable(TranslationKeys.BARREL_ADVANCEMENT_TITLE),
|
Component.translatable(TranslationKeys.BARREL_ADVANCEMENT_TITLE),
|
||||||
Component.translatable(TranslationKeys.BARREL_ADVANCEMENT_DESCRIPTION),
|
Component.translatable(TranslationKeys.BARREL_ADVANCEMENT_DESCRIPTION),
|
||||||
null,
|
null,
|
||||||
FrameType.TASK,
|
AdvancementType.TASK,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
true
|
true
|
||||||
|
|
@ -102,7 +103,7 @@ class Advancements extends ForgeAdvancementProvider {
|
||||||
Component.translatable(TranslationKeys.SILK_WORM_ADVANCEMENT_TITLE),
|
Component.translatable(TranslationKeys.SILK_WORM_ADVANCEMENT_TITLE),
|
||||||
Component.translatable(TranslationKeys.SILK_WORM_ADVANCEMENT_DESCRIPTION),
|
Component.translatable(TranslationKeys.SILK_WORM_ADVANCEMENT_DESCRIPTION),
|
||||||
null,
|
null,
|
||||||
FrameType.TASK,
|
AdvancementType.TASK,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
false
|
false
|
||||||
|
|
@ -116,7 +117,7 @@ class Advancements extends ForgeAdvancementProvider {
|
||||||
Component.translatable(TranslationKeys.STRING_MESH_ADVANCEMENT_TITLE),
|
Component.translatable(TranslationKeys.STRING_MESH_ADVANCEMENT_TITLE),
|
||||||
Component.translatable(TranslationKeys.STRING_MESH_ADVANCEMENT_DESCRIPTION),
|
Component.translatable(TranslationKeys.STRING_MESH_ADVANCEMENT_DESCRIPTION),
|
||||||
null,
|
null,
|
||||||
FrameType.TASK,
|
AdvancementType.TASK,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
false
|
false
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,12 @@
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.data;
|
package thedarkcolour.exdeorum.data;
|
||||||
|
|
||||||
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
import net.minecraftforge.client.model.generators.BlockModelBuilder;
|
import net.neoforged.neoforge.client.model.generators.BlockModelBuilder;
|
||||||
import net.minecraftforge.client.model.generators.ConfiguredModel;
|
import net.neoforged.neoforge.client.model.generators.ConfiguredModel;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
|
||||||
import thedarkcolour.exdeorum.material.DefaultMaterials;
|
import thedarkcolour.exdeorum.material.DefaultMaterials;
|
||||||
import thedarkcolour.exdeorum.registry.EBlocks;
|
import thedarkcolour.exdeorum.registry.EBlocks;
|
||||||
import thedarkcolour.modkit.data.MKBlockModelProvider;
|
import thedarkcolour.modkit.data.MKBlockModelProvider;
|
||||||
|
|
@ -196,7 +196,7 @@ class BlockModels {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ResourceLocation texture(Block block, String prefix, String suffix) {
|
private static ResourceLocation texture(Block block, String prefix, String suffix) {
|
||||||
var key = Objects.requireNonNull(ForgeRegistries.BLOCKS.getKey(block));
|
var key = Objects.requireNonNull(BuiltInRegistries.BLOCK.getKey(block));
|
||||||
return new ResourceLocation(key.getNamespace(), "block/" + prefix + key.getPath() + suffix);
|
return new ResourceLocation(key.getNamespace(), "block/" + prefix + key.getPath() + suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,8 @@
|
||||||
package thedarkcolour.exdeorum.data;
|
package thedarkcolour.exdeorum.data;
|
||||||
|
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraftforge.data.event.GatherDataEvent;
|
import net.neoforged.fml.common.Mod;
|
||||||
import net.minecraftforge.data.loading.DatagenModLoader;
|
import net.neoforged.neoforge.data.event.GatherDataEvent;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|
||||||
import net.minecraftforge.fml.common.Mod;
|
|
||||||
import thedarkcolour.exdeorum.ExDeorum;
|
import thedarkcolour.exdeorum.ExDeorum;
|
||||||
import thedarkcolour.exdeorum.data.recipe.Recipes;
|
import thedarkcolour.exdeorum.data.recipe.Recipes;
|
||||||
import thedarkcolour.modkit.data.DataHelper;
|
import thedarkcolour.modkit.data.DataHelper;
|
||||||
|
|
@ -30,13 +28,6 @@ import thedarkcolour.modkit.data.DataHelper;
|
||||||
// these two annotations are equivalent to modEventBus.addListener(Data::generateData)
|
// these two annotations are equivalent to modEventBus.addListener(Data::generateData)
|
||||||
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
|
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
|
||||||
public class Data {
|
public class Data {
|
||||||
static {
|
|
||||||
if (DatagenModLoader.isRunningDataGen()) {
|
|
||||||
ModCompatData.registerModData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void generateData(GatherDataEvent event) {
|
public static void generateData(GatherDataEvent event) {
|
||||||
// Two things used by data generators
|
// Two things used by data generators
|
||||||
var gen = event.getGenerator(); // writes to json
|
var gen = event.getGenerator(); // writes to json
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,12 @@ import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||||
import net.minecraftforge.data.loading.DatagenModLoader;
|
import net.neoforged.bus.api.IEventBus;
|
||||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
import net.neoforged.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
import net.minecraftforge.registries.DeferredRegister;
|
import net.neoforged.neoforge.data.loading.DatagenModLoader;
|
||||||
import net.minecraftforge.registries.RegistryObject;
|
import net.neoforged.neoforge.registries.DeferredBlock;
|
||||||
|
import net.neoforged.neoforge.registries.DeferredItem;
|
||||||
|
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||||
import thedarkcolour.exdeorum.compat.ModIds;
|
import thedarkcolour.exdeorum.compat.ModIds;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
@ -35,13 +37,13 @@ import java.util.Map;
|
||||||
// Mocks modded items so that data generation can reference modded items without needing those mods installed.
|
// Mocks modded items so that data generation can reference modded items without needing those mods installed.
|
||||||
public class ModCompatData {
|
public class ModCompatData {
|
||||||
// Identity maps because keys are just constants from ModIds
|
// Identity maps because keys are just constants from ModIds
|
||||||
private static final Map<String, DeferredRegister<Item>> itemRegistries = new HashMap<>();
|
private static final Map<String, DeferredRegister.Items> itemRegistries = new HashMap<>();
|
||||||
private static final Map<String, DeferredRegister<Block>> blockRegistries = new HashMap<>();
|
private static final Map<String, DeferredRegister.Blocks> blockRegistries = new HashMap<>();
|
||||||
|
|
||||||
@SuppressWarnings("DataFlowIssue")
|
@SuppressWarnings("DataFlowIssue")
|
||||||
private static RegistryObject<Item> item(String modid, String name) {
|
private static DeferredItem<Item> item(String modid, String name) {
|
||||||
if (DatagenModLoader.isRunningDataGen()) {
|
if (DatagenModLoader.isRunningDataGen()) {
|
||||||
DeferredRegister<Item> registry = itemRegistries.computeIfAbsent(modid, key -> DeferredRegister.create(Registries.ITEM, key));
|
DeferredRegister.Items registry = itemRegistries.computeIfAbsent(modid, DeferredRegister::createItems);
|
||||||
return registry.register(name, () -> new Item(new Item.Properties()));
|
return registry.register(name, () -> new Item(new Item.Properties()));
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -49,9 +51,9 @@ public class ModCompatData {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("DataFlowIssue")
|
@SuppressWarnings("DataFlowIssue")
|
||||||
private static RegistryObject<Block> block(String modid, String name) {
|
private static DeferredBlock<Block> block(String modid, String name) {
|
||||||
if (DatagenModLoader.isRunningDataGen()) {
|
if (DatagenModLoader.isRunningDataGen()) {
|
||||||
DeferredRegister<Block> registry = blockRegistries.computeIfAbsent(modid, key -> DeferredRegister.create(Registries.BLOCK, key));
|
DeferredRegister.Blocks registry = blockRegistries.computeIfAbsent(modid, DeferredRegister::createBlocks);
|
||||||
return registry.register(name, () -> new Block(BlockBehaviour.Properties.of()));
|
return registry.register(name, () -> new Block(BlockBehaviour.Properties.of()));
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -59,13 +61,13 @@ public class ModCompatData {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ender IO
|
// Ender IO
|
||||||
public static final RegistryObject<Item>
|
public static final DeferredItem<Item>
|
||||||
GRAINS_OF_INFINITY = item(ModIds.ENDERIO, "grains_of_infinity");
|
GRAINS_OF_INFINITY = item(ModIds.ENDERIO, "grains_of_infinity");
|
||||||
// Bigger reactors
|
// Bigger reactors
|
||||||
public static final RegistryObject<Item>
|
public static final DeferredItem<Item>
|
||||||
YELLORIUM_DUST = item(ModIds.BIGGER_REACTORS, "yellorium_dust");
|
YELLORIUM_DUST = item(ModIds.BIGGER_REACTORS, "yellorium_dust");
|
||||||
// Biomes O' Plenty
|
// Biomes O' Plenty
|
||||||
public static final RegistryObject<Block>
|
public static final DeferredBlock<Block>
|
||||||
FIR_PLANKS = block(ModIds.BIOMES_O_PLENTY, "fir_planks"),
|
FIR_PLANKS = block(ModIds.BIOMES_O_PLENTY, "fir_planks"),
|
||||||
REDWOOD_PLANKS = block(ModIds.BIOMES_O_PLENTY, "redwood_planks"),
|
REDWOOD_PLANKS = block(ModIds.BIOMES_O_PLENTY, "redwood_planks"),
|
||||||
MAHOGANY_PLANKS = block(ModIds.BIOMES_O_PLENTY, "mahogany_planks"),
|
MAHOGANY_PLANKS = block(ModIds.BIOMES_O_PLENTY, "mahogany_planks"),
|
||||||
|
|
@ -86,7 +88,7 @@ public class ModCompatData {
|
||||||
MAGIC_LOG = block(ModIds.BIOMES_O_PLENTY, "magic_log"),
|
MAGIC_LOG = block(ModIds.BIOMES_O_PLENTY, "magic_log"),
|
||||||
UMBRAN_LOG = block(ModIds.BIOMES_O_PLENTY, "umbran_log"),
|
UMBRAN_LOG = block(ModIds.BIOMES_O_PLENTY, "umbran_log"),
|
||||||
HELLBARK_LOG = block(ModIds.BIOMES_O_PLENTY, "hellbark_log");
|
HELLBARK_LOG = block(ModIds.BIOMES_O_PLENTY, "hellbark_log");
|
||||||
public static final RegistryObject<Item>
|
public static final DeferredItem<Item>
|
||||||
FIR_PLANKS_ITEM = item(ModIds.BIOMES_O_PLENTY, "fir_planks"),
|
FIR_PLANKS_ITEM = item(ModIds.BIOMES_O_PLENTY, "fir_planks"),
|
||||||
REDWOOD_PLANKS_ITEM = item(ModIds.BIOMES_O_PLENTY, "redwood_planks"),
|
REDWOOD_PLANKS_ITEM = item(ModIds.BIOMES_O_PLENTY, "redwood_planks"),
|
||||||
MAHOGANY_PLANKS_ITEM = item(ModIds.BIOMES_O_PLENTY, "mahogany_planks"),
|
MAHOGANY_PLANKS_ITEM = item(ModIds.BIOMES_O_PLENTY, "mahogany_planks"),
|
||||||
|
|
@ -135,19 +137,19 @@ public class ModCompatData {
|
||||||
UMBRAN_SAPLING = item(ModIds.BIOMES_O_PLENTY, "umbran_sapling"),
|
UMBRAN_SAPLING = item(ModIds.BIOMES_O_PLENTY, "umbran_sapling"),
|
||||||
HELLBARK_SAPLING = item(ModIds.BIOMES_O_PLENTY, "hellbark_sapling");
|
HELLBARK_SAPLING = item(ModIds.BIOMES_O_PLENTY, "hellbark_sapling");
|
||||||
// Applied Energistics 2
|
// Applied Energistics 2
|
||||||
public static final RegistryObject<Item>
|
public static final DeferredItem<Item>
|
||||||
CERTUS_QUARTZ_CRYSTAL = item(ModIds.APPLIED_ENERGISTICS_2, "certus_quartz_crystal"),
|
CERTUS_QUARTZ_CRYSTAL = item(ModIds.APPLIED_ENERGISTICS_2, "certus_quartz_crystal"),
|
||||||
CHARGED_CERTUS_QUARTZ_CRYSTAL = item(ModIds.APPLIED_ENERGISTICS_2, "charged_certus_quartz_crystal"),
|
CHARGED_CERTUS_QUARTZ_CRYSTAL = item(ModIds.APPLIED_ENERGISTICS_2, "charged_certus_quartz_crystal"),
|
||||||
CERTUS_QUARTZ_DUST = item(ModIds.APPLIED_ENERGISTICS_2, "certus_quartz_dust"),
|
CERTUS_QUARTZ_DUST = item(ModIds.APPLIED_ENERGISTICS_2, "certus_quartz_dust"),
|
||||||
SKY_STONE_DUST = item(ModIds.APPLIED_ENERGISTICS_2, "sky_dust");
|
SKY_STONE_DUST = item(ModIds.APPLIED_ENERGISTICS_2, "sky_dust");
|
||||||
// Ars Nouveau
|
// Ars Nouveau
|
||||||
public static final RegistryObject<Block>
|
public static final DeferredBlock<Block>
|
||||||
CASCADING_ARCHWOOD_LOG = block(ModIds.ARS_NOUVEAU, "blue_archwood_log"),
|
CASCADING_ARCHWOOD_LOG = block(ModIds.ARS_NOUVEAU, "blue_archwood_log"),
|
||||||
BLAZING_ARCHWOOD_LOG = block(ModIds.ARS_NOUVEAU, "red_archwood_log"),
|
BLAZING_ARCHWOOD_LOG = block(ModIds.ARS_NOUVEAU, "red_archwood_log"),
|
||||||
VEXING_ARCHWOOD_LOG = block(ModIds.ARS_NOUVEAU, "purple_archwood_log"),
|
VEXING_ARCHWOOD_LOG = block(ModIds.ARS_NOUVEAU, "purple_archwood_log"),
|
||||||
FLOURISHING_ARCHWOOD_LOG = block(ModIds.ARS_NOUVEAU, "green_archwood_log"),
|
FLOURISHING_ARCHWOOD_LOG = block(ModIds.ARS_NOUVEAU, "green_archwood_log"),
|
||||||
ARCHWOOD_PLANKS = block(ModIds.ARS_NOUVEAU, "archwood_planks");
|
ARCHWOOD_PLANKS = block(ModIds.ARS_NOUVEAU, "archwood_planks");
|
||||||
public static final RegistryObject<Item>
|
public static final DeferredItem<Item>
|
||||||
BLUE_ARCHWOOD_SAPLING = item(ModIds.ARS_NOUVEAU, "blue_archwood_sapling"),
|
BLUE_ARCHWOOD_SAPLING = item(ModIds.ARS_NOUVEAU, "blue_archwood_sapling"),
|
||||||
RED_ARCHWOOD_SAPLING = item(ModIds.ARS_NOUVEAU, "red_archwood_sapling"),
|
RED_ARCHWOOD_SAPLING = item(ModIds.ARS_NOUVEAU, "red_archwood_sapling"),
|
||||||
PURPLE_ARCHWOOD_SAPLING = item(ModIds.ARS_NOUVEAU, "purple_archwood_sapling"),
|
PURPLE_ARCHWOOD_SAPLING = item(ModIds.ARS_NOUVEAU, "purple_archwood_sapling"),
|
||||||
|
|
@ -160,17 +162,17 @@ public class ModCompatData {
|
||||||
ARCHWOOD_SLAB = item(ModIds.ARS_NOUVEAU, "archwood_slab"),
|
ARCHWOOD_SLAB = item(ModIds.ARS_NOUVEAU, "archwood_slab"),
|
||||||
ARCHWOOD_PLANKS_ITEM = item(ModIds.ARS_NOUVEAU, "archwood_planks");
|
ARCHWOOD_PLANKS_ITEM = item(ModIds.ARS_NOUVEAU, "archwood_planks");
|
||||||
// Aether
|
// Aether
|
||||||
public static final RegistryObject<Block>
|
public static final DeferredBlock<Block>
|
||||||
SKYROOT_PLANKS = block(ModIds.AETHER, "skyroot_planks"),
|
SKYROOT_PLANKS = block(ModIds.AETHER, "skyroot_planks"),
|
||||||
SKYROOT_LOG = block(ModIds.AETHER, "skyroot_log"),
|
SKYROOT_LOG = block(ModIds.AETHER, "skyroot_log"),
|
||||||
GOLDEN_OAK_LOG = block(ModIds.AETHER, "golden_oak_log");
|
GOLDEN_OAK_LOG = block(ModIds.AETHER, "golden_oak_log");
|
||||||
public static final RegistryObject<Item>
|
public static final DeferredItem<Item>
|
||||||
SKYROOT_SLAB = item(ModIds.AETHER, "skyroot_slab"),
|
SKYROOT_SLAB = item(ModIds.AETHER, "skyroot_slab"),
|
||||||
SKYROOT_PLANKS_ITEM = item(ModIds.AETHER, "skyroot_planks"),
|
SKYROOT_PLANKS_ITEM = item(ModIds.AETHER, "skyroot_planks"),
|
||||||
GOLDEN_OAK_LOG_ITEM = item(ModIds.AETHER, "golden_oak_log"),
|
GOLDEN_OAK_LOG_ITEM = item(ModIds.AETHER, "golden_oak_log"),
|
||||||
SKYROOT_LOG_ITEM = item(ModIds.AETHER, "skyroot_log");
|
SKYROOT_LOG_ITEM = item(ModIds.AETHER, "skyroot_log");
|
||||||
// Blue Skies
|
// Blue Skies
|
||||||
public static final RegistryObject<Block>
|
public static final DeferredBlock<Block>
|
||||||
BLUEBRIGHT_PLANKS = block(ModIds.BLUE_SKIES, "bluebright_planks"),
|
BLUEBRIGHT_PLANKS = block(ModIds.BLUE_SKIES, "bluebright_planks"),
|
||||||
STARLIT_PLANKS = block(ModIds.BLUE_SKIES, "starlit_planks"),
|
STARLIT_PLANKS = block(ModIds.BLUE_SKIES, "starlit_planks"),
|
||||||
FROSTBRIGHT_PLANKS = block(ModIds.BLUE_SKIES, "frostbright_planks"),
|
FROSTBRIGHT_PLANKS = block(ModIds.BLUE_SKIES, "frostbright_planks"),
|
||||||
|
|
@ -187,7 +189,7 @@ public class ModCompatData {
|
||||||
DUSK_LOG = block(ModIds.BLUE_SKIES, "dusk_log"),
|
DUSK_LOG = block(ModIds.BLUE_SKIES, "dusk_log"),
|
||||||
MAPLE_LOG = block(ModIds.BLUE_SKIES, "maple_log"),
|
MAPLE_LOG = block(ModIds.BLUE_SKIES, "maple_log"),
|
||||||
CRYSTALLIZED_LOG = block(ModIds.BLUE_SKIES, "crystallized_log");
|
CRYSTALLIZED_LOG = block(ModIds.BLUE_SKIES, "crystallized_log");
|
||||||
public static final RegistryObject<Item>
|
public static final DeferredItem<Item>
|
||||||
BLUEBRIGHT_PLANKS_ITEM = item(ModIds.BLUE_SKIES, "bluebright_planks"),
|
BLUEBRIGHT_PLANKS_ITEM = item(ModIds.BLUE_SKIES, "bluebright_planks"),
|
||||||
STARLIT_PLANKS_ITEM = item(ModIds.BLUE_SKIES, "starlit_planks"),
|
STARLIT_PLANKS_ITEM = item(ModIds.BLUE_SKIES, "starlit_planks"),
|
||||||
FROSTBRIGHT_PLANKS_ITEM = item(ModIds.BLUE_SKIES, "frostbright_planks"),
|
FROSTBRIGHT_PLANKS_ITEM = item(ModIds.BLUE_SKIES, "frostbright_planks"),
|
||||||
|
|
@ -225,9 +227,7 @@ public class ModCompatData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void registerModData() {
|
public static void registerModData(IEventBus modBus) {
|
||||||
var modBus = FMLJavaModLoadingContext.get().getModEventBus();
|
|
||||||
|
|
||||||
for (var registry : itemRegistries.values()) {
|
for (var registry : itemRegistries.values()) {
|
||||||
registry.register(modBus);
|
registry.register(modBus);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@ package thedarkcolour.exdeorum.data.recipe;
|
||||||
|
|
||||||
import net.minecraft.advancements.critereon.StatePropertiesPredicate;
|
import net.minecraft.advancements.critereon.StatePropertiesPredicate;
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.data.recipes.FinishedRecipe;
|
|
||||||
import net.minecraft.data.recipes.RecipeCategory;
|
import net.minecraft.data.recipes.RecipeCategory;
|
||||||
|
import net.minecraft.data.recipes.RecipeOutput;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.tags.BlockTags;
|
import net.minecraft.tags.BlockTags;
|
||||||
import net.minecraft.tags.ItemTags;
|
import net.minecraft.tags.ItemTags;
|
||||||
|
|
@ -40,36 +40,33 @@ import net.minecraft.world.level.material.Fluids;
|
||||||
import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
|
import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
|
||||||
import net.minecraft.world.level.storage.loot.providers.number.NumberProvider;
|
import net.minecraft.world.level.storage.loot.providers.number.NumberProvider;
|
||||||
import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator;
|
import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator;
|
||||||
import net.minecraftforge.common.ForgeMod;
|
import net.neoforged.neoforge.common.NeoForgeMod;
|
||||||
import net.minecraftforge.common.Tags;
|
import net.neoforged.neoforge.common.Tags;
|
||||||
import net.minecraftforge.common.crafting.conditions.ICondition;
|
import net.neoforged.neoforge.common.conditions.ICondition;
|
||||||
import net.minecraftforge.common.crafting.conditions.ModLoadedCondition;
|
import net.neoforged.neoforge.common.conditions.ModLoadedCondition;
|
||||||
import net.minecraftforge.common.crafting.conditions.NotCondition;
|
import net.neoforged.neoforge.common.conditions.NotCondition;
|
||||||
import net.minecraftforge.common.crafting.conditions.TagEmptyCondition;
|
import net.neoforged.neoforge.common.conditions.TagEmptyCondition;
|
||||||
import net.minecraftforge.registries.RegistryObject;
|
import net.neoforged.neoforge.fluids.FluidStack;
|
||||||
import org.apache.commons.lang3.mutable.MutableObject;
|
|
||||||
import thedarkcolour.exdeorum.ExDeorum;
|
import thedarkcolour.exdeorum.ExDeorum;
|
||||||
import thedarkcolour.exdeorum.block.InfestedLeavesBlock;
|
import thedarkcolour.exdeorum.block.InfestedLeavesBlock;
|
||||||
import thedarkcolour.exdeorum.compat.ModIds;
|
import thedarkcolour.exdeorum.compat.ModIds;
|
||||||
import thedarkcolour.exdeorum.data.ModCompatData;
|
import thedarkcolour.exdeorum.data.ModCompatData;
|
||||||
import thedarkcolour.exdeorum.material.DefaultMaterials;
|
import thedarkcolour.exdeorum.material.DefaultMaterials;
|
||||||
import thedarkcolour.exdeorum.recipe.TagResultRecipe;
|
import thedarkcolour.exdeorum.recipe.OreChunkRecipe;
|
||||||
import thedarkcolour.exdeorum.recipe.WeightedList;
|
import thedarkcolour.exdeorum.recipe.WeightedList;
|
||||||
import thedarkcolour.exdeorum.recipe.barrel.*;
|
import thedarkcolour.exdeorum.recipe.barrel.*;
|
||||||
import thedarkcolour.exdeorum.recipe.BlockPredicate;
|
import thedarkcolour.exdeorum.recipe.BlockPredicate;
|
||||||
import thedarkcolour.exdeorum.recipe.crook.FinishedCrookRecipe;
|
import thedarkcolour.exdeorum.recipe.crook.CrookRecipe;
|
||||||
import thedarkcolour.exdeorum.recipe.crucible.FinishedCrucibleHeatRecipe;
|
import thedarkcolour.exdeorum.recipe.crucible.CrucibleHeatRecipe;
|
||||||
import thedarkcolour.exdeorum.recipe.crucible.FinishedCrucibleRecipe;
|
import thedarkcolour.exdeorum.recipe.crucible.CrucibleRecipe;
|
||||||
import thedarkcolour.exdeorum.recipe.hammer.FinishedHammerRecipe;
|
import thedarkcolour.exdeorum.recipe.hammer.HammerRecipe;
|
||||||
import thedarkcolour.exdeorum.registry.EBlocks;
|
import thedarkcolour.exdeorum.registry.EBlocks;
|
||||||
import thedarkcolour.exdeorum.registry.EFluids;
|
import thedarkcolour.exdeorum.registry.EFluids;
|
||||||
import thedarkcolour.exdeorum.registry.EItems;
|
import thedarkcolour.exdeorum.registry.EItems;
|
||||||
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
|
||||||
import thedarkcolour.exdeorum.tag.EItemTags;
|
import thedarkcolour.exdeorum.tag.EItemTags;
|
||||||
import thedarkcolour.modkit.data.MKRecipeProvider;
|
import thedarkcolour.modkit.data.MKRecipeProvider;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import static net.minecraft.world.level.storage.loot.providers.number.UniformGenerator.between;
|
import static net.minecraft.world.level.storage.loot.providers.number.UniformGenerator.between;
|
||||||
|
|
@ -79,7 +76,7 @@ import static thedarkcolour.modkit.data.MKRecipeProvider.path;
|
||||||
public class Recipes {
|
public class Recipes {
|
||||||
private static final Ingredient SPORES_AND_SEEDS = ingredient(EItems.GRASS_SEEDS, EItems.MYCELIUM_SPORES, EItems.WARPED_NYLIUM_SPORES, EItems.CRIMSON_NYLIUM_SPORES);
|
private static final Ingredient SPORES_AND_SEEDS = ingredient(EItems.GRASS_SEEDS, EItems.MYCELIUM_SPORES, EItems.WARPED_NYLIUM_SPORES, EItems.CRIMSON_NYLIUM_SPORES);
|
||||||
|
|
||||||
public static void addRecipes(Consumer<FinishedRecipe> writer, MKRecipeProvider recipes) {
|
public static void addRecipes(RecipeOutput writer, MKRecipeProvider recipes) {
|
||||||
craftingRecipes(writer, recipes);
|
craftingRecipes(writer, recipes);
|
||||||
smeltingRecipes(recipes);
|
smeltingRecipes(recipes);
|
||||||
SieveRecipes.sieveRecipes(writer);
|
SieveRecipes.sieveRecipes(writer);
|
||||||
|
|
@ -92,7 +89,7 @@ public class Recipes {
|
||||||
fluidTransformationRecipes(writer);
|
fluidTransformationRecipes(writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void craftingRecipes(Consumer<FinishedRecipe> writer, MKRecipeProvider recipes) {
|
private static void craftingRecipes(RecipeOutput writer, MKRecipeProvider recipes) {
|
||||||
// Crooks
|
// Crooks
|
||||||
shapedCrook(recipes, EItems.CROOK, ingredient(Tags.Items.RODS_WOODEN));
|
shapedCrook(recipes, EItems.CROOK, ingredient(Tags.Items.RODS_WOODEN));
|
||||||
shapedCrook(recipes, EItems.BONE_CROOK, ingredient(Items.BONE));
|
shapedCrook(recipes, EItems.BONE_CROOK, ingredient(Items.BONE));
|
||||||
|
|
@ -183,36 +180,36 @@ public class Recipes {
|
||||||
modUShaped(recipes, ModIds.BLUE_SKIES, ModCompatData.CRYSTALLIZED_PLANKS_ITEM, ModCompatData.CRYSTALLIZED_SLAB, DefaultMaterials.CRYSTALLIZED_BARREL.getItem());
|
modUShaped(recipes, ModIds.BLUE_SKIES, ModCompatData.CRYSTALLIZED_PLANKS_ITEM, ModCompatData.CRYSTALLIZED_SLAB, DefaultMaterials.CRYSTALLIZED_BARREL.getItem());
|
||||||
|
|
||||||
// Pebbles and ore chunks
|
// Pebbles and ore chunks
|
||||||
recipes.grid2x2(Items.COBBLESTONE, ingredient(EItems.STONE_PEBBLE));
|
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.COBBLESTONE, ingredient(EItems.STONE_PEBBLE));
|
||||||
recipes.grid2x2(Items.ANDESITE, ingredient(EItems.ANDESITE_PEBBLE));
|
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.ANDESITE, ingredient(EItems.ANDESITE_PEBBLE));
|
||||||
recipes.grid2x2(Items.DIORITE, ingredient(EItems.DIORITE_PEBBLE));
|
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.DIORITE, ingredient(EItems.DIORITE_PEBBLE));
|
||||||
recipes.grid2x2(Items.GRANITE, ingredient(EItems.GRANITE_PEBBLE));
|
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.GRANITE, ingredient(EItems.GRANITE_PEBBLE));
|
||||||
recipes.grid2x2(Items.COBBLED_DEEPSLATE, ingredient(EItems.DEEPSLATE_PEBBLE));
|
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.COBBLED_DEEPSLATE, ingredient(EItems.DEEPSLATE_PEBBLE));
|
||||||
recipes.grid2x2(Items.TUFF, ingredient(EItems.TUFF_PEBBLE));
|
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.TUFF, ingredient(EItems.TUFF_PEBBLE));
|
||||||
recipes.grid2x2(Items.CALCITE, ingredient(EItems.CALCITE_PEBBLE));
|
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.CALCITE, ingredient(EItems.CALCITE_PEBBLE));
|
||||||
recipes.grid2x2(Items.BLACKSTONE, ingredient(EItems.BLACKSTONE_PEBBLE));
|
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.BLACKSTONE, ingredient(EItems.BLACKSTONE_PEBBLE));
|
||||||
recipes.grid2x2(Items.BASALT, ingredient(EItems.BASALT_PEBBLE));
|
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.BASALT, ingredient(EItems.BASALT_PEBBLE));
|
||||||
recipes.grid2x2(Items.IRON_ORE, ingredient(EItems.IRON_ORE_CHUNK));
|
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.IRON_ORE, ingredient(EItems.IRON_ORE_CHUNK));
|
||||||
recipes.grid2x2(Items.GOLD_ORE, ingredient(EItems.GOLD_ORE_CHUNK));
|
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.GOLD_ORE, ingredient(EItems.GOLD_ORE_CHUNK));
|
||||||
recipes.grid2x2(Items.COPPER_ORE, ingredient(EItems.COPPER_ORE_CHUNK));
|
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.COPPER_ORE, ingredient(EItems.COPPER_ORE_CHUNK));
|
||||||
recipes.grid2x2(Items.MOSS_BLOCK, ingredient(EItems.GRASS_SEEDS));
|
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.MOSS_BLOCK, ingredient(EItems.GRASS_SEEDS));
|
||||||
|
|
||||||
// Modded ores
|
// Modded ores
|
||||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_ALUMINUM, ingredient(EItems.ALUMINUM_ORE_CHUNK));
|
grid2x2TagResult(writer, EItemTags.ORES_ALUMINUM, ingredient(EItems.ALUMINUM_ORE_CHUNK));
|
||||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_COBALT, ingredient(EItems.COBALT_ORE_CHUNK));
|
grid2x2TagResult(writer, EItemTags.ORES_COBALT, ingredient(EItems.COBALT_ORE_CHUNK));
|
||||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_SILVER, ingredient(EItems.SILVER_ORE_CHUNK));
|
grid2x2TagResult(writer, EItemTags.ORES_SILVER, ingredient(EItems.SILVER_ORE_CHUNK));
|
||||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_LEAD, ingredient(EItems.LEAD_ORE_CHUNK));
|
grid2x2TagResult(writer, EItemTags.ORES_LEAD, ingredient(EItems.LEAD_ORE_CHUNK));
|
||||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_PLATINUM, ingredient(EItems.PLATINUM_ORE_CHUNK));
|
grid2x2TagResult(writer, EItemTags.ORES_PLATINUM, ingredient(EItems.PLATINUM_ORE_CHUNK));
|
||||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_NICKEL, ingredient(EItems.NICKEL_ORE_CHUNK));
|
grid2x2TagResult(writer, EItemTags.ORES_NICKEL, ingredient(EItems.NICKEL_ORE_CHUNK));
|
||||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_URANIUM, ingredient(EItems.URANIUM_ORE_CHUNK));
|
grid2x2TagResult(writer, EItemTags.ORES_URANIUM, ingredient(EItems.URANIUM_ORE_CHUNK));
|
||||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_OSMIUM, ingredient(EItems.OSMIUM_ORE_CHUNK));
|
grid2x2TagResult(writer, EItemTags.ORES_OSMIUM, ingredient(EItems.OSMIUM_ORE_CHUNK));
|
||||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_TIN, ingredient(EItems.TIN_ORE_CHUNK));
|
grid2x2TagResult(writer, EItemTags.ORES_TIN, ingredient(EItems.TIN_ORE_CHUNK));
|
||||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_ZINC, ingredient(EItems.ZINC_ORE_CHUNK));
|
grid2x2TagResult(writer, EItemTags.ORES_ZINC, ingredient(EItems.ZINC_ORE_CHUNK));
|
||||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_IRIDIUM, ingredient(EItems.IRIDIUM_ORE_CHUNK));
|
grid2x2TagResult(writer, EItemTags.ORES_IRIDIUM, ingredient(EItems.IRIDIUM_ORE_CHUNK));
|
||||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_THORIUM, ingredient(EItems.THORIUM_ORE_CHUNK));
|
grid2x2TagResult(writer, EItemTags.ORES_THORIUM, ingredient(EItems.THORIUM_ORE_CHUNK));
|
||||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_MAGNESIUM, ingredient(EItems.MAGNESIUM_ORE_CHUNK));
|
grid2x2TagResult(writer, EItemTags.ORES_MAGNESIUM, ingredient(EItems.MAGNESIUM_ORE_CHUNK));
|
||||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_LITHIUM, ingredient(EItems.LITHIUM_ORE_CHUNK));
|
grid2x2TagResult(writer, EItemTags.ORES_LITHIUM, ingredient(EItems.LITHIUM_ORE_CHUNK));
|
||||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_BORON, ingredient(EItems.BORON_ORE_CHUNK));
|
grid2x2TagResult(writer, EItemTags.ORES_BORON, ingredient(EItems.BORON_ORE_CHUNK));
|
||||||
|
|
||||||
// Sieves
|
// Sieves
|
||||||
sieve(recipes, DefaultMaterials.OAK_SIEVE.getItem(), Items.OAK_PLANKS, Items.OAK_SLAB);
|
sieve(recipes, DefaultMaterials.OAK_SIEVE.getItem(), Items.OAK_PLANKS, Items.OAK_SLAB);
|
||||||
|
|
@ -322,33 +319,24 @@ public class Recipes {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void modUShaped(MKRecipeProvider recipes, String modid, RegistryObject<? extends Item> sides, RegistryObject<? extends Item> middle, Item result) {
|
private static void modUShaped(MKRecipeProvider recipes, String modid, ItemLike sides, ItemLike middle, Item result) {
|
||||||
recipes.conditional(path(result), List.of(modInstalled(modid)), writer1 -> {
|
recipes.conditional(path(result), List.of(modInstalled(modid)), writer1 -> {
|
||||||
uShaped(recipes, result, ingredient(sides), ingredient(middle));
|
uShaped(recipes, result, ingredient(sides), ingredient(middle));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void modSieve(MKRecipeProvider recipes, String modid, RegistryObject<? extends Item> planks, RegistryObject<? extends Item> slab, Item result) {
|
private static void modSieve(MKRecipeProvider recipes, String modid, ItemLike planks, ItemLike slab, Item result) {
|
||||||
recipes.conditional(path(result), List.of(modInstalled(modid)), writer1 -> {
|
recipes.conditional(path(result), List.of(modInstalled(modid)), writer1 -> {
|
||||||
sieve(recipes, result, planks.get(), slab.get());
|
sieve(recipes, result, planks, slab);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void grid2x2TagResult(Consumer<FinishedRecipe> writer, MKRecipeProvider recipes, TagKey<Item> resultTag, Ingredient ingredient) {
|
private static void grid2x2TagResult(RecipeOutput writer, TagKey<Item> resultTag, Ingredient ingredient) {
|
||||||
// capture the generated recipe and wrap it in a TagResultRecipe
|
writer.accept(new ResourceLocation(resultTag.location().getPath() + "_from_chunks"), new OreChunkRecipe(ingredient, resultTag), null, tagNotEmpty(resultTag));
|
||||||
var wrappedRecipe = new MutableObject<FinishedRecipe>();
|
|
||||||
recipes.pushWriter(wrappedRecipe::setValue, newWriter -> {
|
|
||||||
recipes.shapedCrafting(resultTag.location().getPath() + "_tag", RecipeCategory.MISC, Items.AIR, recipe -> {
|
|
||||||
recipe.define('#', ingredient);
|
|
||||||
recipe.pattern("##");
|
|
||||||
recipe.pattern("##");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
writer.accept(new TagResultRecipe.Finished(resultTag, wrappedRecipe.getValue()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void shapedCrook(MKRecipeProvider recipes, RegistryObject<? extends Item> crook, Ingredient stick) {
|
private static void shapedCrook(MKRecipeProvider recipes, ItemLike crook, Ingredient stick) {
|
||||||
recipes.shapedCrafting(RecipeCategory.TOOLS, crook.get(), recipe -> {
|
recipes.shapedCrafting(RecipeCategory.TOOLS, crook, recipe -> {
|
||||||
recipe.define('x', stick);
|
recipe.define('x', stick);
|
||||||
recipe.pattern("xx");
|
recipe.pattern("xx");
|
||||||
recipe.pattern(" x");
|
recipe.pattern(" x");
|
||||||
|
|
@ -356,8 +344,8 @@ public class Recipes {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void shapedHammer(MKRecipeProvider recipes, RegistryObject<? extends Item> hammer, Ingredient material) {
|
private static void shapedHammer(MKRecipeProvider recipes, ItemLike hammer, Ingredient material) {
|
||||||
recipes.shapedCrafting(RecipeCategory.TOOLS, hammer.get(), recipe -> {
|
recipes.shapedCrafting(RecipeCategory.TOOLS, hammer, recipe -> {
|
||||||
recipe.define('m', material);
|
recipe.define('m', material);
|
||||||
recipe.define('s', Tags.Items.RODS_WOODEN);
|
recipe.define('s', Tags.Items.RODS_WOODEN);
|
||||||
recipe.pattern(" m ");
|
recipe.pattern(" m ");
|
||||||
|
|
@ -376,7 +364,7 @@ public class Recipes {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void sieve(MKRecipeProvider recipes, Item result, Item planks, Item slab) {
|
private static void sieve(MKRecipeProvider recipes, ItemLike result, ItemLike planks, ItemLike slab) {
|
||||||
recipes.shapedCrafting(RecipeCategory.MISC, result, recipe -> {
|
recipes.shapedCrafting(RecipeCategory.MISC, result, recipe -> {
|
||||||
recipe.define('O', planks);
|
recipe.define('O', planks);
|
||||||
recipe.define('_', slab);
|
recipe.define('_', slab);
|
||||||
|
|
@ -397,10 +385,10 @@ public class Recipes {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void meshUpgrade(MKRecipeProvider recipes, RegistryObject<? extends Item> newMesh, RegistryObject<? extends Item> previousMesh, Ingredient ingredient) {
|
private static void meshUpgrade(MKRecipeProvider recipes, ItemLike newMesh, ItemLike previousMesh, Ingredient ingredient) {
|
||||||
recipes.shapedCrafting(newMesh.getId().getPath() + "_from_" + previousMesh.getId().getPath(), RecipeCategory.MISC, newMesh.get(), recipe -> {
|
recipes.shapedCrafting(path(newMesh) + "_from_" + path(previousMesh), RecipeCategory.MISC, newMesh, recipe -> {
|
||||||
recipe.define('#', ingredient);
|
recipe.define('#', ingredient);
|
||||||
recipe.define('M', previousMesh.get());
|
recipe.define('M', previousMesh);
|
||||||
recipe.pattern(" # ");
|
recipe.pattern(" # ");
|
||||||
recipe.pattern("#M#");
|
recipe.pattern("#M#");
|
||||||
recipe.pattern(" # ");
|
recipe.pattern(" # ");
|
||||||
|
|
@ -423,7 +411,7 @@ public class Recipes {
|
||||||
|
|
||||||
recipes.foodCooking(EItems.SILK_WORM.get(), EItems.COOKED_SILK_WORM.get(), 0.1f);
|
recipes.foodCooking(EItems.SILK_WORM.get(), EItems.COOKED_SILK_WORM.get(), 0.1f);
|
||||||
}
|
}
|
||||||
private static void crucibleRecipes(Consumer<FinishedRecipe> writer) {
|
private static void crucibleRecipes(RecipeOutput writer) {
|
||||||
lavaCrucible(writer, "cobblestone", ingredient(Tags.Items.COBBLESTONE), 250);
|
lavaCrucible(writer, "cobblestone", ingredient(Tags.Items.COBBLESTONE), 250);
|
||||||
lavaCrucible(writer, "stone", ingredient(Tags.Items.STONE), 250);
|
lavaCrucible(writer, "stone", ingredient(Tags.Items.STONE), 250);
|
||||||
lavaCrucible(writer, "gravel", ingredient(Tags.Items.GRAVEL), 250);
|
lavaCrucible(writer, "gravel", ingredient(Tags.Items.GRAVEL), 250);
|
||||||
|
|
@ -439,7 +427,7 @@ public class Recipes {
|
||||||
waterCrucible(writer, "vine", ingredient(Items.VINE), 100);
|
waterCrucible(writer, "vine", ingredient(Items.VINE), 100);
|
||||||
waterCrucible(writer, "seeds_and_spores", SPORES_AND_SEEDS, 50);
|
waterCrucible(writer, "seeds_and_spores", SPORES_AND_SEEDS, 50);
|
||||||
waterCrucible(writer, "seeds", ingredient(Tags.Items.SEEDS), 50);
|
waterCrucible(writer, "seeds", ingredient(Tags.Items.SEEDS), 50);
|
||||||
waterCrucible(writer, "grass", ingredient(Items.GRASS, Items.TALL_GRASS), 100);
|
waterCrucible(writer, "grass", ingredient(Items.SHORT_GRASS, Items.TALL_GRASS), 100);
|
||||||
waterCrucible(writer, "grass_block", ingredient(Items.GRASS_BLOCK), 150);
|
waterCrucible(writer, "grass_block", ingredient(Items.GRASS_BLOCK), 150);
|
||||||
waterCrucible(writer, "sweet_berries", ingredient(Items.SWEET_BERRIES, Items.GLOW_BERRIES), 50);
|
waterCrucible(writer, "sweet_berries", ingredient(Items.SWEET_BERRIES, Items.GLOW_BERRIES), 50);
|
||||||
waterCrucible(writer, "melon_slice", ingredient(Items.MELON_SLICE), 50);
|
waterCrucible(writer, "melon_slice", ingredient(Items.MELON_SLICE), 50);
|
||||||
|
|
@ -457,15 +445,15 @@ public class Recipes {
|
||||||
waterCrucible(writer, "spore_blossom", ingredient(Items.SPORE_BLOSSOM), 150);
|
waterCrucible(writer, "spore_blossom", ingredient(Items.SPORE_BLOSSOM), 150);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void lavaCrucible(Consumer<FinishedRecipe> writer, String id, Ingredient ingredient, int volume) {
|
private static void lavaCrucible(RecipeOutput writer, String id, Ingredient ingredient, int volume) {
|
||||||
writer.accept(new FinishedCrucibleRecipe(new ResourceLocation(ExDeorum.ID, "lava_crucible/" + id), ERecipeSerializers.LAVA_CRUCIBLE.get(), ingredient, Fluids.LAVA, volume));
|
writer.accept(new ResourceLocation(ExDeorum.ID, "lava_crucible/" + id), new CrucibleRecipe.Lava(ingredient, new FluidStack(Fluids.LAVA, volume)), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void waterCrucible(Consumer<FinishedRecipe> writer, String id, Ingredient ingredient, int volume) {
|
private static void waterCrucible(RecipeOutput writer, String id, Ingredient ingredient, int volume) {
|
||||||
writer.accept(new FinishedCrucibleRecipe(new ResourceLocation(ExDeorum.ID, "water_crucible/" + id), ERecipeSerializers.WATER_CRUCIBLE.get(), ingredient, Fluids.WATER, volume));
|
writer.accept(new ResourceLocation(ExDeorum.ID, "water_crucible/" + id), new CrucibleRecipe.Water(ingredient, new FluidStack(Fluids.WATER, volume)), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void hammerRecipes(Consumer<FinishedRecipe> writer) {
|
private static void hammerRecipes(RecipeOutput writer) {
|
||||||
// Cobblestone -> Gravel -> Sand -> Dust
|
// Cobblestone -> Gravel -> Sand -> Dust
|
||||||
hammerRecipe(writer, "gravel", ingredient(Items.COBBLESTONE, Items.DIORITE, Items.GRANITE, Items.ANDESITE), Blocks.GRAVEL);
|
hammerRecipe(writer, "gravel", ingredient(Items.COBBLESTONE, Items.DIORITE, Items.GRANITE, Items.ANDESITE), Blocks.GRAVEL);
|
||||||
hammerRecipe(writer, "sand", ingredient(Items.GRAVEL), Blocks.SAND);
|
hammerRecipe(writer, "sand", ingredient(Items.GRAVEL), Blocks.SAND);
|
||||||
|
|
@ -500,27 +488,29 @@ public class Recipes {
|
||||||
hammerRecipe(writer, "pointed_dripstone", ingredient(Items.DRIPSTONE_BLOCK), Items.POINTED_DRIPSTONE, between(2, 4));
|
hammerRecipe(writer, "pointed_dripstone", ingredient(Items.DRIPSTONE_BLOCK), Items.POINTED_DRIPSTONE, between(2, 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void hammerRecipe(Consumer<FinishedRecipe> writer, String name, Ingredient block, ItemLike result) {
|
private static void hammerRecipe(RecipeOutput writer, String name, Ingredient block, ItemLike result) {
|
||||||
hammerRecipe(writer, name, block, result, ConstantValue.exactly(1f));
|
hammerRecipe(writer, name, block, result, ConstantValue.exactly(1f));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void hammerRecipe(Consumer<FinishedRecipe> writer, String name, Ingredient block, ItemLike result, NumberProvider resultAmount) {
|
private static void hammerRecipe(RecipeOutput writer, String name, Ingredient block, ItemLike result, NumberProvider resultAmount) {
|
||||||
writer.accept(new FinishedHammerRecipe(new ResourceLocation(ExDeorum.ID, "hammer/" + name), block, result.asItem(), resultAmount));
|
writer.accept(new ResourceLocation(ExDeorum.ID, "hammer/" + name), new HammerRecipe(block, result.asItem(), resultAmount), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void crookRecipes(Consumer<FinishedRecipe> writer) {
|
private static void crookRecipes(RecipeOutput writer) {
|
||||||
crookRecipe(writer, "silkworm", BlockPredicate.blockTag(BlockTags.LEAVES), EItems.SILK_WORM.get(), 0.01f);
|
crookRecipe(writer, "silkworm", BlockPredicate.blockTag(BlockTags.LEAVES), EItems.SILK_WORM.get(), 0.01f);
|
||||||
var fullyInfestedLeaves = BlockPredicate.blockState(EBlocks.INFESTED_LEAVES.get(), StatePropertiesPredicate.Builder.properties().hasProperty(InfestedLeavesBlock.FULLY_INFESTED, true).build());
|
@SuppressWarnings("OptionalGetWithoutIsPresent")
|
||||||
|
var fullyInfestedLeaves = BlockPredicate.blockState(EBlocks.INFESTED_LEAVES.get(), StatePropertiesPredicate.Builder.properties().hasProperty(InfestedLeavesBlock.FULLY_INFESTED, true).build().get());
|
||||||
crookRecipe(writer, "silkworm_bonus", fullyInfestedLeaves, EItems.SILK_WORM.get(), 0.01f);
|
crookRecipe(writer, "silkworm_bonus", fullyInfestedLeaves, EItems.SILK_WORM.get(), 0.01f);
|
||||||
crookRecipe(writer, "string_roll_1", fullyInfestedLeaves, Items.STRING, 0.4f);
|
crookRecipe(writer, "string_roll_1", fullyInfestedLeaves, Items.STRING, 0.4f);
|
||||||
crookRecipe(writer, "string_roll_2", fullyInfestedLeaves, Items.STRING, 0.1f);
|
crookRecipe(writer, "string_roll_2", fullyInfestedLeaves, Items.STRING, 0.1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void crookRecipe(Consumer<FinishedRecipe> writer, String name, BlockPredicate blockPredicate, ItemLike result, float chance) {
|
private static void crookRecipe(RecipeOutput writer, String name, BlockPredicate blockPredicate, ItemLike result, float chance) {
|
||||||
writer.accept(new FinishedCrookRecipe(new ResourceLocation(ExDeorum.ID, "crook/" + name), blockPredicate, result.asItem(), chance));
|
writer.accept(new ResourceLocation(ExDeorum.ID, "crook/" + name), new CrookRecipe(blockPredicate, result.asItem(), chance), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void crucibleHeatSources(Consumer<FinishedRecipe> writer) {
|
@SuppressWarnings("OptionalGetWithoutIsPresent")
|
||||||
|
private static void crucibleHeatSources(RecipeOutput writer) {
|
||||||
crucibleHeatSource(writer, Blocks.TORCH, 1);
|
crucibleHeatSource(writer, Blocks.TORCH, 1);
|
||||||
crucibleHeatSource(writer, Blocks.WALL_TORCH, 1);
|
crucibleHeatSource(writer, Blocks.WALL_TORCH, 1);
|
||||||
crucibleHeatSource(writer, Blocks.LANTERN, 1);
|
crucibleHeatSource(writer, Blocks.LANTERN, 1);
|
||||||
|
|
@ -531,19 +521,19 @@ public class Recipes {
|
||||||
crucibleHeatSource(writer, Blocks.FIRE, 5);
|
crucibleHeatSource(writer, Blocks.FIRE, 5);
|
||||||
crucibleHeatSource(writer, Blocks.SOUL_FIRE, 5);
|
crucibleHeatSource(writer, Blocks.SOUL_FIRE, 5);
|
||||||
|
|
||||||
crucibleHeatSource(writer, "lit_campfire", BlockPredicate.blockState(Blocks.CAMPFIRE, StatePropertiesPredicate.Builder.properties().hasProperty(CampfireBlock.LIT, true).build()), 2);
|
crucibleHeatSource(writer, "lit_campfire", BlockPredicate.blockState(Blocks.CAMPFIRE, StatePropertiesPredicate.Builder.properties().hasProperty(CampfireBlock.LIT, true).build().get()), 2);
|
||||||
crucibleHeatSource(writer, "lit_soul_campfire", BlockPredicate.blockState(Blocks.SOUL_CAMPFIRE, StatePropertiesPredicate.Builder.properties().hasProperty(CampfireBlock.LIT, true).build()), 2);
|
crucibleHeatSource(writer, "lit_soul_campfire", BlockPredicate.blockState(Blocks.SOUL_CAMPFIRE, StatePropertiesPredicate.Builder.properties().hasProperty(CampfireBlock.LIT, true).build().get()), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void crucibleHeatSource(Consumer<FinishedRecipe> writer, Block block, int heatValue) {
|
private static void crucibleHeatSource(RecipeOutput writer, Block block, int heatValue) {
|
||||||
crucibleHeatSource(writer, BuiltInRegistries.BLOCK.getKey(block).getPath(), BlockPredicate.singleBlock(block), heatValue);
|
crucibleHeatSource(writer, BuiltInRegistries.BLOCK.getKey(block).getPath(), BlockPredicate.singleBlock(block), heatValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void crucibleHeatSource(Consumer<FinishedRecipe> writer, String name, BlockPredicate blockPredicate, int heatValue) {
|
private static void crucibleHeatSource(RecipeOutput writer, String name, BlockPredicate blockPredicate, int heatValue) {
|
||||||
writer.accept(new FinishedCrucibleHeatRecipe(new ResourceLocation(ExDeorum.ID, "crucible_heat_source/" + name), blockPredicate, heatValue));
|
writer.accept(new ResourceLocation(ExDeorum.ID, "crucible_heat_source/" + name), new CrucibleHeatRecipe(blockPredicate, heatValue), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void barrelCompostRecipes(Consumer<FinishedRecipe> writer) {
|
private static void barrelCompostRecipes(RecipeOutput writer) {
|
||||||
// plants
|
// plants
|
||||||
barrelCompost(writer, "saplings", ingredient(ItemTags.SAPLINGS), 125);
|
barrelCompost(writer, "saplings", ingredient(ItemTags.SAPLINGS), 125);
|
||||||
barrelCompost(writer, "leaves", ingredient(ItemTags.LEAVES), 125);
|
barrelCompost(writer, "leaves", ingredient(ItemTags.LEAVES), 125);
|
||||||
|
|
@ -553,7 +543,7 @@ public class Recipes {
|
||||||
barrelCompost(writer, "lily_pad", ingredient(Items.LILY_PAD), 100);
|
barrelCompost(writer, "lily_pad", ingredient(Items.LILY_PAD), 100);
|
||||||
barrelCompost(writer, "sugar_cane", ingredient(Items.SUGAR_CANE), 80);
|
barrelCompost(writer, "sugar_cane", ingredient(Items.SUGAR_CANE), 80);
|
||||||
barrelCompost(writer, "vine", ingredient(Items.VINE), 100);
|
barrelCompost(writer, "vine", ingredient(Items.VINE), 100);
|
||||||
barrelCompost(writer, "grass", ingredient(Items.GRASS, Items.FERN), 100);
|
barrelCompost(writer, "grass", ingredient(Items.SHORT_GRASS, Items.FERN), 100);
|
||||||
barrelCompost(writer, "tall_grass", ingredient(Items.TALL_GRASS, Items.LARGE_FERN), 150);
|
barrelCompost(writer, "tall_grass", ingredient(Items.TALL_GRASS, Items.LARGE_FERN), 150);
|
||||||
barrelCompost(writer, "seagrass", ingredient(Items.SEAGRASS), 80);
|
barrelCompost(writer, "seagrass", ingredient(Items.SEAGRASS), 80);
|
||||||
barrelCompost(writer, "nether_wart", ingredient(Items.NETHER_WART), 100);
|
barrelCompost(writer, "nether_wart", ingredient(Items.NETHER_WART), 100);
|
||||||
|
|
@ -614,16 +604,16 @@ public class Recipes {
|
||||||
barrelCompost(writer, "golden_apples", ingredient(Items.GOLDEN_APPLE, Items.ENCHANTED_GOLDEN_APPLE), 1000);
|
barrelCompost(writer, "golden_apples", ingredient(Items.GOLDEN_APPLE, Items.ENCHANTED_GOLDEN_APPLE), 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void barrelCompost(Consumer<FinishedRecipe> writer, String id, Ingredient ingredient, int volume) {
|
private static void barrelCompost(RecipeOutput writer, String id, Ingredient ingredient, int volume) {
|
||||||
writer.accept(new FinishedBarrelCompostRecipe(new ResourceLocation(ExDeorum.ID, "barrel_compost/" + id), ingredient, volume));
|
writer.accept(new ResourceLocation(ExDeorum.ID, "barrel_compost/" + id), new BarrelCompostRecipe(ingredient, volume), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void barrelMixingRecipes(Consumer<FinishedRecipe> writer) {
|
private static void barrelMixingRecipes(RecipeOutput writer) {
|
||||||
// water
|
// water
|
||||||
barrelMixing(writer, ingredient(EItems.DUST.get()), Fluids.WATER, Items.CLAY);
|
barrelMixing(writer, ingredient(EItems.DUST.get()), Fluids.WATER, Items.CLAY);
|
||||||
barrelMixing(writer, ingredient(Items.MILK_BUCKET), Fluids.WATER, Items.SLIME_BLOCK);
|
barrelMixing(writer, ingredient(Items.MILK_BUCKET), Fluids.WATER, Items.SLIME_BLOCK);
|
||||||
barrelMixing(writer, "_from_porcelain_bucket", ingredient(EItems.PORCELAIN_MILK_BUCKET.get()), Fluids.WATER, Items.SLIME_BLOCK);
|
barrelMixing(writer, "_from_porcelain_bucket", ingredient(EItems.PORCELAIN_MILK_BUCKET.get()), Fluids.WATER, Items.SLIME_BLOCK);
|
||||||
barrelFluidMixing(writer, Fluids.WATER, ForgeMod.MILK.get(), Items.SLIME_BLOCK, true);
|
barrelFluidMixing(writer, Fluids.WATER, NeoForgeMod.MILK.get(), Items.SLIME_BLOCK, true);
|
||||||
barrelMixing(writer, ingredient(Items.SNOWBALL), Fluids.WATER, Items.ICE);
|
barrelMixing(writer, ingredient(Items.SNOWBALL), Fluids.WATER, Items.ICE);
|
||||||
barrelFluidMixing(writer, Fluids.WATER, Fluids.LAVA, Items.STONE, false);
|
barrelFluidMixing(writer, Fluids.WATER, Fluids.LAVA, Items.STONE, false);
|
||||||
// lava
|
// lava
|
||||||
|
|
@ -637,20 +627,20 @@ public class Recipes {
|
||||||
barrelMixing(writer, ingredient(Items.SAND), EFluids.WITCH_WATER.get(), Items.SOUL_SAND);
|
barrelMixing(writer, ingredient(Items.SAND), EFluids.WITCH_WATER.get(), Items.SOUL_SAND);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void barrelMixing(Consumer<FinishedRecipe> writer, Ingredient ingredient, Fluid fluidType, Item result) {
|
private static void barrelMixing(RecipeOutput writer, Ingredient ingredient, Fluid fluidType, Item result) {
|
||||||
barrelMixing(writer, "", ingredient, fluidType, result);
|
barrelMixing(writer, "", ingredient, fluidType, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void barrelMixing(Consumer<FinishedRecipe> writer, String suffix, Ingredient ingredient, Fluid fluidType, Item result) {
|
private static void barrelMixing(RecipeOutput writer, String suffix, Ingredient ingredient, Fluid fluidType, Item result) {
|
||||||
writer.accept(new FinishedBarrelMixingRecipe(new ResourceLocation(ExDeorum.ID, "barrel_mixing/" + path(result) + suffix), ingredient, fluidType, 1000, result));
|
writer.accept(modLoc("barrel_mixing/" + path(result) + suffix), new BarrelMixingRecipe(ingredient, fluidType, 1000, result), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void barrelFluidMixing(Consumer<FinishedRecipe> writer, Fluid base, Fluid additive, Item result, boolean consumesAdditive) {
|
private static void barrelFluidMixing(RecipeOutput writer, Fluid base, Fluid additive, Item result, boolean consumesAdditive) {
|
||||||
writer.accept(new FinishedBarrelFluidMixingRecipe(new ResourceLocation(ExDeorum.ID, "barrel_fluid_mixing/" + path(result)), base, 1000, additive, result, consumesAdditive));
|
writer.accept(modLoc("barrel_fluid_mixing/" + path(result)), new BarrelFluidMixingRecipe(base, 1000, additive, result, consumesAdditive), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void fluidTransformationRecipes(Consumer<FinishedRecipe> writer) {
|
private static void fluidTransformationRecipes(RecipeOutput writer) {
|
||||||
writer.accept(new FinishedFluidTransformationRecipe(modLoc("barrel_fluid_transformation/witch_water"), Fluids.WATER, EFluids.WITCH_WATER.get(), 0x2B1057, BlockPredicate.singleBlock(Blocks.MYCELIUM), WeightedList.<BlockState>builder().add(50, Blocks.RED_MUSHROOM.defaultBlockState()).add(50, Blocks.BROWN_MUSHROOM.defaultBlockState()).build(), 1700));
|
writer.accept(modLoc("barrel_fluid_transformation/witch_water"), new FluidTransformationRecipe(Fluids.WATER, EFluids.WITCH_WATER.get(), 0x2B1057, BlockPredicate.singleBlock(Blocks.MYCELIUM), WeightedList.<BlockState>builder().add(50, Blocks.RED_MUSHROOM.defaultBlockState()).add(50, Blocks.BROWN_MUSHROOM.defaultBlockState()).build(), 1700), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ResourceLocation modLoc(String path) {
|
static ResourceLocation modLoc(String path) {
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -35,41 +35,49 @@ import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.Items;
|
import net.minecraft.world.item.Items;
|
||||||
import net.minecraft.world.level.GameRules;
|
import net.minecraft.world.level.GameRules;
|
||||||
import net.minecraft.world.level.block.Block;
|
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.levelgen.Heightmap;
|
import net.minecraft.world.level.levelgen.Heightmap;
|
||||||
import net.minecraft.world.level.levelgen.XoroshiroRandomSource;
|
import net.minecraft.world.level.levelgen.XoroshiroRandomSource;
|
||||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.neoforged.api.distmarker.Dist;
|
||||||
import net.minecraftforge.client.event.ClientChatEvent;
|
import net.neoforged.bus.api.IEventBus;
|
||||||
import net.minecraftforge.common.ForgeMod;
|
import net.neoforged.fml.DistExecutor;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.neoforged.fml.InterModComms;
|
||||||
import net.minecraftforge.event.AddReloadListenerEvent;
|
import net.neoforged.fml.ModList;
|
||||||
import net.minecraftforge.event.OnDatapackSyncEvent;
|
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||||
import net.minecraftforge.event.TickEvent;
|
import net.neoforged.fml.event.lifecycle.InterModEnqueueEvent;
|
||||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
import net.neoforged.fml.loading.FMLEnvironment;
|
||||||
import net.minecraftforge.event.level.LevelEvent;
|
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||||
import net.minecraftforge.event.server.ServerStoppingEvent;
|
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent;
|
||||||
import net.minecraftforge.fluids.FluidInteractionRegistry;
|
import net.neoforged.neoforge.client.event.ClientChatEvent;
|
||||||
import net.minecraftforge.fml.DistExecutor;
|
import net.neoforged.neoforge.common.NeoForge;
|
||||||
import net.minecraftforge.fml.InterModComms;
|
import net.neoforged.neoforge.common.NeoForgeMod;
|
||||||
import net.minecraftforge.fml.ModList;
|
import net.neoforged.neoforge.event.AddReloadListenerEvent;
|
||||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
import net.neoforged.neoforge.event.OnDatapackSyncEvent;
|
||||||
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
|
import net.neoforged.neoforge.event.TickEvent;
|
||||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
import net.neoforged.neoforge.event.entity.player.PlayerEvent;
|
||||||
import net.minecraftforge.fml.loading.FMLEnvironment;
|
import net.neoforged.neoforge.event.level.LevelEvent;
|
||||||
|
import net.neoforged.neoforge.event.server.ServerStoppingEvent;
|
||||||
|
import net.neoforged.neoforge.fluids.FluidInteractionRegistry;
|
||||||
|
import net.neoforged.neoforge.fluids.capability.wrappers.FluidBucketWrapper;
|
||||||
|
import net.neoforged.neoforge.network.event.RegisterPayloadHandlerEvent;
|
||||||
|
import net.neoforged.neoforge.network.registration.IPayloadRegistrar;
|
||||||
import thedarkcolour.exdeorum.ExDeorum;
|
import thedarkcolour.exdeorum.ExDeorum;
|
||||||
import thedarkcolour.exdeorum.blockentity.helper.ItemHelper;
|
import thedarkcolour.exdeorum.blockentity.helper.ItemHelper;
|
||||||
import thedarkcolour.exdeorum.client.CompostColors;
|
import thedarkcolour.exdeorum.client.CompostColors;
|
||||||
import thedarkcolour.exdeorum.compat.ModIds;
|
import thedarkcolour.exdeorum.compat.ModIds;
|
||||||
import thedarkcolour.exdeorum.compat.top.ExDeorumTopCompat;
|
import thedarkcolour.exdeorum.compat.top.ExDeorumTopCompat;
|
||||||
import thedarkcolour.exdeorum.config.EConfig;
|
import thedarkcolour.exdeorum.config.EConfig;
|
||||||
|
import thedarkcolour.exdeorum.item.PorcelainBucket;
|
||||||
import thedarkcolour.exdeorum.item.WateringCanItem;
|
import thedarkcolour.exdeorum.item.WateringCanItem;
|
||||||
import thedarkcolour.exdeorum.material.BarrelMaterial;
|
import thedarkcolour.exdeorum.material.BarrelMaterial;
|
||||||
|
import thedarkcolour.exdeorum.network.ClientMessageHandler;
|
||||||
|
import thedarkcolour.exdeorum.network.MenuPropertyMessage;
|
||||||
import thedarkcolour.exdeorum.network.NetworkHandler;
|
import thedarkcolour.exdeorum.network.NetworkHandler;
|
||||||
import thedarkcolour.exdeorum.network.VisualUpdateTracker;
|
import thedarkcolour.exdeorum.network.VisualUpdateTracker;
|
||||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
||||||
|
import thedarkcolour.exdeorum.registry.EBlockEntities;
|
||||||
import thedarkcolour.exdeorum.registry.EFluids;
|
import thedarkcolour.exdeorum.registry.EFluids;
|
||||||
import thedarkcolour.exdeorum.registry.EItems;
|
import thedarkcolour.exdeorum.registry.EItems;
|
||||||
import thedarkcolour.exdeorum.tag.EBiomeTags;
|
import thedarkcolour.exdeorum.tag.EBiomeTags;
|
||||||
|
|
@ -81,9 +89,8 @@ import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public final class EventHandler {
|
public final class EventHandler {
|
||||||
public static void register() {
|
public static void register(IEventBus modBus) {
|
||||||
var fmlBus = MinecraftForge.EVENT_BUS;
|
var fmlBus = NeoForge.EVENT_BUS;
|
||||||
var modBus = FMLJavaModLoadingContext.get().getModEventBus();
|
|
||||||
|
|
||||||
fmlBus.addListener(EventHandler::onPlayerLogin);
|
fmlBus.addListener(EventHandler::onPlayerLogin);
|
||||||
fmlBus.addListener(EventHandler::onDataSynced);
|
fmlBus.addListener(EventHandler::onDataSynced);
|
||||||
|
|
@ -91,8 +98,10 @@ public final class EventHandler {
|
||||||
fmlBus.addListener(EventHandler::createSpawnTree);
|
fmlBus.addListener(EventHandler::createSpawnTree);
|
||||||
modBus.addListener(EventHandler::interModEnqueue);
|
modBus.addListener(EventHandler::interModEnqueue);
|
||||||
modBus.addListener(EventHandler::onCommonSetup);
|
modBus.addListener(EventHandler::onCommonSetup);
|
||||||
|
modBus.addListener(EventHandler::registerPayloadHandler);
|
||||||
fmlBus.addListener(EventHandler::serverShutdown);
|
fmlBus.addListener(EventHandler::serverShutdown);
|
||||||
fmlBus.addListener(EventHandler::serverTick);
|
fmlBus.addListener(EventHandler::serverTick);
|
||||||
|
fmlBus.addListener(EventHandler::registerCapabilities);
|
||||||
|
|
||||||
if (ExDeorum.DEBUG) {
|
if (ExDeorum.DEBUG) {
|
||||||
fmlBus.addListener(EventHandler::handleDebugCommands);
|
fmlBus.addListener(EventHandler::handleDebugCommands);
|
||||||
|
|
@ -147,10 +156,10 @@ public final class EventHandler {
|
||||||
|
|
||||||
for (var entry : EBiomeTags.TREE_TAGS.entrySet()) {
|
for (var entry : EBiomeTags.TREE_TAGS.entrySet()) {
|
||||||
if (biome.is(entry.getKey())) {
|
if (biome.is(entry.getKey())) {
|
||||||
var optional = entry.getValue().getHolder();
|
var optional = entry.getValue();
|
||||||
|
|
||||||
if (optional.isPresent()) {
|
if (optional.isBound()) {
|
||||||
holder = (optional.get());
|
holder = optional;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -171,14 +180,14 @@ public final class EventHandler {
|
||||||
|
|
||||||
private static void onCommonSetup(FMLCommonSetupEvent event) {
|
private static void onCommonSetup(FMLCommonSetupEvent event) {
|
||||||
event.enqueueWork(() -> {
|
event.enqueueWork(() -> {
|
||||||
FluidInteractionRegistry.addInteraction(ForgeMod.LAVA_TYPE.get(), new FluidInteractionRegistry.InteractionInformation(
|
FluidInteractionRegistry.addInteraction(NeoForgeMod.LAVA_TYPE.value(), new FluidInteractionRegistry.InteractionInformation(
|
||||||
EFluids.WITCH_WATER_TYPE.get(),
|
EFluids.WITCH_WATER_TYPE.get(),
|
||||||
fluidState -> fluidState.isSource() ? Blocks.OBSIDIAN.defaultBlockState() : (EConfig.SERVER.witchWaterNetherrackGenerator.get() ? Blocks.NETHERRACK.defaultBlockState() : Blocks.COBBLESTONE.defaultBlockState())
|
fluidState -> fluidState.isSource() ? Blocks.OBSIDIAN.defaultBlockState() : (EConfig.SERVER.witchWaterNetherrackGenerator.get() ? Blocks.NETHERRACK.defaultBlockState() : Blocks.COBBLESTONE.defaultBlockState())
|
||||||
));
|
));
|
||||||
var dirtVariants = new BlockState[]{Blocks.DIRT.defaultBlockState(), Blocks.PODZOL.defaultBlockState(), Blocks.COARSE_DIRT.defaultBlockState()};
|
var dirtVariants = new BlockState[]{Blocks.DIRT.defaultBlockState(), Blocks.PODZOL.defaultBlockState(), Blocks.COARSE_DIRT.defaultBlockState()};
|
||||||
var rng = RandomSource.create();
|
var rng = RandomSource.create();
|
||||||
FluidInteractionRegistry.addInteraction(EFluids.WITCH_WATER_TYPE.get(), new FluidInteractionRegistry.InteractionInformation(
|
FluidInteractionRegistry.addInteraction(EFluids.WITCH_WATER_TYPE.get(), new FluidInteractionRegistry.InteractionInformation(
|
||||||
(level, pos, relative, state) -> level.getFluidState(relative).getFluidType() == ForgeMod.WATER_TYPE.get() && EConfig.SERVER.witchWaterDirtGenerator.get(),
|
(level, pos, relative, state) -> level.getFluidState(relative).getFluidType() == NeoForgeMod.WATER_TYPE.value() && EConfig.SERVER.witchWaterDirtGenerator.get(),
|
||||||
fluidState -> Util.getRandom(dirtVariants, rng)
|
fluidState -> Util.getRandom(dirtVariants, rng)
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
@ -186,11 +195,16 @@ public final class EventHandler {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void registerPayloadHandler(RegisterPayloadHandlerEvent event) {
|
||||||
|
NetworkHandler.register(event.registrar(ExDeorum.ID));
|
||||||
|
}
|
||||||
|
|
||||||
private static void onDataSynced(OnDatapackSyncEvent event) {
|
private static void onDataSynced(OnDatapackSyncEvent event) {
|
||||||
UUID excludedUUID = null;
|
UUID excludedUUID = null;
|
||||||
|
|
||||||
if (FMLEnvironment.dist == Dist.CLIENT) {
|
if (FMLEnvironment.dist == Dist.CLIENT) {
|
||||||
// since event code is turned into ASM, we need this to prevent ASM trying to load the LocalPlayer class
|
// since event code is turned into ASM, we need this to prevent ASM trying to load the LocalPlayer class
|
||||||
|
// todo check if the IF statement can work here
|
||||||
Player player = DistExecutor.unsafeCallWhenOn(Dist.CLIENT, () -> ClientsideCode::getLocalPlayer);
|
Player player = DistExecutor.unsafeCallWhenOn(Dist.CLIENT, () -> ClientsideCode::getLocalPlayer);
|
||||||
if (player == null) {
|
if (player == null) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -219,7 +233,7 @@ public final class EventHandler {
|
||||||
// tries to account for other SkyBlock generator mods like SkyBlockBuilder
|
// tries to account for other SkyBlock generator mods like SkyBlockBuilder
|
||||||
if (generator instanceof VoidChunkGenerator || generator.getClass().getName().toLowerCase(Locale.ROOT).contains("skyblock")) {
|
if (generator instanceof VoidChunkGenerator || generator.getClass().getName().toLowerCase(Locale.ROOT).contains("skyblock")) {
|
||||||
NetworkHandler.sendVoidWorld(player);
|
NetworkHandler.sendVoidWorld(player);
|
||||||
var advancement = player.server.getAdvancements().getAdvancement(new ResourceLocation(ExDeorum.ID, "core/root"));
|
var advancement = player.server.getAdvancements().get(new ResourceLocation(ExDeorum.ID, "core/root"));
|
||||||
|
|
||||||
if (advancement != null) {
|
if (advancement != null) {
|
||||||
if (!player.getAdvancements().getOrStartProgress(advancement).isDone()) {
|
if (!player.getAdvancements().getOrStartProgress(advancement).isDone()) {
|
||||||
|
|
@ -262,4 +276,30 @@ public final class EventHandler {
|
||||||
VisualUpdateTracker.syncVisualUpdates();
|
VisualUpdateTracker.syncVisualUpdates();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void registerCapabilities(RegisterCapabilitiesEvent event) {
|
||||||
|
event.registerBlockEntity(Capabilities.ItemHandler.BLOCK, EBlockEntities.BARREL.get(), (barrel, direction) -> barrel.getItemHandler());
|
||||||
|
event.registerBlockEntity(Capabilities.FluidHandler.BLOCK, EBlockEntities.BARREL.get(), (barrel, direction) -> barrel.getTank());
|
||||||
|
|
||||||
|
event.registerBlockEntity(Capabilities.ItemHandler.BLOCK, EBlockEntities.MECHANICAL_SIEVE.get(), (sieve, direction) -> sieve.getItemHandler());
|
||||||
|
event.registerBlockEntity(Capabilities.EnergyStorage.BLOCK, EBlockEntities.MECHANICAL_SIEVE.get(), (sieve, direction) -> sieve.getEnergyStorage());
|
||||||
|
|
||||||
|
event.registerBlockEntity(Capabilities.ItemHandler.BLOCK, EBlockEntities.MECHANICAL_HAMMER.get(), (hammer, direction) -> hammer.getItemHandler());
|
||||||
|
event.registerBlockEntity(Capabilities.EnergyStorage.BLOCK, EBlockEntities.MECHANICAL_HAMMER.get(), (hammer, direction) -> hammer.getEnergyStorage());
|
||||||
|
|
||||||
|
event.registerBlockEntity(Capabilities.ItemHandler.BLOCK, EBlockEntities.LAVA_CRUCIBLE.get(), (hammer, direction) -> hammer.getItem());
|
||||||
|
event.registerBlockEntity(Capabilities.FluidHandler.BLOCK, EBlockEntities.LAVA_CRUCIBLE.get(), (hammer, direction) -> hammer.getTank());
|
||||||
|
|
||||||
|
event.registerBlockEntity(Capabilities.ItemHandler.BLOCK, EBlockEntities.WATER_CRUCIBLE.get(), (hammer, direction) -> hammer.getItem());
|
||||||
|
event.registerBlockEntity(Capabilities.FluidHandler.BLOCK, EBlockEntities.WATER_CRUCIBLE.get(), (hammer, direction) -> hammer.getTank());
|
||||||
|
|
||||||
|
event.registerItem(Capabilities.FluidHandler.ITEM, (stack, ctx) -> new PorcelainBucket.ItemHandler(stack),
|
||||||
|
EItems.PORCELAIN_BUCKET,
|
||||||
|
EItems.PORCELAIN_WATER_BUCKET,
|
||||||
|
EItems.PORCELAIN_LAVA_BUCKET,
|
||||||
|
EItems.PORCELAIN_MILK_BUCKET,
|
||||||
|
EItems.PORCELAIN_WITCH_WATER_BUCKET);
|
||||||
|
event.registerItem(Capabilities.FluidHandler.ITEM, (stack, ctx) -> new FluidBucketWrapper(stack), EItems.WITCH_WATER_BUCKET);
|
||||||
|
event.registerItem(Capabilities.FluidHandler.ITEM, (stack, ctx) -> new WateringCanItem.FluidHandler(stack));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,10 +22,10 @@ import net.minecraft.client.Camera;
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.sounds.SoundEvents;
|
import net.minecraft.sounds.SoundEvents;
|
||||||
import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions;
|
import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions;
|
||||||
import net.minecraftforge.common.SoundActions;
|
import net.neoforged.neoforge.common.SoundActions;
|
||||||
import net.minecraftforge.fluids.FluidType;
|
import net.neoforged.neoforge.fluids.BaseFlowingFluid;
|
||||||
import net.minecraftforge.fluids.ForgeFlowingFluid;
|
import net.neoforged.neoforge.fluids.FluidType;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
import thedarkcolour.exdeorum.ExDeorum;
|
import thedarkcolour.exdeorum.ExDeorum;
|
||||||
|
|
@ -40,8 +40,8 @@ public class WitchWaterFluid extends FluidType {
|
||||||
private static final ResourceLocation FLOWING_TEXTURE = new ResourceLocation(ExDeorum.ID, "block/witch_water_flowing");
|
private static final ResourceLocation FLOWING_TEXTURE = new ResourceLocation(ExDeorum.ID, "block/witch_water_flowing");
|
||||||
private static final ResourceLocation OVERLAY_TEXTURE = new ResourceLocation("block/water_overlay");
|
private static final ResourceLocation OVERLAY_TEXTURE = new ResourceLocation("block/water_overlay");
|
||||||
|
|
||||||
public static ForgeFlowingFluid.Properties properties() {
|
public static BaseFlowingFluid.Properties properties() {
|
||||||
return new ForgeFlowingFluid.Properties(EFluids.WITCH_WATER_TYPE, EFluids.WITCH_WATER, EFluids.WITCH_WATER_FLOWING).block(EBlocks.WITCH_WATER).bucket(EItems.WITCH_WATER_BUCKET);
|
return new BaseFlowingFluid.Properties(EFluids.WITCH_WATER_TYPE, EFluids.WITCH_WATER, EFluids.WITCH_WATER_FLOWING).block(EBlocks.WITCH_WATER).bucket(EItems.WITCH_WATER_BUCKET);
|
||||||
}
|
}
|
||||||
|
|
||||||
public WitchWaterFluid() {
|
public WitchWaterFluid() {
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ import net.minecraft.world.item.enchantment.Enchantment;
|
||||||
import net.minecraft.world.item.enchantment.Enchantments;
|
import net.minecraft.world.item.enchantment.Enchantments;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraftforge.common.Tags;
|
import net.neoforged.neoforge.common.Tags;
|
||||||
import thedarkcolour.exdeorum.registry.EItems;
|
import thedarkcolour.exdeorum.registry.EItems;
|
||||||
|
|
||||||
// Silk worms have a 1 in 100 chance to drop from regular leaves, 1 in 15 if the block is infested.
|
// Silk worms have a 1 in 100 chance to drop from regular leaves, 1 in 15 if the block is infested.
|
||||||
|
|
|
||||||
|
|
@ -19,19 +19,28 @@
|
||||||
package thedarkcolour.exdeorum.item;
|
package thedarkcolour.exdeorum.item;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.tags.BlockTags;
|
import net.minecraft.tags.BlockTags;
|
||||||
import net.minecraft.world.item.BlockItem;
|
import net.minecraft.world.item.BlockItem;
|
||||||
import net.minecraft.world.item.DiggerItem;
|
import net.minecraft.world.item.DiggerItem;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.Tier;
|
import net.minecraft.world.item.Tier;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeHolder;
|
||||||
import net.minecraft.world.item.crafting.RecipeType;
|
import net.minecraft.world.item.crafting.RecipeType;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraftforge.common.util.Lazy;
|
import net.neoforged.api.distmarker.Dist;
|
||||||
|
import net.neoforged.fml.loading.FMLEnvironment;
|
||||||
|
import net.neoforged.neoforge.common.TierSortingRegistry;
|
||||||
|
import net.neoforged.neoforge.common.util.Lazy;
|
||||||
|
import net.neoforged.neoforge.server.ServerLifecycleHooks;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
import thedarkcolour.exdeorum.recipe.hammer.HammerRecipe;
|
||||||
import thedarkcolour.exdeorum.registry.EItems;
|
import thedarkcolour.exdeorum.registry.EItems;
|
||||||
|
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class HammerItem extends DiggerItem {
|
public class HammerItem extends DiggerItem {
|
||||||
|
|
@ -42,11 +51,17 @@ public class HammerItem extends DiggerItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Set<Block> computeValidBlocks() {
|
public static Set<Block> computeValidBlocks() {
|
||||||
var hammerRecipes = RecipeUtil.getCachedHammerRecipes();
|
Collection<RecipeHolder<HammerRecipe>> hammerRecipes;
|
||||||
|
// todo test that this works properly
|
||||||
|
if (FMLEnvironment.dist == Dist.CLIENT) {
|
||||||
|
hammerRecipes = Objects.requireNonNull(Minecraft.getInstance().level).getRecipeManager().byType(ERecipeTypes.HAMMER.get()).values();
|
||||||
|
} else {
|
||||||
|
hammerRecipes = ServerLifecycleHooks.getCurrentServer().getRecipeManager().byType(ERecipeTypes.HAMMER.get()).values();
|
||||||
|
}
|
||||||
var validBlocks = new ObjectOpenHashSet<Block>(hammerRecipes.size());
|
var validBlocks = new ObjectOpenHashSet<Block>(hammerRecipes.size());
|
||||||
|
|
||||||
for (var recipe : hammerRecipes) {
|
for (var recipe : hammerRecipes) {
|
||||||
for (var item : recipe.getIngredient().getItems()) {
|
for (var item : recipe.value().getIngredient().getItems()) {
|
||||||
if (item.getItem() instanceof BlockItem blockItem) {
|
if (item.getItem() instanceof BlockItem blockItem) {
|
||||||
validBlocks.add(blockItem.getBlock());
|
validBlocks.add(blockItem.getBlock());
|
||||||
}
|
}
|
||||||
|
|
@ -71,10 +86,11 @@ public class HammerItem extends DiggerItem {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCorrectToolForDrops(BlockState state) {
|
public boolean isCorrectToolForDrops(BlockState state) {
|
||||||
if (net.minecraftforge.common.TierSortingRegistry.isTierSorted(getTier())) {
|
var tier = getTier();
|
||||||
return net.minecraftforge.common.TierSortingRegistry.isCorrectTierForDrops(getTier(), state) && getValidBlocks().contains(state.getBlock());
|
if (TierSortingRegistry.isTierSorted(tier)) {
|
||||||
|
return TierSortingRegistry.isCorrectTierForDrops(tier, state) && getValidBlocks().contains(state.getBlock());
|
||||||
}
|
}
|
||||||
int i = this.getTier().getLevel();
|
int i = tier.getLevel();
|
||||||
if (i < 3 && state.is(BlockTags.NEEDS_DIAMOND_TOOL)) {
|
if (i < 3 && state.is(BlockTags.NEEDS_DIAMOND_TOOL)) {
|
||||||
return false;
|
return false;
|
||||||
} else if (i < 2 && state.is(BlockTags.NEEDS_IRON_TOOL)) {
|
} else if (i < 2 && state.is(BlockTags.NEEDS_IRON_TOOL)) {
|
||||||
|
|
@ -87,7 +103,7 @@ public class HammerItem extends DiggerItem {
|
||||||
// FORGE START
|
// FORGE START
|
||||||
@Override
|
@Override
|
||||||
public boolean isCorrectToolForDrops(ItemStack stack, BlockState state) {
|
public boolean isCorrectToolForDrops(ItemStack stack, BlockState state) {
|
||||||
return getValidBlocks().contains(state.getBlock()) && net.minecraftforge.common.TierSortingRegistry.isCorrectTierForDrops(getTier(), state);
|
return getValidBlocks().contains(state.getBlock()) && TierSortingRegistry.isCorrectTierForDrops(getTier(), state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ package thedarkcolour.exdeorum.item;
|
||||||
|
|
||||||
import net.minecraft.tags.BlockTags;
|
import net.minecraft.tags.BlockTags;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraftforge.common.Tags;
|
import net.neoforged.neoforge.common.Tags;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,7 @@ package thedarkcolour.exdeorum.item;
|
||||||
|
|
||||||
import net.minecraft.advancements.CriteriaTriggers;
|
import net.minecraft.advancements.CriteriaTriggers;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.core.particles.ParticleTypes;
|
import net.minecraft.core.particles.ParticleTypes;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.sounds.SoundEvents;
|
import net.minecraft.sounds.SoundEvents;
|
||||||
import net.minecraft.sounds.SoundSource;
|
import net.minecraft.sounds.SoundSource;
|
||||||
|
|
@ -49,14 +47,13 @@ import net.minecraft.world.level.material.Fluid;
|
||||||
import net.minecraft.world.level.material.Fluids;
|
import net.minecraft.world.level.material.Fluids;
|
||||||
import net.minecraft.world.phys.BlockHitResult;
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
import net.minecraft.world.phys.HitResult;
|
import net.minecraft.world.phys.HitResult;
|
||||||
import net.minecraftforge.common.ForgeMod;
|
import net.neoforged.neoforge.common.NeoForgeMod;
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import net.neoforged.neoforge.common.SoundActions;
|
||||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
import net.neoforged.neoforge.event.EventHooks;
|
||||||
import net.minecraftforge.common.capabilities.ICapabilityProvider;
|
import net.neoforged.neoforge.fluids.FluidStack;
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.neoforged.neoforge.fluids.FluidUtil;
|
||||||
import net.minecraftforge.fluids.FluidStack;
|
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
|
||||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
import net.neoforged.neoforge.fluids.capability.IFluidHandlerItem;
|
||||||
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import thedarkcolour.exdeorum.registry.EFluids;
|
import thedarkcolour.exdeorum.registry.EFluids;
|
||||||
|
|
@ -94,7 +91,7 @@ public class PorcelainBucket extends Item {
|
||||||
public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand pHand) {
|
public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand pHand) {
|
||||||
var stack = player.getItemInHand(pHand);
|
var stack = player.getItemInHand(pHand);
|
||||||
var hitResult = getPlayerPOVHitResult(level, player, this.fluid.get() == Fluids.EMPTY ? ClipContext.Fluid.SOURCE_ONLY : ClipContext.Fluid.NONE);
|
var hitResult = getPlayerPOVHitResult(level, player, this.fluid.get() == Fluids.EMPTY ? ClipContext.Fluid.SOURCE_ONLY : ClipContext.Fluid.NONE);
|
||||||
var ret = net.minecraftforge.event.ForgeEventFactory.onBucketUse(player, level, stack, hitResult);
|
var ret = EventHooks.onBucketUse(player, level, stack, hitResult);
|
||||||
if (ret != null) return ret;
|
if (ret != null) return ret;
|
||||||
if (hitResult.getType() == HitResult.Type.MISS) {
|
if (hitResult.getType() == HitResult.Type.MISS) {
|
||||||
return InteractionResultHolder.pass(stack);
|
return InteractionResultHolder.pass(stack);
|
||||||
|
|
@ -109,13 +106,13 @@ public class PorcelainBucket extends Item {
|
||||||
var state = level.getBlockState(pos);
|
var state = level.getBlockState(pos);
|
||||||
var fluidType = state.getFluidState().getFluidType();
|
var fluidType = state.getFluidState().getFluidType();
|
||||||
|
|
||||||
if (fluidType == ForgeMod.WATER_TYPE.get() || fluidType == ForgeMod.LAVA_TYPE.get() || fluidType == EFluids.WITCH_WATER_TYPE.get()) {
|
if (fluidType == NeoForgeMod.WATER_TYPE.value() || fluidType == NeoForgeMod.LAVA_TYPE.value() || fluidType == EFluids.WITCH_WATER_TYPE.value()) {
|
||||||
if (state.getBlock() instanceof BucketPickup pickup) {
|
if (state.getBlock() instanceof BucketPickup pickup) {
|
||||||
var result = pickup.pickupBlock(level, pos, state);
|
var result = pickup.pickupBlock(player, level, pos, state);
|
||||||
|
|
||||||
if (fluidType == ForgeMod.WATER_TYPE.get()) {
|
if (fluidType == NeoForgeMod.WATER_TYPE.value()) {
|
||||||
result = new ItemStack(EItems.PORCELAIN_WATER_BUCKET.get());
|
result = new ItemStack(EItems.PORCELAIN_WATER_BUCKET.get());
|
||||||
} else if (fluidType == ForgeMod.LAVA_TYPE.get()) {
|
} else if (fluidType == NeoForgeMod.LAVA_TYPE.value()) {
|
||||||
result = new ItemStack(EItems.PORCELAIN_LAVA_BUCKET.get());
|
result = new ItemStack(EItems.PORCELAIN_LAVA_BUCKET.get());
|
||||||
} else {
|
} else {
|
||||||
result = new ItemStack(EItems.PORCELAIN_WITCH_WATER_BUCKET.get());
|
result = new ItemStack(EItems.PORCELAIN_WITCH_WATER_BUCKET.get());
|
||||||
|
|
@ -138,7 +135,7 @@ public class PorcelainBucket extends Item {
|
||||||
return InteractionResultHolder.fail(stack);
|
return InteractionResultHolder.fail(stack);
|
||||||
} else {
|
} else {
|
||||||
var state = level.getBlockState(pos);
|
var state = level.getBlockState(pos);
|
||||||
var placePos = canBlockContainFluid(level, pos, state) ? pos : relative;
|
var placePos = canBlockContainFluid(player, level, pos, state) ? pos : relative;
|
||||||
|
|
||||||
if (emptyContents(player, level, placePos, hitResult, stack)) {
|
if (emptyContents(player, level, placePos, hitResult, stack)) {
|
||||||
if (player instanceof ServerPlayer serverPlayer) {
|
if (player instanceof ServerPlayer serverPlayer) {
|
||||||
|
|
@ -176,8 +173,8 @@ public class PorcelainBucket extends Item {
|
||||||
var state = level.getBlockState(pos);
|
var state = level.getBlockState(pos);
|
||||||
var block = state.getBlock();
|
var block = state.getBlock();
|
||||||
var replacing = state.canBeReplaced(this.fluid.get());
|
var replacing = state.canBeReplaced(this.fluid.get());
|
||||||
var canPlaceAtPos = state.isAir() || replacing || block instanceof LiquidBlockContainer liquidContainer && liquidContainer.canPlaceLiquid(level, pos, state, this.fluid.get());
|
var canPlaceAtPos = state.isAir() || replacing || block instanceof LiquidBlockContainer liquidContainer && liquidContainer.canPlaceLiquid(player, level, pos, state, this.fluid.get());
|
||||||
var containedFluidStack = java.util.Optional.ofNullable(container).flatMap(net.minecraftforge.fluids.FluidUtil::getFluidContained);
|
var containedFluidStack = java.util.Optional.ofNullable(container).flatMap(FluidUtil::getFluidContained);
|
||||||
|
|
||||||
if (!canPlaceAtPos) {
|
if (!canPlaceAtPos) {
|
||||||
return hitResult != null && this.emptyContents(player, level, hitResult.getBlockPos().relative(hitResult.getDirection()), null, container);
|
return hitResult != null && this.emptyContents(player, level, hitResult.getBlockPos().relative(hitResult.getDirection()), null, container);
|
||||||
|
|
@ -195,7 +192,7 @@ public class PorcelainBucket extends Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else if (block instanceof LiquidBlockContainer liquidContainer && liquidContainer.canPlaceLiquid(level, pos, state, this.fluid.get())) {
|
} else if (block instanceof LiquidBlockContainer liquidContainer && liquidContainer.canPlaceLiquid(player, level, pos, state, this.fluid.get())) {
|
||||||
liquidContainer.placeLiquid(level, pos, state, ((FlowingFluid)this.fluid.get()).getSource(false));
|
liquidContainer.placeLiquid(level, pos, state, ((FlowingFluid)this.fluid.get()).getSource(false));
|
||||||
playEmptySound(player, level, pos);
|
playEmptySound(player, level, pos);
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -215,7 +212,7 @@ public class PorcelainBucket extends Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void playEmptySound(@Nullable Player pPlayer, LevelAccessor pLevel, BlockPos pPos) {
|
protected void playEmptySound(@Nullable Player pPlayer, LevelAccessor pLevel, BlockPos pPos) {
|
||||||
var sound = this.fluid.get().getFluidType().getSound(pPlayer, pLevel, pPos, net.minecraftforge.common.SoundActions.BUCKET_EMPTY);
|
var sound = this.fluid.get().getFluidType().getSound(pPlayer, pLevel, pPos, SoundActions.BUCKET_EMPTY);
|
||||||
if (sound == null) {
|
if (sound == null) {
|
||||||
sound = this.fluid.get().is(FluidTags.LAVA) ? SoundEvents.BUCKET_EMPTY_LAVA : SoundEvents.BUCKET_EMPTY;
|
sound = this.fluid.get().is(FluidTags.LAVA) ? SoundEvents.BUCKET_EMPTY_LAVA : SoundEvents.BUCKET_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
@ -223,20 +220,14 @@ public class PorcelainBucket extends Item {
|
||||||
pLevel.gameEvent(pPlayer, GameEvent.FLUID_PLACE, pPos);
|
pLevel.gameEvent(pPlayer, GameEvent.FLUID_PLACE, pPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean canBlockContainFluid(Level level, BlockPos pos, BlockState state) {
|
protected boolean canBlockContainFluid(Player player, Level level, BlockPos pos, BlockState state) {
|
||||||
return state.getBlock() instanceof LiquidBlockContainer block && block.canPlaceLiquid(level, pos, state, this.fluid.get());
|
return state.getBlock() instanceof LiquidBlockContainer block && block.canPlaceLiquid(player, level, pos, state, this.fluid.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public static class ItemHandler implements IFluidHandlerItem {
|
||||||
public @Nullable ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundTag nbt) {
|
|
||||||
return new PorcelainBucket.CapabilityProvider(stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
static class CapabilityProvider implements ICapabilityProvider, IFluidHandlerItem {
|
|
||||||
private final LazyOptional<IFluidHandlerItem> holder = LazyOptional.of(() -> this);
|
|
||||||
private ItemStack container;
|
private ItemStack container;
|
||||||
|
|
||||||
public CapabilityProvider(ItemStack container) {
|
public ItemHandler(ItemStack container) {
|
||||||
this.container = container;
|
this.container = container;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -246,12 +237,6 @@ public class PorcelainBucket extends Item {
|
||||||
return this.container;
|
return this.container;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
|
|
||||||
return ForgeCapabilities.FLUID_HANDLER_ITEM.orEmpty(cap, this.holder);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getTanks() {
|
public int getTanks() {
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -270,7 +255,7 @@ public class PorcelainBucket extends Item {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFluidValid(int tank, @NotNull FluidStack stack) {
|
public boolean isFluidValid(int tank, @NotNull FluidStack stack) {
|
||||||
return stack.getFluid() == Fluids.LAVA || stack.getFluid() == Fluids.WATER || stack.getFluid() == EFluids.WITCH_WATER.get() || (ForgeMod.MILK.isPresent() && stack.getFluid() == ForgeMod.MILK.get());
|
return stack.getFluid() == Fluids.LAVA || stack.getFluid() == Fluids.WATER || stack.getFluid() == EFluids.WITCH_WATER.get() || (NeoForgeMod.MILK.isBound() && stack.getFluid() == NeoForgeMod.MILK.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -328,8 +313,8 @@ public class PorcelainBucket extends Item {
|
||||||
return new FluidStack(Fluids.WATER, 1000);
|
return new FluidStack(Fluids.WATER, 1000);
|
||||||
} else if (item == EItems.PORCELAIN_WITCH_WATER_BUCKET.get()) {
|
} else if (item == EItems.PORCELAIN_WITCH_WATER_BUCKET.get()) {
|
||||||
return new FluidStack(EFluids.WITCH_WATER.get(), 1000);
|
return new FluidStack(EFluids.WITCH_WATER.get(), 1000);
|
||||||
} else if (item == EItems.PORCELAIN_MILK_BUCKET.get() && ForgeMod.MILK.isPresent()) {
|
} else if (item == EItems.PORCELAIN_MILK_BUCKET.get() && NeoForgeMod.MILK.isBound()) {
|
||||||
return new FluidStack(ForgeMod.MILK.get(), 1000);
|
return new FluidStack(NeoForgeMod.MILK.get(), 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
return FluidStack.EMPTY;
|
return FluidStack.EMPTY;
|
||||||
|
|
@ -344,7 +329,7 @@ public class PorcelainBucket extends Item {
|
||||||
this.container = new ItemStack(EItems.PORCELAIN_WATER_BUCKET.get());
|
this.container = new ItemStack(EItems.PORCELAIN_WATER_BUCKET.get());
|
||||||
} else if (fluidStack.getFluid() == EFluids.WITCH_WATER.get()) {
|
} else if (fluidStack.getFluid() == EFluids.WITCH_WATER.get()) {
|
||||||
this.container = new ItemStack(EItems.PORCELAIN_WITCH_WATER_BUCKET.get());
|
this.container = new ItemStack(EItems.PORCELAIN_WITCH_WATER_BUCKET.get());
|
||||||
} else if (ForgeMod.MILK.isPresent() && fluidStack.getFluid() == ForgeMod.MILK.get()) {
|
} else if (NeoForgeMod.MILK.isBound() && fluidStack.getFluid() == NeoForgeMod.MILK.get()) {
|
||||||
this.container = new ItemStack(EItems.PORCELAIN_MILK_BUCKET.get());
|
this.container = new ItemStack(EItems.PORCELAIN_MILK_BUCKET.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,17 +18,11 @@
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.item;
|
package thedarkcolour.exdeorum.item;
|
||||||
|
|
||||||
import net.minecraft.nbt.CompoundTag;
|
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.Items;
|
import net.minecraft.world.item.Items;
|
||||||
import net.minecraft.world.item.MilkBucketItem;
|
import net.minecraft.world.item.MilkBucketItem;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraftforge.common.ForgeMod;
|
|
||||||
import net.minecraftforge.common.capabilities.ICapabilityProvider;
|
|
||||||
import net.minecraftforge.fluids.FluidStack;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import thedarkcolour.exdeorum.registry.EItems;
|
import thedarkcolour.exdeorum.registry.EItems;
|
||||||
|
|
||||||
public class PorcelainMilkBucket extends MilkBucketItem {
|
public class PorcelainMilkBucket extends MilkBucketItem {
|
||||||
|
|
@ -46,20 +40,4 @@ public class PorcelainMilkBucket extends MilkBucketItem {
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundTag nbt) {
|
|
||||||
return new PorcelainBucket.CapabilityProvider(stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class CapabilityProvider extends PorcelainBucket.CapabilityProvider {
|
|
||||||
public CapabilityProvider(@NotNull ItemStack container) {
|
|
||||||
super(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFluidValid(int tank, @NotNull FluidStack stack) {
|
|
||||||
return ForgeMod.MILK.isPresent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ import net.minecraft.client.player.LocalPlayer;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.core.particles.ParticleTypes;
|
import net.minecraft.core.particles.ParticleTypes;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.sounds.SoundEvents;
|
import net.minecraft.sounds.SoundEvents;
|
||||||
|
|
@ -51,15 +50,13 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.material.Fluids;
|
import net.minecraft.world.level.material.Fluids;
|
||||||
import net.minecraft.world.phys.BlockHitResult;
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
import net.minecraft.world.phys.HitResult;
|
import net.minecraft.world.phys.HitResult;
|
||||||
import net.minecraftforge.client.extensions.common.IClientItemExtensions;
|
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||||
import net.minecraftforge.common.ForgeMod;
|
import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions;
|
||||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
import net.neoforged.neoforge.common.NeoForgeMod;
|
||||||
import net.minecraftforge.common.capabilities.ICapabilityProvider;
|
import net.neoforged.neoforge.common.util.FakePlayer;
|
||||||
import net.minecraftforge.common.util.FakePlayer;
|
import net.neoforged.neoforge.fluids.FluidStack;
|
||||||
import net.minecraftforge.fluids.FluidStack;
|
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
|
||||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
import net.neoforged.neoforge.fluids.capability.templates.FluidHandlerItemStack;
|
||||||
import net.minecraftforge.fluids.capability.templates.FluidHandlerItemStack;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import thedarkcolour.exdeorum.blockentity.BarrelBlockEntity;
|
import thedarkcolour.exdeorum.blockentity.BarrelBlockEntity;
|
||||||
import thedarkcolour.exdeorum.data.TranslationKeys;
|
import thedarkcolour.exdeorum.data.TranslationKeys;
|
||||||
|
|
@ -97,13 +94,21 @@ public class WateringCanItem extends Item {
|
||||||
|
|
||||||
public static ItemStack getFull(Supplier<? extends Item> wateringCan) {
|
public static ItemStack getFull(Supplier<? extends Item> wateringCan) {
|
||||||
var stack = new ItemStack(wateringCan.get());
|
var stack = new ItemStack(wateringCan.get());
|
||||||
stack.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).ifPresent(handler -> handler.fill(new FluidStack(Fluids.WATER, Integer.MAX_VALUE), IFluidHandler.FluidAction.EXECUTE));
|
var fluidHandler = stack.getCapability(Capabilities.FluidHandler.ITEM);
|
||||||
|
if (fluidHandler != null) {
|
||||||
|
fluidHandler.fill(new FluidStack(Fluids.WATER, Integer.MAX_VALUE), IFluidHandler.FluidAction.EXECUTE);
|
||||||
|
}
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isBarVisible(ItemStack stack) {
|
public boolean isBarVisible(ItemStack stack) {
|
||||||
return this.renewing ? stack.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).map(handler -> handler.getFluidInTank(0).getAmount() < this.capacity).orElse(true) : true;
|
if (this.renewing) {
|
||||||
|
var fluidHandler = stack.getCapability(Capabilities.FluidHandler.ITEM);
|
||||||
|
return fluidHandler == null || fluidHandler.getFluidInTank(0).getAmount() < this.capacity;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -113,9 +118,12 @@ public class WateringCanItem extends Item {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBarWidth(ItemStack stack) {
|
public int getBarWidth(ItemStack stack) {
|
||||||
return stack.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).map(fluidHandler -> {
|
var fluidHandler = stack.getCapability(Capabilities.FluidHandler.ITEM);
|
||||||
return Math.round((float) fluidHandler.getFluidInTank(0).getAmount() * 13.0F / (float) this.capacity);
|
if (fluidHandler != null) {
|
||||||
}).orElse(0);
|
return Math.round((float) fluidHandler.getFluidInTank(0).getAmount() * 13f / (float) this.capacity);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -130,16 +138,18 @@ public class WateringCanItem extends Item {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void appendHoverText(ItemStack stack, @Nullable Level pLevel, List<Component> tooltip, TooltipFlag pIsAdvanced) {
|
public void appendHoverText(ItemStack stack, @Nullable Level pLevel, List<Component> tooltip, TooltipFlag pIsAdvanced) {
|
||||||
stack.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).ifPresent(fluidHandler -> {
|
var fluidHandler = stack.getCapability(Capabilities.FluidHandler.ITEM);
|
||||||
|
if (fluidHandler != null) {
|
||||||
// use the block name which is guaranteed to have a vanilla translation
|
// use the block name which is guaranteed to have a vanilla translation
|
||||||
tooltip.add(Component.translatable("block.minecraft.water").append(Component.translatable(TranslationKeys.FRACTION_DISPLAY, fluidHandler.getFluidInTank(0).getAmount(), this.capacity)).withStyle(ChatFormatting.GRAY));
|
tooltip.add(Component.translatable("block.minecraft.water").append(Component.translatable(TranslationKeys.FRACTION_DISPLAY, fluidHandler.getFluidInTank(0).getAmount(), this.capacity)).withStyle(ChatFormatting.GRAY));
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) {
|
public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) {
|
||||||
var itemInHand = player.getItemInHand(hand);
|
var itemInHand = player.getItemInHand(hand);
|
||||||
return itemInHand.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).map(fluidHandler -> {
|
var fluidHandler = itemInHand.getCapability(Capabilities.FluidHandler.ITEM);
|
||||||
|
if (fluidHandler != null) {
|
||||||
if (fluidHandler.getFluidInTank(0).getAmount() < this.capacity) {
|
if (fluidHandler.getFluidInTank(0).getAmount() < this.capacity) {
|
||||||
var hitResult = getPlayerPOVHitResult(level, player, ClipContext.Fluid.SOURCE_ONLY);
|
var hitResult = getPlayerPOVHitResult(level, player, ClipContext.Fluid.SOURCE_ONLY);
|
||||||
|
|
||||||
|
|
@ -150,7 +160,7 @@ public class WateringCanItem extends Item {
|
||||||
if (state.getFluidState().getType() == Fluids.WATER && state.getBlock() instanceof BucketPickup pickup) {
|
if (state.getFluidState().getType() == Fluids.WATER && state.getBlock() instanceof BucketPickup pickup) {
|
||||||
if (!level.isClientSide) {
|
if (!level.isClientSide) {
|
||||||
fluidHandler.fill(new FluidStack(Fluids.WATER, 1000), IFluidHandler.FluidAction.EXECUTE);
|
fluidHandler.fill(new FluidStack(Fluids.WATER, 1000), IFluidHandler.FluidAction.EXECUTE);
|
||||||
pickup.pickupBlock(level, pos, state);
|
pickup.pickupBlock(player, level, pos, state);
|
||||||
pickup.getPickupSound(state).ifPresent(sound -> player.playSound(sound, 1.0F, 1.0F));
|
pickup.getPickupSound(state).ifPresent(sound -> player.playSound(sound, 1.0F, 1.0F));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,8 +180,8 @@ public class WateringCanItem extends Item {
|
||||||
|
|
||||||
return InteractionResultHolder.consume(itemInHand);
|
return InteractionResultHolder.consume(itemInHand);
|
||||||
}
|
}
|
||||||
return InteractionResultHolder.pass(itemInHand);
|
}
|
||||||
}).orElse(InteractionResultHolder.pass(itemInHand));
|
return InteractionResultHolder.pass(itemInHand);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -179,10 +189,11 @@ public class WateringCanItem extends Item {
|
||||||
var useTicks = 72000 - remainingTicks;
|
var useTicks = 72000 - remainingTicks;
|
||||||
|
|
||||||
if (useTicks >= STARTUP_TIME || living instanceof FakePlayer) {
|
if (useTicks >= STARTUP_TIME || living instanceof FakePlayer) {
|
||||||
stack.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).ifPresent(fluidHandler -> {
|
var fluidHandler = stack.getCapability(Capabilities.FluidHandler.ITEM);
|
||||||
|
if (fluidHandler != null) {
|
||||||
if (!fluidHandler.getFluidInTank(0).isEmpty()) {
|
if (!fluidHandler.getFluidInTank(0).isEmpty()) {
|
||||||
// do watering can
|
// do watering can
|
||||||
var reachDist = living instanceof Player player ? player.getBlockReach() : living.getAttributeValue(ForgeMod.BLOCK_REACH.get());
|
var reachDist = living instanceof Player player ? player.getBlockReach() : living.getAttributeValue(NeoForgeMod.BLOCK_REACH.value());
|
||||||
var hit = living.pick(reachDist, 0, true);
|
var hit = living.pick(reachDist, 0, true);
|
||||||
|
|
||||||
if (hit instanceof BlockHitResult blockHit && blockHit.getType() == HitResult.Type.BLOCK) {
|
if (hit instanceof BlockHitResult blockHit && blockHit.getType() == HitResult.Type.BLOCK) {
|
||||||
|
|
@ -195,7 +206,7 @@ public class WateringCanItem extends Item {
|
||||||
|
|
||||||
if (!this.renewing || fluidHandler.getFluidInTank(0).getAmount() != this.capacity) {
|
if (!this.renewing || fluidHandler.getFluidInTank(0).getAmount() != this.capacity) {
|
||||||
if (!(living instanceof Player player && player.getAbilities().instabuild)) {
|
if (!(living instanceof Player player && player.getAbilities().instabuild)) {
|
||||||
((CapabilityProvider) fluidHandler).drain();
|
((FluidHandler) fluidHandler).drain();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -215,7 +226,7 @@ public class WateringCanItem extends Item {
|
||||||
living.stopUsingItem();
|
living.stopUsingItem();
|
||||||
isWatering = false;
|
isWatering = false;
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -236,7 +247,7 @@ public class WateringCanItem extends Item {
|
||||||
} else if (state.getBlock() instanceof SugarCaneBlock block) {
|
} else if (state.getBlock() instanceof SugarCaneBlock block) {
|
||||||
var cursor = pos.mutable();
|
var cursor = pos.mutable();
|
||||||
while (level.isInWorldBounds(cursor.move(0, 1, 0)) && level.getBlockState(cursor).getBlock() == block) {
|
while (level.isInWorldBounds(cursor.move(0, 1, 0)) && level.getBlockState(cursor).getBlock() == block) {
|
||||||
// just keep looping
|
// just keep looping, cursor is moved up each check
|
||||||
}
|
}
|
||||||
// randomTick only works on the top sugarcane block
|
// randomTick only works on the top sugarcane block
|
||||||
var topState = level.getBlockState(cursor.move(0, -1, 0));
|
var topState = level.getBlockState(cursor.move(0, -1, 0));
|
||||||
|
|
@ -294,19 +305,22 @@ public class WateringCanItem extends Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundTag nbt) {
|
|
||||||
return new CapabilityProvider(stack, this.capacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initializeClient(Consumer<IClientItemExtensions> consumer) {
|
public void initializeClient(Consumer<IClientItemExtensions> consumer) {
|
||||||
consumer.accept(ClientExtensions.INSTANCE);
|
consumer.accept(ClientExtensions.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class CapabilityProvider extends FluidHandlerItemStack {
|
public static class FluidHandler extends FluidHandlerItemStack {
|
||||||
public CapabilityProvider(@NotNull ItemStack container, int capacity) {
|
public FluidHandler(ItemStack container) {
|
||||||
super(container, capacity);
|
super(container, determineCapacityFromItem(container.getItem()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int determineCapacityFromItem(Item item) {
|
||||||
|
if (item instanceof WateringCanItem wateringCan) {
|
||||||
|
return wateringCan.capacity;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Invalid watering can");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -18,21 +18,11 @@
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.item;
|
package thedarkcolour.exdeorum.item;
|
||||||
|
|
||||||
import net.minecraft.nbt.CompoundTag;
|
|
||||||
import net.minecraft.world.item.BucketItem;
|
import net.minecraft.world.item.BucketItem;
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraftforge.common.capabilities.ICapabilityProvider;
|
|
||||||
import net.minecraftforge.fluids.capability.wrappers.FluidBucketWrapper;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import thedarkcolour.exdeorum.registry.EFluids;
|
import thedarkcolour.exdeorum.registry.EFluids;
|
||||||
|
|
||||||
public class WitchWaterBucketItem extends BucketItem {
|
public class WitchWaterBucketItem extends BucketItem {
|
||||||
public WitchWaterBucketItem(Properties properties) {
|
public WitchWaterBucketItem(Properties properties) {
|
||||||
super(EFluids.WITCH_WATER, properties);
|
super(EFluids.WITCH_WATER, properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundTag nbt) {
|
|
||||||
return new FluidBucketWrapper(stack);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,8 @@ import net.minecraft.world.level.storage.loot.LootContext;
|
||||||
import net.minecraft.world.level.storage.loot.LootParams;
|
import net.minecraft.world.level.storage.loot.LootParams;
|
||||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
||||||
import net.minecraftforge.common.loot.IGlobalLootModifier;
|
import net.neoforged.neoforge.common.loot.IGlobalLootModifier;
|
||||||
import net.minecraftforge.common.loot.LootModifier;
|
import net.neoforged.neoforge.common.loot.LootModifier;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
||||||
import thedarkcolour.exdeorum.recipe.crook.CrookRecipe;
|
import thedarkcolour.exdeorum.recipe.crook.CrookRecipe;
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,8 @@ import net.minecraft.world.item.enchantment.Enchantments;
|
||||||
import net.minecraft.world.level.storage.loot.LootContext;
|
import net.minecraft.world.level.storage.loot.LootContext;
|
||||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
||||||
import net.minecraftforge.common.loot.IGlobalLootModifier;
|
import net.neoforged.neoforge.common.loot.IGlobalLootModifier;
|
||||||
import net.minecraftforge.common.loot.LootModifier;
|
import net.neoforged.neoforge.common.loot.LootModifier;
|
||||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,8 @@
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.loot;
|
package thedarkcolour.exdeorum.loot;
|
||||||
|
|
||||||
import com.google.gson.JsonDeserializationContext;
|
import com.mojang.serialization.Codec;
|
||||||
import com.google.gson.JsonObject;
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.storage.loot.LootContext;
|
import net.minecraft.world.level.storage.loot.LootContext;
|
||||||
|
|
@ -29,8 +29,12 @@ import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
||||||
import thedarkcolour.exdeorum.registry.ELootFunctions;
|
import thedarkcolour.exdeorum.registry.ELootFunctions;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class MachineLootFunction extends LootItemConditionalFunction {
|
public class MachineLootFunction extends LootItemConditionalFunction {
|
||||||
protected MachineLootFunction(LootItemCondition[] conditions) {
|
public static final Codec<MachineLootFunction> CODEC = RecordCodecBuilder.create(instance -> commonFields(instance).apply(instance, MachineLootFunction::new));
|
||||||
|
|
||||||
|
protected MachineLootFunction(List<LootItemCondition> conditions) {
|
||||||
super(conditions);
|
super(conditions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,11 +56,4 @@ public class MachineLootFunction extends LootItemConditionalFunction {
|
||||||
public static LootItemConditionalFunction.Builder<?> machineLoot() {
|
public static LootItemConditionalFunction.Builder<?> machineLoot() {
|
||||||
return LootItemConditionalFunction.simpleBuilder(MachineLootFunction::new);
|
return LootItemConditionalFunction.simpleBuilder(MachineLootFunction::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class LootSerializer extends LootItemConditionalFunction.Serializer<MachineLootFunction> {
|
|
||||||
@Override
|
|
||||||
public MachineLootFunction deserialize(JsonObject json, JsonDeserializationContext ctx, LootItemCondition[] conditions) {
|
|
||||||
return new MachineLootFunction(conditions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,17 +18,19 @@
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.loot;
|
package thedarkcolour.exdeorum.loot;
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
import com.mojang.serialization.Codec;
|
||||||
import com.google.gson.JsonDeserializationContext;
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonSerializationContext;
|
|
||||||
import net.minecraft.util.GsonHelper;
|
|
||||||
import net.minecraft.world.level.storage.loot.LootContext;
|
import net.minecraft.world.level.storage.loot.LootContext;
|
||||||
import net.minecraft.world.level.storage.loot.providers.number.LootNumberProviderType;
|
import net.minecraft.world.level.storage.loot.providers.number.LootNumberProviderType;
|
||||||
import net.minecraft.world.level.storage.loot.providers.number.NumberProvider;
|
import net.minecraft.world.level.storage.loot.providers.number.NumberProvider;
|
||||||
|
import net.minecraft.world.level.storage.loot.providers.number.NumberProviders;
|
||||||
import thedarkcolour.exdeorum.registry.ENumberProviders;
|
import thedarkcolour.exdeorum.registry.ENumberProviders;
|
||||||
|
|
||||||
public record SummationGenerator(NumberProvider[] providers) implements NumberProvider {
|
import java.util.List;
|
||||||
|
|
||||||
|
public record SummationGenerator(List<NumberProvider> providers) implements NumberProvider {
|
||||||
|
public static final Codec<SummationGenerator> CODEC = RecordCodecBuilder.create(instance -> instance.group(NumberProviders.CODEC.listOf().fieldOf("values").forGetter(SummationGenerator::providers)).apply(instance, SummationGenerator::new));
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getFloat(LootContext context) {
|
public float getFloat(LootContext context) {
|
||||||
float sum = 0f;
|
float sum = 0f;
|
||||||
|
|
@ -42,26 +44,4 @@ public record SummationGenerator(NumberProvider[] providers) implements NumberPr
|
||||||
public LootNumberProviderType getType() {
|
public LootNumberProviderType getType() {
|
||||||
return ENumberProviders.SUMMATION.get();
|
return ENumberProviders.SUMMATION.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Serializer implements net.minecraft.world.level.storage.loot.Serializer<SummationGenerator> {
|
|
||||||
@Override
|
|
||||||
public void serialize(JsonObject json, SummationGenerator value, JsonSerializationContext ctx) {
|
|
||||||
JsonArray array = new JsonArray();
|
|
||||||
for (var provider : value.providers) {
|
|
||||||
array.add(ctx.serialize(provider, NumberProvider.class));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SummationGenerator deserialize(JsonObject json, JsonDeserializationContext ctx) {
|
|
||||||
var valuesJson = GsonHelper.getAsJsonArray(json, "values");
|
|
||||||
NumberProvider[] providers = new NumberProvider[valuesJson.size()];
|
|
||||||
int i = 0;
|
|
||||||
for (var valueJson : valuesJson) {
|
|
||||||
providers[i++] = ctx.deserialize(valueJson, NumberProvider.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new SummationGenerator(providers);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,8 @@ import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.SoundType;
|
import net.minecraft.world.level.block.SoundType;
|
||||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||||
import net.minecraftforge.registries.RegistryObject;
|
import net.neoforged.neoforge.registries.DeferredBlock;
|
||||||
|
import net.neoforged.neoforge.registries.DeferredItem;
|
||||||
|
|
||||||
public abstract class AbstractMaterial {
|
public abstract class AbstractMaterial {
|
||||||
// The sound this block makes (a string corresponding to a field in SoundType or a JSON object with the five sound events used to create a sound type)
|
// The sound this block makes (a string corresponding to a field in SoundType or a JSON object with the five sound events used to create a sound type)
|
||||||
|
|
@ -37,8 +38,8 @@ public abstract class AbstractMaterial {
|
||||||
// ID of mod that should be present
|
// ID of mod that should be present
|
||||||
public final String requiredModId;
|
public final String requiredModId;
|
||||||
|
|
||||||
RegistryObject<Block> block;
|
DeferredBlock<Block> block;
|
||||||
RegistryObject<BlockItem> item;
|
DeferredItem<BlockItem> item;
|
||||||
|
|
||||||
protected AbstractMaterial(SoundType soundType, float strength, boolean needsCorrectTool, int mapColor, String requiredModId) {
|
protected AbstractMaterial(SoundType soundType, float strength, boolean needsCorrectTool, int mapColor, String requiredModId) {
|
||||||
this.soundType = soundType;
|
this.soundType = soundType;
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ import com.google.gson.JsonPrimitive;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.level.block.SoundType;
|
import net.minecraft.world.level.block.SoundType;
|
||||||
import net.minecraftforge.common.util.ForgeSoundType;
|
import net.neoforged.neoforge.common.util.DeferredSoundType;
|
||||||
import net.minecraftforge.registries.RegistryObject;
|
import net.neoforged.neoforge.registries.DeferredHolder;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import thedarkcolour.exdeorum.ExDeorum;
|
import thedarkcolour.exdeorum.ExDeorum;
|
||||||
|
|
||||||
|
|
@ -49,7 +49,7 @@ public class MaterialParser {
|
||||||
|
|
||||||
if (soundTypeJson.isJsonPrimitive()) {
|
if (soundTypeJson.isJsonPrimitive()) {
|
||||||
String soundTypeString = soundTypeJson.getAsString();
|
String soundTypeString = soundTypeJson.getAsString();
|
||||||
var soundType = SoundTypeResolver.VANILLA_SOUND_TYPES.get(soundTypeString);
|
var soundType = SoundTypeResolver.resolve(soundTypeString);
|
||||||
|
|
||||||
if (soundType == null) {
|
if (soundType == null) {
|
||||||
ExDeorum.LOGGER.error("Unknown sound type \"{}\" for material {}", soundTypeString, this.jsonPath);
|
ExDeorum.LOGGER.error("Unknown sound type \"{}\" for material {}", soundTypeString, this.jsonPath);
|
||||||
|
|
@ -59,12 +59,12 @@ public class MaterialParser {
|
||||||
}
|
}
|
||||||
} else if (soundTypeJson instanceof JsonObject soundTypeObj) {
|
} else if (soundTypeJson instanceof JsonObject soundTypeObj) {
|
||||||
if (soundTypeObj.has("break_sound") && soundTypeObj.has("step_sound") && soundTypeObj.has("place_sound") && soundTypeObj.has("hit_sound") && soundTypeObj.has("fall_sound")) {
|
if (soundTypeObj.has("break_sound") && soundTypeObj.has("step_sound") && soundTypeObj.has("place_sound") && soundTypeObj.has("hit_sound") && soundTypeObj.has("fall_sound")) {
|
||||||
return new ForgeSoundType(1.0f, 1.0f,
|
return new DeferredSoundType(1.0f, 1.0f,
|
||||||
RegistryObject.create(new ResourceLocation(soundTypeObj.get("break_sound").getAsString()), Registries.SOUND_EVENT, ExDeorum.ID),
|
DeferredHolder.create(Registries.SOUND_EVENT, new ResourceLocation(soundTypeObj.get("break_sound").getAsString())),
|
||||||
RegistryObject.create(new ResourceLocation(soundTypeObj.get("step_sound").getAsString()), Registries.SOUND_EVENT, ExDeorum.ID),
|
DeferredHolder.create(Registries.SOUND_EVENT, new ResourceLocation(soundTypeObj.get("step_sound").getAsString())),
|
||||||
RegistryObject.create(new ResourceLocation(soundTypeObj.get("place_sound").getAsString()), Registries.SOUND_EVENT, ExDeorum.ID),
|
DeferredHolder.create(Registries.SOUND_EVENT, new ResourceLocation(soundTypeObj.get("place_sound").getAsString())),
|
||||||
RegistryObject.create(new ResourceLocation(soundTypeObj.get("hit_sound").getAsString()), Registries.SOUND_EVENT, ExDeorum.ID),
|
DeferredHolder.create(Registries.SOUND_EVENT, new ResourceLocation(soundTypeObj.get("hit_sound").getAsString())),
|
||||||
RegistryObject.create(new ResourceLocation(soundTypeObj.get("fall_sound").getAsString()), Registries.SOUND_EVENT, ExDeorum.ID)
|
DeferredHolder.create(Registries.SOUND_EVENT, new ResourceLocation(soundTypeObj.get("fall_sound").getAsString()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ import com.google.gson.JsonParser;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
import net.minecraftforge.data.loading.DatagenModLoader;
|
import net.neoforged.neoforge.data.loading.DatagenModLoader;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import thedarkcolour.exdeorum.ExDeorum;
|
import thedarkcolour.exdeorum.ExDeorum;
|
||||||
import thedarkcolour.exdeorum.client.CompostColors;
|
import thedarkcolour.exdeorum.client.CompostColors;
|
||||||
|
|
|
||||||
|
|
@ -18,126 +18,24 @@
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.material;
|
package thedarkcolour.exdeorum.material;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
import net.minecraft.world.level.block.SoundType;
|
import net.minecraft.world.level.block.SoundType;
|
||||||
import net.minecraftforge.fml.loading.FMLLoader;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import thedarkcolour.exdeorum.ExDeorum;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.HashMap;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
class SoundTypeResolver {
|
class SoundTypeResolver {
|
||||||
static final Map<String, SoundType> VANILLA_SOUND_TYPES;
|
private static final HashMap<String, SoundType> VANILLA_SOUND_TYPES = new HashMap<>();
|
||||||
|
|
||||||
static {
|
@Nullable
|
||||||
if (ExDeorum.DEBUG && !FMLLoader.versionInfo().mcVersion().equals("1.20.1")) {
|
static SoundType resolve(String name) {
|
||||||
throw new RuntimeException("Update the BarrelMaterial map");
|
return VANILLA_SOUND_TYPES.computeIfAbsent(name.toUpperCase(Locale.ROOT), (fieldName) -> {
|
||||||
}
|
try {
|
||||||
// Very long line of put calls that put each SoundType field and its lowercase name into the map
|
var field = SoundType.class.getDeclaredField(fieldName);
|
||||||
ImmutableMap.Builder<String, SoundType> temp = ImmutableMap.builder();
|
return (SoundType) field.get(null);
|
||||||
temp.put("empty", SoundType.EMPTY);
|
} catch (NoSuchFieldException | IllegalAccessException ignored) {
|
||||||
temp.put("wood", SoundType.WOOD);
|
return null;
|
||||||
temp.put("gravel", SoundType.GRAVEL);
|
}
|
||||||
temp.put("grass", SoundType.GRASS);
|
});
|
||||||
temp.put("lily_pad", SoundType.LILY_PAD);
|
|
||||||
temp.put("stone", SoundType.STONE);
|
|
||||||
temp.put("metal", SoundType.METAL);
|
|
||||||
temp.put("glass", SoundType.GLASS);
|
|
||||||
temp.put("wool", SoundType.WOOL);
|
|
||||||
temp.put("sand", SoundType.SAND);
|
|
||||||
temp.put("snow", SoundType.SNOW);
|
|
||||||
temp.put("powder_snow", SoundType.POWDER_SNOW);
|
|
||||||
temp.put("ladder", SoundType.LADDER);
|
|
||||||
temp.put("anvil", SoundType.ANVIL);
|
|
||||||
temp.put("slime_block", SoundType.SLIME_BLOCK);
|
|
||||||
temp.put("honey_block", SoundType.HONEY_BLOCK);
|
|
||||||
temp.put("wet_grass", SoundType.WET_GRASS);
|
|
||||||
temp.put("coral_block", SoundType.CORAL_BLOCK);
|
|
||||||
temp.put("bamboo", SoundType.BAMBOO);
|
|
||||||
temp.put("bamboo_sapling", SoundType.BAMBOO_SAPLING);
|
|
||||||
temp.put("scaffolding", SoundType.SCAFFOLDING);
|
|
||||||
temp.put("sweet_berry_bush", SoundType.SWEET_BERRY_BUSH);
|
|
||||||
temp.put("crop", SoundType.CROP);
|
|
||||||
temp.put("hard_crop", SoundType.HARD_CROP);
|
|
||||||
temp.put("vine", SoundType.VINE);
|
|
||||||
temp.put("nether_wart", SoundType.NETHER_WART);
|
|
||||||
temp.put("lantern", SoundType.LANTERN);
|
|
||||||
temp.put("stem", SoundType.STEM);
|
|
||||||
temp.put("nylium", SoundType.NYLIUM);
|
|
||||||
temp.put("fungus", SoundType.FUNGUS);
|
|
||||||
temp.put("roots", SoundType.ROOTS);
|
|
||||||
temp.put("shroomlight", SoundType.SHROOMLIGHT);
|
|
||||||
temp.put("weeping_vines", SoundType.WEEPING_VINES);
|
|
||||||
temp.put("twisting_vines", SoundType.TWISTING_VINES);
|
|
||||||
temp.put("soul_sand", SoundType.SOUL_SAND);
|
|
||||||
temp.put("soul_soil", SoundType.SOUL_SOIL);
|
|
||||||
temp.put("basalt", SoundType.BASALT);
|
|
||||||
temp.put("wart_block", SoundType.WART_BLOCK);
|
|
||||||
temp.put("netherrack", SoundType.NETHERRACK);
|
|
||||||
temp.put("nether_bricks", SoundType.NETHER_BRICKS);
|
|
||||||
temp.put("nether_sprouts", SoundType.NETHER_SPROUTS);
|
|
||||||
temp.put("nether_ore", SoundType.NETHER_ORE);
|
|
||||||
temp.put("bone_block", SoundType.BONE_BLOCK);
|
|
||||||
temp.put("netherite_block", SoundType.NETHERITE_BLOCK);
|
|
||||||
temp.put("ancient_debris", SoundType.ANCIENT_DEBRIS);
|
|
||||||
temp.put("lodestone", SoundType.LODESTONE);
|
|
||||||
temp.put("chain", SoundType.CHAIN);
|
|
||||||
temp.put("nether_gold_ore", SoundType.NETHER_GOLD_ORE);
|
|
||||||
temp.put("gilded_blackstone", SoundType.GILDED_BLACKSTONE);
|
|
||||||
temp.put("candle", SoundType.CANDLE);
|
|
||||||
temp.put("amethyst", SoundType.AMETHYST);
|
|
||||||
temp.put("amethyst_cluster", SoundType.AMETHYST_CLUSTER);
|
|
||||||
temp.put("small_amethyst_bud", SoundType.SMALL_AMETHYST_BUD);
|
|
||||||
temp.put("medium_amethyst_bud", SoundType.MEDIUM_AMETHYST_BUD);
|
|
||||||
temp.put("large_amethyst_bud", SoundType.LARGE_AMETHYST_BUD);
|
|
||||||
temp.put("tuff", SoundType.TUFF);
|
|
||||||
temp.put("calcite", SoundType.CALCITE);
|
|
||||||
temp.put("dripstone_block", SoundType.DRIPSTONE_BLOCK);
|
|
||||||
temp.put("pointed_dripstone", SoundType.POINTED_DRIPSTONE);
|
|
||||||
temp.put("copper", SoundType.COPPER);
|
|
||||||
temp.put("cave_vines", SoundType.CAVE_VINES);
|
|
||||||
temp.put("spore_blossom", SoundType.SPORE_BLOSSOM);
|
|
||||||
temp.put("azalea", SoundType.AZALEA);
|
|
||||||
temp.put("flowering_azalea", SoundType.FLOWERING_AZALEA);
|
|
||||||
temp.put("moss_carpet", SoundType.MOSS_CARPET);
|
|
||||||
temp.put("pink_petals", SoundType.PINK_PETALS);
|
|
||||||
temp.put("moss", SoundType.MOSS);
|
|
||||||
temp.put("big_dripleaf", SoundType.BIG_DRIPLEAF);
|
|
||||||
temp.put("small_dripleaf", SoundType.SMALL_DRIPLEAF);
|
|
||||||
temp.put("rooted_dirt", SoundType.ROOTED_DIRT);
|
|
||||||
temp.put("hanging_roots", SoundType.HANGING_ROOTS);
|
|
||||||
temp.put("azalea_leaves", SoundType.AZALEA_LEAVES);
|
|
||||||
temp.put("sculk_sensor", SoundType.SCULK_SENSOR);
|
|
||||||
temp.put("sculk_catalyst", SoundType.SCULK_CATALYST);
|
|
||||||
temp.put("sculk", SoundType.SCULK);
|
|
||||||
temp.put("sculk_vein", SoundType.SCULK_VEIN);
|
|
||||||
temp.put("sculk_shrieker", SoundType.SCULK_SHRIEKER);
|
|
||||||
temp.put("glow_lichen", SoundType.GLOW_LICHEN);
|
|
||||||
temp.put("deepslate", SoundType.DEEPSLATE);
|
|
||||||
temp.put("deepslate_bricks", SoundType.DEEPSLATE_BRICKS);
|
|
||||||
temp.put("deepslate_tiles", SoundType.DEEPSLATE_TILES);
|
|
||||||
temp.put("polished_deepslate", SoundType.POLISHED_DEEPSLATE);
|
|
||||||
temp.put("froglight", SoundType.FROGLIGHT);
|
|
||||||
temp.put("frogspawn", SoundType.FROGSPAWN);
|
|
||||||
temp.put("mangrove_roots", SoundType.MANGROVE_ROOTS);
|
|
||||||
temp.put("muddy_mangrove_roots", SoundType.MUDDY_MANGROVE_ROOTS);
|
|
||||||
temp.put("mud", SoundType.MUD);
|
|
||||||
temp.put("mud_bricks", SoundType.MUD_BRICKS);
|
|
||||||
temp.put("packed_mud", SoundType.PACKED_MUD);
|
|
||||||
temp.put("hanging_sign", SoundType.HANGING_SIGN);
|
|
||||||
temp.put("nether_wood_hanging_sign", SoundType.NETHER_WOOD_HANGING_SIGN);
|
|
||||||
temp.put("bamboo_wood_hanging_sign", SoundType.BAMBOO_WOOD_HANGING_SIGN);
|
|
||||||
temp.put("bamboo_wood", SoundType.BAMBOO_WOOD);
|
|
||||||
temp.put("nether_wood", SoundType.NETHER_WOOD);
|
|
||||||
temp.put("cherry_wood", SoundType.CHERRY_WOOD);
|
|
||||||
temp.put("cherry_sapling", SoundType.CHERRY_SAPLING);
|
|
||||||
temp.put("cherry_leaves", SoundType.CHERRY_LEAVES);
|
|
||||||
temp.put("cherry_wood_hanging_sign", SoundType.CHERRY_WOOD_HANGING_SIGN);
|
|
||||||
temp.put("chiseled_bookshelf", SoundType.CHISELED_BOOKSHELF);
|
|
||||||
temp.put("suspicious_sand", SoundType.SUSPICIOUS_SAND);
|
|
||||||
temp.put("suspicious_gravel", SoundType.SUSPICIOUS_GRAVEL);
|
|
||||||
temp.put("decorated_pot", SoundType.DECORATED_POT);
|
|
||||||
temp.put("decorated_pot_cracked", SoundType.DECORATED_POT_CRACKED);
|
|
||||||
|
|
||||||
VANILLA_SOUND_TYPES = temp.build();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.blockentity;
|
package thedarkcolour.exdeorum.menu;
|
||||||
|
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
@ -26,7 +26,7 @@ import net.minecraft.world.inventory.DataSlot;
|
||||||
import net.minecraft.world.inventory.InventoryMenu;
|
import net.minecraft.world.inventory.InventoryMenu;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import thedarkcolour.exdeorum.ExDeorum;
|
import thedarkcolour.exdeorum.ExDeorum;
|
||||||
import thedarkcolour.exdeorum.menu.AbstractMachineMenu;
|
import thedarkcolour.exdeorum.blockentity.MechanicalHammerBlockEntity;
|
||||||
import thedarkcolour.exdeorum.registry.EMenus;
|
import thedarkcolour.exdeorum.registry.EMenus;
|
||||||
import thedarkcolour.exdeorum.tag.EItemTags;
|
import thedarkcolour.exdeorum.tag.EItemTags;
|
||||||
|
|
||||||
|
|
@ -43,7 +43,7 @@ public class ClientMessageHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("DataFlowIssue")
|
@SuppressWarnings("DataFlowIssue")
|
||||||
public static void handleVisualUpdate(VisualUpdateMessage msg) {
|
static void handleVisualUpdate(VisualUpdateMessage msg) {
|
||||||
ClientLevel level = Minecraft.getInstance().level;
|
ClientLevel level = Minecraft.getInstance().level;
|
||||||
if (level != null && level.getBlockEntity(msg.pos) instanceof EBlockEntity blockEntity) {
|
if (level != null && level.getBlockEntity(msg.pos) instanceof EBlockEntity blockEntity) {
|
||||||
// payload should be nonnull on the client side
|
// payload should be nonnull on the client side
|
||||||
|
|
|
||||||
|
|
@ -19,27 +19,27 @@
|
||||||
package thedarkcolour.exdeorum.network;
|
package thedarkcolour.exdeorum.network;
|
||||||
|
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||||
import net.minecraftforge.fml.DistExecutor;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraftforge.network.NetworkEvent;
|
import thedarkcolour.exdeorum.ExDeorum;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
// Like ClientboundContainerSetDataPacket except that the value is 32 bits instead of 16 bits
|
// Like ClientboundContainerSetDataPacket except that the value is 32 bits instead of 16 bits
|
||||||
public record MenuPropertyMessage(int containerId, int index, int value) {
|
public record MenuPropertyMessage(int containerId, int index, int value) implements CustomPacketPayload {
|
||||||
public static void encode(MenuPropertyMessage msg, FriendlyByteBuf buffer) {
|
public static final ResourceLocation ID = new ResourceLocation(ExDeorum.ID, "menu_property");
|
||||||
buffer.writeByte(msg.containerId);
|
|
||||||
buffer.writeShort(msg.index);
|
@Override
|
||||||
buffer.writeVarInt(msg.value);
|
public void write(FriendlyByteBuf buffer) {
|
||||||
|
buffer.writeByte(this.containerId);
|
||||||
|
buffer.writeShort(this.index);
|
||||||
|
buffer.writeVarInt(this.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResourceLocation id() {
|
||||||
|
return ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MenuPropertyMessage decode(FriendlyByteBuf buffer) {
|
public static MenuPropertyMessage decode(FriendlyByteBuf buffer) {
|
||||||
return new MenuPropertyMessage(buffer.readByte(), buffer.readShort(), buffer.readVarInt());
|
return new MenuPropertyMessage(buffer.readByte(), buffer.readShort(), buffer.readVarInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void handle(MenuPropertyMessage msg, Supplier<NetworkEvent.Context> ctxSupplier) {
|
|
||||||
NetworkHandler.handle(ctxSupplier, ctx -> {
|
|
||||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ClientMessageHandler.handleMenuProperty(msg));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,43 +18,36 @@
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.network;
|
package thedarkcolour.exdeorum.network;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraftforge.network.NetworkDirection;
|
import net.neoforged.neoforge.network.PacketDistributor;
|
||||||
import net.minecraftforge.network.NetworkEvent;
|
import net.neoforged.neoforge.network.registration.IPayloadRegistrar;
|
||||||
import net.minecraftforge.network.NetworkRegistry;
|
|
||||||
import net.minecraftforge.network.simple.SimpleChannel;
|
|
||||||
import thedarkcolour.exdeorum.ExDeorum;
|
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
public final class NetworkHandler {
|
public final class NetworkHandler {
|
||||||
public static final String PROTOCOL_VERSION = "1";
|
public static void register(IPayloadRegistrar registrar) {
|
||||||
public static final SimpleChannel CHANNEL = NetworkRegistry.newSimpleChannel(new ResourceLocation(ExDeorum.ID, "channel"), () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals, PROTOCOL_VERSION::equals);
|
registrar.play(MenuPropertyMessage.ID, MenuPropertyMessage::decode, sidedHandler -> {
|
||||||
|
sidedHandler.client((msg, ctx) -> ClientMessageHandler.handleMenuProperty(msg));
|
||||||
public static void register() {
|
});
|
||||||
CHANNEL.registerMessage(0, VoidWorldMessage.class, VoidWorldMessage::encode, VoidWorldMessage::decode, VoidWorldMessage::handle);
|
registrar.play(VisualUpdateMessage.ID, VisualUpdateMessage::decode, sidedHandler -> {
|
||||||
CHANNEL.registerMessage(1, PlayerDataMessage.class, (msg, buffer) -> {}, buffer -> new PlayerDataMessage(), PlayerDataMessage::handle);
|
sidedHandler.client((msg, ctx) -> ClientMessageHandler.handleVisualUpdate(msg));
|
||||||
CHANNEL.registerMessage(2, VisualUpdateMessage.class, VisualUpdateMessage::encode, VisualUpdateMessage::decode, VisualUpdateMessage::handle);
|
});
|
||||||
CHANNEL.registerMessage(3, MenuPropertyMessage.class, MenuPropertyMessage::encode, MenuPropertyMessage::decode, MenuPropertyMessage::handle);
|
// not sure if these stop working if they're in the wrong phase, so I'll put them in both
|
||||||
|
registrar.common(VoidWorldMessage.ID, buffer -> VoidWorldMessage.INSTANCE, sidedHandler -> {
|
||||||
|
sidedHandler.client((msg, ctx) -> ClientMessageHandler.disableVoidFogRendering());
|
||||||
|
});
|
||||||
|
registrar.common(RecipeCacheResetMessage.ID, buffer -> RecipeCacheResetMessage.INSTANCE, sidedHandler -> {
|
||||||
|
sidedHandler.client((msg, ctx) -> ClientMessageHandler.reloadClientRecipeCache());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendVoidWorld(ServerPlayer pPlayer) {
|
public static void sendVoidWorld(ServerPlayer player) {
|
||||||
CHANNEL.sendTo(new VoidWorldMessage(), pPlayer.connection.connection, NetworkDirection.PLAY_TO_CLIENT);
|
PacketDistributor.PLAYER.with(player).send(VoidWorldMessage.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendRecipeCacheReset(ServerPlayer player) {
|
public static void sendRecipeCacheReset(ServerPlayer player) {
|
||||||
CHANNEL.sendTo(new PlayerDataMessage(), player.connection.connection, NetworkDirection.PLAY_TO_CLIENT);
|
PacketDistributor.PLAYER.with(player).send(RecipeCacheResetMessage.INSTANCE);
|
||||||
}
|
|
||||||
|
|
||||||
static void handle(Supplier<NetworkEvent.Context> ctxSupplier, Consumer<NetworkEvent.Context> handler) {
|
|
||||||
var ctx = ctxSupplier.get();
|
|
||||||
ctx.enqueueWork(() -> handler.accept(ctx));
|
|
||||||
ctx.setPacketHandled(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendMenuProperty(ServerPlayer player, int containerId, int index, int prevSieveEnergy) {
|
public static void sendMenuProperty(ServerPlayer player, int containerId, int index, int prevSieveEnergy) {
|
||||||
CHANNEL.sendTo(new MenuPropertyMessage(containerId, index, prevSieveEnergy), player.connection.connection, NetworkDirection.PLAY_TO_CLIENT);
|
PacketDistributor.PLAYER.with(player).send(new MenuPropertyMessage(containerId, index, prevSieveEnergy));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,19 +18,25 @@
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.network;
|
package thedarkcolour.exdeorum.network;
|
||||||
|
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraftforge.fml.DistExecutor;
|
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||||
import net.minecraftforge.network.NetworkEvent;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import thedarkcolour.exdeorum.ExDeorum;
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
// Server -> Client
|
// Server -> Client
|
||||||
// Fired whenever a player joins an LAN world or dedicated server to load the recipe caches
|
// Fired whenever a player joins an LAN world or dedicated server to load the recipe caches
|
||||||
// Also fired whenever those servers reload data
|
// Also fired whenever those servers reload data
|
||||||
public class PlayerDataMessage {
|
public enum RecipeCacheResetMessage implements CustomPacketPayload {
|
||||||
public void handle(Supplier<NetworkEvent.Context> ctxSupplier) {
|
INSTANCE;
|
||||||
NetworkHandler.handle(ctxSupplier, ctx -> {
|
|
||||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> ClientMessageHandler::reloadClientRecipeCache);
|
public static final ResourceLocation ID = new ResourceLocation(ExDeorum.ID, "recipe_cache_reset");
|
||||||
});
|
|
||||||
|
@Override
|
||||||
|
public void write(FriendlyByteBuf pBuffer) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResourceLocation id() {
|
||||||
|
return ID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -21,16 +21,17 @@ package thedarkcolour.exdeorum.network;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
|
||||||
import net.minecraftforge.fml.DistExecutor;
|
|
||||||
import net.minecraftforge.network.NetworkEvent;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import thedarkcolour.exdeorum.ExDeorum;
|
||||||
import thedarkcolour.exdeorum.blockentity.EBlockEntity;
|
import thedarkcolour.exdeorum.blockentity.EBlockEntity;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
// todo change this into two classes instead of having nullable fields
|
||||||
|
class VisualUpdateMessage implements CustomPacketPayload {
|
||||||
|
public static final ResourceLocation ID = new ResourceLocation(ExDeorum.ID, "visual_update");
|
||||||
|
|
||||||
class VisualUpdateMessage {
|
|
||||||
final BlockEntityType<?> blockEntityType;
|
final BlockEntityType<?> blockEntityType;
|
||||||
final BlockPos pos;
|
final BlockPos pos;
|
||||||
// Null on the client side
|
// Null on the client side
|
||||||
|
|
@ -40,6 +41,7 @@ class VisualUpdateMessage {
|
||||||
@Nullable
|
@Nullable
|
||||||
final FriendlyByteBuf payload;
|
final FriendlyByteBuf payload;
|
||||||
|
|
||||||
|
@SuppressWarnings("DataFlowIssue")
|
||||||
public VisualUpdateMessage(BlockPos pos, @Nullable EBlockEntity blockEntity, @Nullable FriendlyByteBuf payload) {
|
public VisualUpdateMessage(BlockPos pos, @Nullable EBlockEntity blockEntity, @Nullable FriendlyByteBuf payload) {
|
||||||
this.pos = pos;
|
this.pos = pos;
|
||||||
this.blockEntity = blockEntity;
|
this.blockEntity = blockEntity;
|
||||||
|
|
@ -54,20 +56,21 @@ class VisualUpdateMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void encode(VisualUpdateMessage msg, FriendlyByteBuf buffer) {
|
@SuppressWarnings("DataFlowIssue")
|
||||||
buffer.writeBlockPos(msg.pos);
|
@Override
|
||||||
buffer.writeId(BuiltInRegistries.BLOCK_ENTITY_TYPE, msg.blockEntityType);
|
public void write(FriendlyByteBuf buffer) {
|
||||||
|
buffer.writeBlockPos(this.pos);
|
||||||
|
buffer.writeId(BuiltInRegistries.BLOCK_ENTITY_TYPE, this.blockEntityType);
|
||||||
// never null on the server side, where this packet is meant to be encoded
|
// never null on the server side, where this packet is meant to be encoded
|
||||||
msg.blockEntity.writeVisualData(buffer);
|
this.blockEntity.writeVisualData(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResourceLocation id() {
|
||||||
|
return ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static VisualUpdateMessage decode(FriendlyByteBuf buffer) {
|
public static VisualUpdateMessage decode(FriendlyByteBuf buffer) {
|
||||||
return new VisualUpdateMessage(buffer.readBlockPos(), null, buffer);
|
return new VisualUpdateMessage(buffer.readBlockPos(), null, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void handle(VisualUpdateMessage msg, Supplier<NetworkEvent.Context> ctxSupplier) {
|
|
||||||
NetworkHandler.handle(ctxSupplier, ctx -> {
|
|
||||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ClientMessageHandler.handleVisualUpdate(msg));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,16 +20,19 @@ package thedarkcolour.exdeorum.network;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
import net.minecraftforge.network.PacketDistributor;
|
import net.neoforged.neoforge.network.PacketDistributor;
|
||||||
import thedarkcolour.exdeorum.blockentity.EBlockEntity;
|
import thedarkcolour.exdeorum.blockentity.EBlockEntity;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
// Syncs certain block entity data to the client for visual purposes
|
// Syncs certain block entity data to the client for visual purposes
|
||||||
// Since some block entities might change their data multiple times a tick, this class keeps track of
|
// Since some block entities might change their data multiple times a tick, this class keeps track of
|
||||||
// whether a block entity has updated and then pushes out the changes once at the end of each tick.
|
// whether a block entity has updated and then pushes out the changes once at the end of each tick.
|
||||||
public class VisualUpdateTracker {
|
public class VisualUpdateTracker {
|
||||||
// WeakHashMap is faster than Guava mapmaker
|
// WeakHashMap is faster than Guava mapmaker because it isn't thread safe
|
||||||
// Use sets to avoid duplicate updates
|
// Use sets to avoid duplicate updates
|
||||||
private static final Map<LevelChunk, Set<BlockPos>> UPDATES = new WeakHashMap<>();
|
private static final Map<LevelChunk, Set<BlockPos>> UPDATES = new WeakHashMap<>();
|
||||||
|
|
||||||
|
|
@ -57,7 +60,7 @@ public class VisualUpdateTracker {
|
||||||
|
|
||||||
if (chunk.getBlockEntity(updatePos) instanceof EBlockEntity blockEntity) {
|
if (chunk.getBlockEntity(updatePos) instanceof EBlockEntity blockEntity) {
|
||||||
// packet uses strong reference
|
// packet uses strong reference
|
||||||
NetworkHandler.CHANNEL.send(PacketDistributor.TRACKING_CHUNK.with(entry::getKey), new VisualUpdateMessage(updatePos, blockEntity, null));
|
PacketDistributor.TRACKING_CHUNK.with(chunk).send(new VisualUpdateMessage(updatePos, blockEntity, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,25 +19,23 @@
|
||||||
package thedarkcolour.exdeorum.network;
|
package thedarkcolour.exdeorum.network;
|
||||||
|
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||||
import net.minecraftforge.fml.DistExecutor;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraftforge.network.NetworkEvent;
|
import thedarkcolour.exdeorum.ExDeorum;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
// Server -> Client
|
// Server -> Client
|
||||||
// used to tell the client to disable the cave darkness rendering in a void world
|
// used to tell the client to disable the cave darkness rendering in a void world
|
||||||
public class VoidWorldMessage {
|
public enum VoidWorldMessage implements CustomPacketPayload {
|
||||||
public static void encode(VoidWorldMessage msg, FriendlyByteBuf packet) {
|
INSTANCE;
|
||||||
|
|
||||||
|
public static final ResourceLocation ID = new ResourceLocation(ExDeorum.ID, "void_world_msg");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(FriendlyByteBuf pBuffer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static VoidWorldMessage decode(FriendlyByteBuf packet) {
|
@Override
|
||||||
return new VoidWorldMessage();
|
public ResourceLocation id() {
|
||||||
}
|
return ID;
|
||||||
|
|
||||||
public static void handle(VoidWorldMessage msg, Supplier<NetworkEvent.Context> ctxSupplier) {
|
|
||||||
NetworkHandler.handle(ctxSupplier, ctx -> {
|
|
||||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> ClientMessageHandler::disableVoidFogRendering);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,16 @@
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.recipe;
|
package thedarkcolour.exdeorum.recipe;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
|
import com.mojang.datafixers.util.Pair;
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.DataResult;
|
||||||
|
import com.mojang.serialization.DynamicOps;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
import net.minecraft.advancements.critereon.StatePropertiesPredicate;
|
import net.minecraft.advancements.critereon.StatePropertiesPredicate;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
|
@ -36,11 +43,13 @@ import java.util.function.Predicate;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public sealed interface BlockPredicate extends Predicate<BlockState> {
|
public sealed interface BlockPredicate extends Predicate<BlockState> {
|
||||||
// used for network
|
// used for network
|
||||||
byte SINGLE_BLOCK = 0, BLOCK_STATE = 1, BLOCK_TAG = 2;
|
byte SINGLE_BLOCK = 0, BLOCK_STATE = 1, BLOCK_TAG = 2;
|
||||||
|
|
||||||
|
// todo test this
|
||||||
|
Codec<BlockPredicate> CODEC = new BlockPredicate.SpecialCodec();
|
||||||
|
|
||||||
JsonObject toJson();
|
JsonObject toJson();
|
||||||
|
|
||||||
void toNetwork(FriendlyByteBuf buffer);
|
void toNetwork(FriendlyByteBuf buffer);
|
||||||
|
|
@ -70,7 +79,7 @@ public sealed interface BlockPredicate extends Predicate<BlockState> {
|
||||||
if (block == Blocks.AIR) return null;
|
if (block == Blocks.AIR) return null;
|
||||||
|
|
||||||
if (json.has("state")) {
|
if (json.has("state")) {
|
||||||
return new BlockStatePredicate(block, StatePropertiesPredicate.fromJson(json.get("state")));
|
return new BlockStatePredicate(block, CodecUtil.decode(StatePropertiesPredicate.CODEC, json.get("state")));
|
||||||
} else {
|
} else {
|
||||||
return new SingleBlockPredicate(block);
|
return new SingleBlockPredicate(block);
|
||||||
}
|
}
|
||||||
|
|
@ -84,14 +93,24 @@ public sealed interface BlockPredicate extends Predicate<BlockState> {
|
||||||
@Nullable
|
@Nullable
|
||||||
static BlockPredicate fromNetwork(FriendlyByteBuf buffer) {
|
static BlockPredicate fromNetwork(FriendlyByteBuf buffer) {
|
||||||
return switch (buffer.readByte()) {
|
return switch (buffer.readByte()) {
|
||||||
case SINGLE_BLOCK -> new SingleBlockPredicate(buffer.readById(BuiltInRegistries.BLOCK));
|
case SINGLE_BLOCK -> new SingleBlockPredicate(Objects.requireNonNull(buffer.readById(BuiltInRegistries.BLOCK)));
|
||||||
case BLOCK_STATE -> new BlockStatePredicate(buffer.readById(BuiltInRegistries.BLOCK), StatePropertiesPredicate.fromJson(JsonParser.parseString(buffer.readUtf())));
|
case BLOCK_STATE -> new BlockStatePredicate(Objects.requireNonNull(buffer.readById(BuiltInRegistries.BLOCK)), decodeStatePredicate(JsonParser.parseString(buffer.readUtf())));
|
||||||
case BLOCK_TAG -> new TagPredicate(TagKey.create(Registries.BLOCK, buffer.readResourceLocation()));
|
case BLOCK_TAG -> new TagPredicate(RecipeUtil.readTag(buffer, Registries.BLOCK));
|
||||||
default -> null;
|
default -> null;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static StatePropertiesPredicate decodeStatePredicate(JsonElement json) {
|
||||||
|
return CodecUtil.decode(StatePropertiesPredicate.CODEC, json);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JsonElement encodeStatePredicate(StatePropertiesPredicate predicate) {
|
||||||
|
return CodecUtil.encode(StatePropertiesPredicate.CODEC, predicate);
|
||||||
|
}
|
||||||
|
|
||||||
record TagPredicate(TagKey<Block> tag) implements BlockPredicate {
|
record TagPredicate(TagKey<Block> tag) implements BlockPredicate {
|
||||||
|
private static final Codec<TagPredicate> CODEC = RecordCodecBuilder.create(instance -> instance.group(TagKey.codec(Registries.BLOCK).fieldOf("tag").forGetter(TagPredicate::tag)).apply(instance, TagPredicate::new));
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonObject toJson() {
|
public JsonObject toJson() {
|
||||||
var json = new JsonObject();
|
var json = new JsonObject();
|
||||||
|
|
@ -102,7 +121,7 @@ public sealed interface BlockPredicate extends Predicate<BlockState> {
|
||||||
@Override
|
@Override
|
||||||
public void toNetwork(FriendlyByteBuf buffer) {
|
public void toNetwork(FriendlyByteBuf buffer) {
|
||||||
buffer.writeByte(BLOCK_TAG);
|
buffer.writeByte(BLOCK_TAG);
|
||||||
buffer.writeResourceLocation(this.tag.location());
|
RecipeUtil.writeTag(buffer, this.tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -114,16 +133,20 @@ public sealed interface BlockPredicate extends Predicate<BlockState> {
|
||||||
public Stream<BlockState> possibleStates() {
|
public Stream<BlockState> possibleStates() {
|
||||||
return StreamSupport.stream(BuiltInRegistries.BLOCK.getTagOrEmpty(this.tag).spliterator(), false)
|
return StreamSupport.stream(BuiltInRegistries.BLOCK.getTagOrEmpty(this.tag).spliterator(), false)
|
||||||
.filter(holder -> holder.is(this.tag))
|
.filter(holder -> holder.is(this.tag))
|
||||||
.flatMap(holder -> holder.get().getStateDefinition().getPossibleStates().stream());
|
.flatMap(holder -> holder.value().getStateDefinition().getPossibleStates().stream());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
record BlockStatePredicate(Block block, StatePropertiesPredicate properties) implements BlockPredicate {
|
record BlockStatePredicate(Block block, StatePropertiesPredicate properties) implements BlockPredicate {
|
||||||
|
private static final Codec<BlockStatePredicate> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||||
|
CodecUtil.blockField("block", BlockStatePredicate::block),
|
||||||
|
StatePropertiesPredicate.CODEC.fieldOf("properties").forGetter(BlockStatePredicate::properties)
|
||||||
|
).apply(instance, BlockStatePredicate::new));
|
||||||
@Override
|
@Override
|
||||||
public JsonObject toJson() {
|
public JsonObject toJson() {
|
||||||
var json = new JsonObject();
|
var json = new JsonObject();
|
||||||
json.addProperty("block", BuiltInRegistries.BLOCK.getKey(this.block).toString());
|
json.addProperty("block", BuiltInRegistries.BLOCK.getKey(this.block).toString());
|
||||||
json.add("state", this.properties.serializeToJson());
|
json.add("state", encodeStatePredicate(this.properties));
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -131,7 +154,7 @@ public sealed interface BlockPredicate extends Predicate<BlockState> {
|
||||||
public void toNetwork(FriendlyByteBuf buffer) {
|
public void toNetwork(FriendlyByteBuf buffer) {
|
||||||
buffer.writeByte(BLOCK_STATE);
|
buffer.writeByte(BLOCK_STATE);
|
||||||
buffer.writeId(BuiltInRegistries.BLOCK, this.block);
|
buffer.writeId(BuiltInRegistries.BLOCK, this.block);
|
||||||
buffer.writeUtf(this.properties.serializeToJson().toString());
|
buffer.writeUtf(encodeStatePredicate(this.properties).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -150,7 +173,7 @@ public sealed interface BlockPredicate extends Predicate<BlockState> {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
BlockStatePredicate that = (BlockStatePredicate) o;
|
BlockStatePredicate that = (BlockStatePredicate) o;
|
||||||
return Objects.equals(block, that.block) && Objects.equals(properties.serializeToJson(), that.properties.serializeToJson());
|
return this.block == that.block && Objects.equals(encodeStatePredicate(this.properties), encodeStatePredicate(that.properties));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -178,4 +201,37 @@ public sealed interface BlockPredicate extends Predicate<BlockState> {
|
||||||
return this.block.getStateDefinition().getPossibleStates().stream();
|
return this.block.getStateDefinition().getPossibleStates().stream();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SpecialCodec implements Codec<BlockPredicate> {
|
||||||
|
@Override
|
||||||
|
public <T> DataResult<Pair<BlockPredicate, T>> decode(DynamicOps<T> ops, T input) {
|
||||||
|
var tagResult = TagPredicate.CODEC.decode(ops, input);
|
||||||
|
|
||||||
|
if (tagResult.error().isEmpty()) {
|
||||||
|
return CodecUtil.cast(tagResult);
|
||||||
|
} else {
|
||||||
|
var stateResult = BlockStatePredicate.CODEC.decode(ops, input);
|
||||||
|
|
||||||
|
if (stateResult.error().isEmpty()) {
|
||||||
|
return CodecUtil.cast(stateResult);
|
||||||
|
} else {
|
||||||
|
var blockResult = SingleBlockPredicate.CODEC.decode(ops, input);
|
||||||
|
|
||||||
|
return blockResult.error().isEmpty() ? CodecUtil.cast(blockResult) : DataResult.error(() -> "Invalid block predicate");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> DataResult<T> encode(BlockPredicate input, DynamicOps<T> ops, T prefix) {
|
||||||
|
// in newer java, this should be replaced with pattern matching
|
||||||
|
if (input instanceof SingleBlockPredicate block) {
|
||||||
|
return SingleBlockPredicate.CODEC.encode(block, ops, prefix);
|
||||||
|
} else if (input instanceof BlockStatePredicate state) {
|
||||||
|
return BlockStatePredicate.CODEC.encode(state, ops, prefix);
|
||||||
|
} else {
|
||||||
|
return TagPredicate.CODEC.encode((TagPredicate) input, ops, prefix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
73
src/main/java/thedarkcolour/exdeorum/recipe/CodecUtil.java
Normal file
73
src/main/java/thedarkcolour/exdeorum/recipe/CodecUtil.java
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* Ex Deorum
|
||||||
|
* Copyright (c) 2024 thedarkcolour
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package thedarkcolour.exdeorum.recipe;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.mojang.datafixers.kinds.App;
|
||||||
|
import com.mojang.datafixers.util.Pair;
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.DataResult;
|
||||||
|
import com.mojang.serialization.JsonOps;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.item.crafting.Ingredient;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.material.Fluid;
|
||||||
|
import net.neoforged.neoforge.fluids.FluidStack;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
@SuppressWarnings("OptionalGetWithoutIsPresent")
|
||||||
|
public class CodecUtil {
|
||||||
|
public static final Codec<FluidStack> FLUIDSTACK_CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||||
|
fluidField("fluid", FluidStack::getFluid),
|
||||||
|
Codec.INT.fieldOf("amount").forGetter(FluidStack::getAmount),
|
||||||
|
CompoundTag.CODEC.optionalFieldOf("tag", null).forGetter(FluidStack::getTag)
|
||||||
|
).apply(instance, FluidStack::new));
|
||||||
|
|
||||||
|
public static <T extends SingleIngredientRecipe> App<RecordCodecBuilder.Mu<T>, Ingredient> ingredientField() {
|
||||||
|
return Ingredient.CODEC_NONEMPTY.fieldOf("ingredient").forGetter(SingleIngredientRecipe::getIngredient);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> App<RecordCodecBuilder.Mu<T>, Item> itemField(String name, Function<T, Item> getter) {
|
||||||
|
return BuiltInRegistries.ITEM.byNameCodec().fieldOf(name).forGetter(getter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> App<RecordCodecBuilder.Mu<T>, Block> blockField(String name, Function<T, Block> getter) {
|
||||||
|
return BuiltInRegistries.BLOCK.byNameCodec().fieldOf(name).forGetter(getter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> App<RecordCodecBuilder.Mu<T>, Fluid> fluidField(String name, Function<T, Fluid> getter) {
|
||||||
|
return BuiltInRegistries.FLUID.byNameCodec().fieldOf(name).forGetter(getter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> JsonElement encode(Codec<T> codec, T object) {
|
||||||
|
return codec.encodeStart(JsonOps.INSTANCE, object).result().get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T decode(Codec<T> codec, JsonElement json) {
|
||||||
|
return codec.parse(JsonOps.INSTANCE, json).result().get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T, U extends T, I> DataResult<Pair<T, I>> cast(DataResult<Pair<U, I>> result) {
|
||||||
|
return result.map(pair -> pair.mapFirst(Function.identity()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
/*
|
|
||||||
* Ex Deorum
|
|
||||||
* Copyright (c) 2024 thedarkcolour
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.recipe;
|
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import net.minecraft.data.recipes.FinishedRecipe;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
public abstract class EFinishedRecipe implements FinishedRecipe {
|
|
||||||
private final ResourceLocation id;
|
|
||||||
|
|
||||||
public EFinishedRecipe(ResourceLocation id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public JsonObject serializeAdvancement() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getAdvancementId() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
133
src/main/java/thedarkcolour/exdeorum/recipe/OreChunkRecipe.java
Normal file
133
src/main/java/thedarkcolour/exdeorum/recipe/OreChunkRecipe.java
Normal file
|
|
@ -0,0 +1,133 @@
|
||||||
|
/*
|
||||||
|
* Ex Deorum
|
||||||
|
* Copyright (c) 2024 thedarkcolour
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package thedarkcolour.exdeorum.recipe;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
import net.minecraft.core.NonNullList;
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
|
import net.minecraft.core.registries.Registries;
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraft.tags.TagKey;
|
||||||
|
import net.minecraft.world.inventory.CraftingContainer;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.crafting.*;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.neoforged.neoforge.common.crafting.IShapedRecipe;
|
||||||
|
import net.neoforged.neoforge.common.util.Lazy;
|
||||||
|
import thedarkcolour.exdeorum.compat.PreferredOres;
|
||||||
|
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class OreChunkRecipe implements CraftingRecipe, IShapedRecipe<CraftingContainer> {
|
||||||
|
public static final Codec<OreChunkRecipe> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||||
|
Ingredient.CODEC_NONEMPTY.fieldOf("ore_chunk").forGetter(OreChunkRecipe::getOreChunk),
|
||||||
|
TagKey.codec(Registries.ITEM).fieldOf("ore").forGetter(OreChunkRecipe::getOre)
|
||||||
|
).apply(instance, OreChunkRecipe::new));
|
||||||
|
|
||||||
|
private static final List<String> GRID_2X2 = List.of("CC", "CC");
|
||||||
|
|
||||||
|
private final Ingredient oreChunk;
|
||||||
|
private final TagKey<Item> ore;
|
||||||
|
private final ShapedRecipePattern pattern;
|
||||||
|
private final Lazy<ItemStack> resultItem;
|
||||||
|
|
||||||
|
public OreChunkRecipe(Ingredient oreChunk, TagKey<Item> ore) {
|
||||||
|
this.oreChunk = oreChunk;
|
||||||
|
this.ore = ore;
|
||||||
|
this.pattern = ShapedRecipePattern.of(Map.of('C', oreChunk), GRID_2X2);
|
||||||
|
this.resultItem = Lazy.of(() -> {
|
||||||
|
return new ItemStack(PreferredOres.getPreferredOre(this.ore));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Ingredient getOreChunk() {
|
||||||
|
return this.oreChunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TagKey<Item> getOre() {
|
||||||
|
return this.ore;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NonNullList<Ingredient> getIngredients() {
|
||||||
|
return this.pattern.ingredients();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getResultItem(RegistryAccess pRegistryAccess) {
|
||||||
|
return this.resultItem.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack assemble(CraftingContainer pContainer, RegistryAccess pRegistryAccess) {
|
||||||
|
return this.resultItem.get().copy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(CraftingContainer container, Level pLevel) {
|
||||||
|
return this.pattern.matches(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canCraftInDimensions(int width, int height) {
|
||||||
|
return width >= 2 && height >= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRecipeWidth() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRecipeHeight() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CraftingBookCategory category() {
|
||||||
|
return CraftingBookCategory.BUILDING;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RecipeSerializer<?> getSerializer() {
|
||||||
|
return ERecipeSerializers.ORE_CHUNK.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Serializer implements RecipeSerializer<OreChunkRecipe> {
|
||||||
|
@Override
|
||||||
|
public Codec<OreChunkRecipe> codec() {
|
||||||
|
return CODEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OreChunkRecipe fromNetwork(FriendlyByteBuf buffer) {
|
||||||
|
return new OreChunkRecipe(Ingredient.fromNetwork(buffer), RecipeUtil.readTag(buffer, Registries.ITEM));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void toNetwork(FriendlyByteBuf buffer, OreChunkRecipe recipe) {
|
||||||
|
recipe.oreChunk.toNetwork(buffer);
|
||||||
|
RecipeUtil.writeTag(buffer, recipe.ore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -18,25 +18,43 @@
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.recipe;
|
package thedarkcolour.exdeorum.recipe;
|
||||||
|
|
||||||
|
import com.mojang.datafixers.Products;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.crafting.Ingredient;
|
import net.minecraft.world.item.crafting.Ingredient;
|
||||||
import net.minecraft.world.level.storage.loot.providers.number.NumberProvider;
|
import net.minecraft.world.level.storage.loot.providers.number.NumberProvider;
|
||||||
|
import net.minecraft.world.level.storage.loot.providers.number.NumberProviders;
|
||||||
|
|
||||||
public abstract class ProbabilityRecipe extends SingleIngredientRecipe {
|
public abstract class ProbabilityRecipe extends SingleIngredientRecipe {
|
||||||
public final Item result;
|
public final Item result;
|
||||||
public final NumberProvider resultAmount;
|
public final NumberProvider resultAmount;
|
||||||
|
|
||||||
public ProbabilityRecipe(ResourceLocation id, Ingredient ingredient, Item result, NumberProvider resultAmount) {
|
public ProbabilityRecipe(Ingredient ingredient, Item result, NumberProvider resultAmount) {
|
||||||
super(id, ingredient);
|
super(ingredient);
|
||||||
this.result = result;
|
this.result = result;
|
||||||
this.resultAmount = resultAmount;
|
this.resultAmount = resultAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static <T extends ProbabilityRecipe> Products.P3<RecordCodecBuilder.Mu<T>, Ingredient, Item, NumberProvider> commonFields(RecordCodecBuilder.Instance<T> instance) {
|
||||||
|
return instance.group(
|
||||||
|
CodecUtil.ingredientField(),
|
||||||
|
CodecUtil.itemField("result", ProbabilityRecipe::getResult),
|
||||||
|
NumberProviders.CODEC.fieldOf("result_amount").forGetter(ProbabilityRecipe::getResultAmount)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemStack getResultItem(RegistryAccess access) {
|
public ItemStack getResultItem(RegistryAccess access) {
|
||||||
return new ItemStack(this.result);
|
return new ItemStack(this.result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Item getResult() {
|
||||||
|
return this.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NumberProvider getResultAmount() {
|
||||||
|
return this.resultAmount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,49 +18,38 @@
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.recipe;
|
package thedarkcolour.exdeorum.recipe;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonPrimitive;
|
|
||||||
import com.google.gson.JsonSyntaxException;
|
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectSet;
|
import it.unimi.dsi.fastutil.objects.ObjectSet;
|
||||||
import net.minecraft.commands.arguments.blocks.BlockStateParser;
|
import net.minecraft.commands.arguments.blocks.BlockStateParser;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceKey;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.tags.TagKey;
|
import net.minecraft.tags.TagKey;
|
||||||
import net.minecraft.util.GsonHelper;
|
|
||||||
import net.minecraft.world.Container;
|
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.Items;
|
import net.minecraft.world.item.Items;
|
||||||
import net.minecraft.world.item.crafting.Ingredient;
|
import net.minecraft.world.item.crafting.Ingredient;
|
||||||
import net.minecraft.world.item.crafting.Recipe;
|
|
||||||
import net.minecraft.world.item.crafting.RecipeManager;
|
import net.minecraft.world.item.crafting.RecipeManager;
|
||||||
import net.minecraft.world.item.crafting.RecipeType;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.block.state.properties.Property;
|
import net.minecraft.world.level.block.state.properties.Property;
|
||||||
import net.minecraft.world.level.material.Fluid;
|
import net.minecraft.world.level.material.Fluid;
|
||||||
import net.minecraft.world.level.material.Fluids;
|
import net.minecraft.world.level.material.Fluids;
|
||||||
import net.minecraft.world.level.storage.loot.LootContext;
|
import net.minecraft.world.level.storage.loot.LootContext;
|
||||||
import net.minecraft.world.level.storage.loot.LootDataType;
|
|
||||||
import net.minecraft.world.level.storage.loot.LootParams;
|
import net.minecraft.world.level.storage.loot.LootParams;
|
||||||
import net.minecraft.world.level.storage.loot.providers.number.*;
|
import net.minecraft.world.level.storage.loot.providers.number.*;
|
||||||
import net.minecraftforge.common.crafting.CraftingHelper;
|
import net.neoforged.neoforge.fluids.FluidStack;
|
||||||
import net.minecraftforge.fluids.FluidStack;
|
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import thedarkcolour.exdeorum.ExDeorum;
|
|
||||||
import thedarkcolour.exdeorum.compat.PreferredOres;
|
import thedarkcolour.exdeorum.compat.PreferredOres;
|
||||||
import thedarkcolour.exdeorum.item.HammerItem;
|
import thedarkcolour.exdeorum.item.HammerItem;
|
||||||
import thedarkcolour.exdeorum.loot.SummationGenerator;
|
import thedarkcolour.exdeorum.loot.SummationGenerator;
|
||||||
import thedarkcolour.exdeorum.recipe.barrel.BarrelCompostRecipe;
|
import thedarkcolour.exdeorum.recipe.barrel.BarrelCompostRecipe;
|
||||||
import thedarkcolour.exdeorum.recipe.barrel.BarrelFluidMixingRecipe;
|
import thedarkcolour.exdeorum.recipe.barrel.BarrelFluidMixingRecipe;
|
||||||
import thedarkcolour.exdeorum.recipe.barrel.FluidTransformationRecipe;
|
|
||||||
import thedarkcolour.exdeorum.recipe.barrel.BarrelMixingRecipe;
|
import thedarkcolour.exdeorum.recipe.barrel.BarrelMixingRecipe;
|
||||||
|
import thedarkcolour.exdeorum.recipe.barrel.FluidTransformationRecipe;
|
||||||
import thedarkcolour.exdeorum.recipe.cache.*;
|
import thedarkcolour.exdeorum.recipe.cache.*;
|
||||||
import thedarkcolour.exdeorum.recipe.crook.CrookRecipe;
|
import thedarkcolour.exdeorum.recipe.crook.CrookRecipe;
|
||||||
import thedarkcolour.exdeorum.recipe.crucible.CrucibleRecipe;
|
import thedarkcolour.exdeorum.recipe.crucible.CrucibleRecipe;
|
||||||
|
|
@ -69,11 +58,7 @@ import thedarkcolour.exdeorum.recipe.sieve.SieveRecipe;
|
||||||
import thedarkcolour.exdeorum.registry.ENumberProviders;
|
import thedarkcolour.exdeorum.registry.ENumberProviders;
|
||||||
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.*;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public final class RecipeUtil {
|
public final class RecipeUtil {
|
||||||
private static final int CONSTANT_TYPE = 1;
|
private static final int CONSTANT_TYPE = 1;
|
||||||
|
|
@ -96,7 +81,7 @@ public final class RecipeUtil {
|
||||||
barrelCompostRecipeCache = new SingleIngredientRecipeCache<>(recipes, ERecipeTypes.BARREL_COMPOST);
|
barrelCompostRecipeCache = new SingleIngredientRecipeCache<>(recipes, ERecipeTypes.BARREL_COMPOST);
|
||||||
lavaCrucibleRecipeCache = new SingleIngredientRecipeCache<>(recipes, ERecipeTypes.LAVA_CRUCIBLE);
|
lavaCrucibleRecipeCache = new SingleIngredientRecipeCache<>(recipes, ERecipeTypes.LAVA_CRUCIBLE);
|
||||||
waterCrucibleRecipeCache = new SingleIngredientRecipeCache<>(recipes, ERecipeTypes.WATER_CRUCIBLE);
|
waterCrucibleRecipeCache = new SingleIngredientRecipeCache<>(recipes, ERecipeTypes.WATER_CRUCIBLE);
|
||||||
hammerRecipeCache = new SingleIngredientRecipeCache<>(recipes, ERecipeTypes.HAMMER).trackAllRecipes();
|
hammerRecipeCache = new SingleIngredientRecipeCache<>(recipes, ERecipeTypes.HAMMER);
|
||||||
sieveRecipeCache = new SieveRecipeCache(recipes);
|
sieveRecipeCache = new SieveRecipeCache(recipes);
|
||||||
barrelFluidMixingRecipeCache = new BarrelFluidMixingRecipeCache(recipes);
|
barrelFluidMixingRecipeCache = new BarrelFluidMixingRecipeCache(recipes);
|
||||||
fluidTransformationRecipeCache = new FluidTransformationRecipeCache(recipes);
|
fluidTransformationRecipeCache = new FluidTransformationRecipeCache(recipes);
|
||||||
|
|
@ -141,66 +126,28 @@ public final class RecipeUtil {
|
||||||
return hammerRecipeCache.getRecipe(item);
|
return hammerRecipeCache.getRecipe(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Collection<HammerRecipe> getCachedHammerRecipes() {
|
|
||||||
return hammerRecipeCache.getAllRecipes();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <C extends Container, T extends Recipe<C>> Collection<T> byType(RecipeManager manager, RecipeType<T> type) {
|
|
||||||
return manager.byType(type).values();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Ingredient readIngredient(JsonObject json, String key) {
|
|
||||||
if (GsonHelper.isArrayNode(json, key)) {
|
|
||||||
return Ingredient.fromJson(GsonHelper.getAsJsonArray(json, key));
|
|
||||||
} else {
|
|
||||||
return Ingredient.fromJson(GsonHelper.getAsJsonObject(json, key));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Item readItem(JsonObject json, String key) {
|
|
||||||
return CraftingHelper.getItem(GsonHelper.getAsString(json, key), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Fluid readFluid(JsonObject json, String key) {
|
|
||||||
String fluidName = GsonHelper.getAsString(json, key);
|
|
||||||
ResourceLocation fluidKey = new ResourceLocation(fluidName);
|
|
||||||
if (!ForgeRegistries.FLUIDS.containsKey(fluidKey)) {
|
|
||||||
throw new JsonSyntaxException("Unknown fluid '" + fluidName + "'");
|
|
||||||
}
|
|
||||||
Fluid fluid = ForgeRegistries.FLUIDS.getValue(fluidKey);
|
|
||||||
if (fluid == Fluids.EMPTY) {
|
|
||||||
throw new JsonSyntaxException("Invalid Fluid: " + fluidName);
|
|
||||||
}
|
|
||||||
return Objects.requireNonNull(fluid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static NumberProvider readNumberProvider(JsonObject json, String key) {
|
|
||||||
var obj = json.get(key);
|
|
||||||
return LootDataType.PREDICATE.parser().fromJson(obj, NumberProvider.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void toNetworkNumberProvider(FriendlyByteBuf buffer, NumberProvider provider) {
|
public static void toNetworkNumberProvider(FriendlyByteBuf buffer, NumberProvider provider) {
|
||||||
if (provider.getType() == NumberProviders.CONSTANT) {
|
if (provider.getType() == NumberProviders.CONSTANT) {
|
||||||
buffer.writeByte(CONSTANT_TYPE);
|
buffer.writeByte(CONSTANT_TYPE);
|
||||||
buffer.writeFloat(((ConstantValue) provider).value);
|
buffer.writeFloat(((ConstantValue) provider).value());
|
||||||
} else if (provider.getType() == NumberProviders.UNIFORM) {
|
} else if (provider.getType() == NumberProviders.UNIFORM) {
|
||||||
var uniform = (UniformGenerator) provider;
|
var uniform = (UniformGenerator) provider;
|
||||||
buffer.writeByte(UNIFORM_TYPE);
|
buffer.writeByte(UNIFORM_TYPE);
|
||||||
toNetworkNumberProvider(buffer, uniform.min);
|
toNetworkNumberProvider(buffer, uniform.min());
|
||||||
toNetworkNumberProvider(buffer, uniform.max);
|
toNetworkNumberProvider(buffer, uniform.max());
|
||||||
} else if (provider.getType() == NumberProviders.BINOMIAL) {
|
} else if (provider.getType() == NumberProviders.BINOMIAL) {
|
||||||
var binomial = (BinomialDistributionGenerator) provider;
|
var binomial = (BinomialDistributionGenerator) provider;
|
||||||
buffer.writeByte(BINOMIAL_TYPE);
|
buffer.writeByte(BINOMIAL_TYPE);
|
||||||
toNetworkNumberProvider(buffer, binomial.n);
|
toNetworkNumberProvider(buffer, binomial.n());
|
||||||
toNetworkNumberProvider(buffer, binomial.p);
|
toNetworkNumberProvider(buffer, binomial.p());
|
||||||
} else if (provider.getType() == ENumberProviders.SUMMATION.get()) {
|
} else if (provider.getType() == ENumberProviders.SUMMATION.get()) {
|
||||||
var summation = (SummationGenerator) provider;
|
var summation = (SummationGenerator) provider;
|
||||||
var providers = summation.providers();
|
var providers = summation.providers();
|
||||||
int length = providers.length;
|
int length = providers.size();
|
||||||
buffer.writeByte(SUMMATION_TYPE);
|
buffer.writeByte(SUMMATION_TYPE);
|
||||||
buffer.writeByte(length);
|
buffer.writeByte(length);
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
toNetworkNumberProvider(buffer, providers[i]);
|
toNetworkNumberProvider(buffer, providers.get(i));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
buffer.writeByte(UNKNOWN_TYPE);
|
buffer.writeByte(UNKNOWN_TYPE);
|
||||||
|
|
@ -220,7 +167,7 @@ public final class RecipeUtil {
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
providers[i] = fromNetworkNumberProvider(buffer);
|
providers[i] = fromNetworkNumberProvider(buffer);
|
||||||
}
|
}
|
||||||
yield new SummationGenerator(providers);
|
yield new SummationGenerator(List.of(providers));
|
||||||
}
|
}
|
||||||
default -> ConstantValue.exactly(1f);
|
default -> ConstantValue.exactly(1f);
|
||||||
};
|
};
|
||||||
|
|
@ -231,7 +178,7 @@ public final class RecipeUtil {
|
||||||
// although unlikely, we should check this anyway
|
// although unlikely, we should check this anyway
|
||||||
if (first == second) return true;
|
if (first == second) return true;
|
||||||
|
|
||||||
if (first.isVanilla() && second.isVanilla()) {
|
if (first.getClass() == Ingredient.class && second.getClass() == Ingredient.class) {
|
||||||
var firstValues = new ObjectArrayList<>(first.values);
|
var firstValues = new ObjectArrayList<>(first.values);
|
||||||
var secondValues = new ObjectArrayList<>(second.values);
|
var secondValues = new ObjectArrayList<>(second.values);
|
||||||
|
|
||||||
|
|
@ -270,11 +217,11 @@ public final class RecipeUtil {
|
||||||
if (firstKlass == secondKlass) {
|
if (firstKlass == secondKlass) {
|
||||||
if (firstKlass == Ingredient.ItemValue.class) {
|
if (firstKlass == Ingredient.ItemValue.class) {
|
||||||
// if items are different, return false
|
// if items are different, return false
|
||||||
return ItemStack.matches(((Ingredient.ItemValue) firstValue).item, ((Ingredient.ItemValue) secondValue).item);
|
return ItemStack.matches(((Ingredient.ItemValue) firstValue).item(), ((Ingredient.ItemValue) secondValue).item());
|
||||||
} else if (firstKlass == Ingredient.TagValue.class) {
|
} else if (firstKlass == Ingredient.TagValue.class) {
|
||||||
// if tags are different, return false
|
// if tags are different, return false
|
||||||
// identity comparison is okay because tags are always interned in vanilla
|
// identity comparison is okay because tags are always interned in vanilla
|
||||||
return ((Ingredient.TagValue) firstValue).tag == ((Ingredient.TagValue) secondValue).tag;
|
return ((Ingredient.TagValue) firstValue).tag() == ((Ingredient.TagValue) secondValue).tag();
|
||||||
} else {
|
} else {
|
||||||
var firstItems = firstValue.getItems();
|
var firstItems = firstValue.getItems();
|
||||||
var secondItems = secondValue.getItems();
|
var secondItems = secondValue.getItems();
|
||||||
|
|
@ -311,9 +258,9 @@ public final class RecipeUtil {
|
||||||
// todo stop using the RecipeManager
|
// todo stop using the RecipeManager
|
||||||
@Nullable
|
@Nullable
|
||||||
public static BarrelMixingRecipe getBarrelMixingRecipe(RecipeManager recipes, ItemStack stack, FluidStack fluid) {
|
public static BarrelMixingRecipe getBarrelMixingRecipe(RecipeManager recipes, ItemStack stack, FluidStack fluid) {
|
||||||
for (var recipe : byType(recipes, ERecipeTypes.BARREL_MIXING.get())) {
|
for (var recipe : recipes.byType(ERecipeTypes.BARREL_MIXING.get()).values()) {
|
||||||
if (recipe.matches(stack, fluid)) {
|
if (recipe.value().matches(stack, fluid)) {
|
||||||
return recipe;
|
return recipe.value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -323,7 +270,7 @@ public final class RecipeUtil {
|
||||||
@Nullable
|
@Nullable
|
||||||
public static BarrelFluidMixingRecipe getFluidMixingRecipe(FluidStack base, Fluid additive) {
|
public static BarrelFluidMixingRecipe getFluidMixingRecipe(FluidStack base, Fluid additive) {
|
||||||
var recipe = barrelFluidMixingRecipeCache.getRecipe(base.getFluid(), additive);
|
var recipe = barrelFluidMixingRecipeCache.getRecipe(base.getFluid(), additive);
|
||||||
if (recipe != null && base.getAmount() >= recipe.baseFluidAmount) {
|
if (recipe != null && base.getAmount() >= recipe.baseFluidAmount()) {
|
||||||
return recipe;
|
return recipe;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -341,11 +288,11 @@ public final class RecipeUtil {
|
||||||
|
|
||||||
public static double getExpectedValue(NumberProvider provider) {
|
public static double getExpectedValue(NumberProvider provider) {
|
||||||
if (provider instanceof ConstantValue constant) {
|
if (provider instanceof ConstantValue constant) {
|
||||||
return constant.value;
|
return constant.value();
|
||||||
} else if (provider instanceof UniformGenerator uniform) {
|
} else if (provider instanceof UniformGenerator uniform) {
|
||||||
return getExpectedValue(uniform.min) + getExpectedValue(uniform.max) / 2.0;
|
return getExpectedValue(uniform.min()) + getExpectedValue(uniform.max()) / 2.0;
|
||||||
} else if (provider instanceof BinomialDistributionGenerator binomial) {
|
} else if (provider instanceof BinomialDistributionGenerator binomial) {
|
||||||
return getExpectedValue(binomial.n) * getExpectedValue(binomial.p);
|
return getExpectedValue(binomial.n()) * getExpectedValue(binomial.p());
|
||||||
} else if (provider instanceof SummationGenerator summation) {
|
} else if (provider instanceof SummationGenerator summation) {
|
||||||
double avgSum = 0.0;
|
double avgSum = 0.0;
|
||||||
|
|
||||||
|
|
@ -366,33 +313,21 @@ public final class RecipeUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
public static BlockPredicate readBlockPredicateNetwork(FriendlyByteBuf buffer) {
|
||||||
public static BlockPredicate readBlockPredicate(ResourceLocation recipeId, JsonObject json, String key) {
|
|
||||||
BlockPredicate blockPredicate = BlockPredicate.fromJson(json.getAsJsonObject(key));
|
|
||||||
|
|
||||||
if (blockPredicate == null) {
|
|
||||||
ExDeorum.LOGGER.error("Invalid {} for recipe {}, refer to Ex Deorum documentation for syntax: {}", key, recipeId, json.getAsJsonObject(key));
|
|
||||||
}
|
|
||||||
return blockPredicate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static BlockPredicate readBlockPredicateNetwork(ResourceLocation recipeId, FriendlyByteBuf buffer) {
|
|
||||||
BlockPredicate blockPredicate = BlockPredicate.fromNetwork(buffer);
|
BlockPredicate blockPredicate = BlockPredicate.fromNetwork(buffer);
|
||||||
|
|
||||||
if (blockPredicate == null) {
|
if (blockPredicate == null) {
|
||||||
ExDeorum.LOGGER.error("Failed to read block_predicate from network for recipe {}", recipeId);
|
throw new IllegalStateException("Failed to read block predicate from network");
|
||||||
}
|
}
|
||||||
return blockPredicate;
|
return blockPredicate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public static boolean isTagEmpty(TagKey<Item> tag) {
|
public static boolean isTagEmpty(TagKey<Item> tag) {
|
||||||
return BuiltInRegistries.ITEM.getTag(tag).map(set -> !set.iterator().hasNext()).orElse(PreferredOres.getPreferredOre(tag) == Items.AIR);
|
return BuiltInRegistries.ITEM.getTag(tag).map(set -> !set.iterator().hasNext()).orElse(PreferredOres.getPreferredOre(tag) == Items.AIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LootContext emptyLootContext(ServerLevel level) {
|
public static LootContext emptyLootContext(ServerLevel level) {
|
||||||
return new LootContext.Builder(new LootParams(level, Map.of(), Map.of(), 0)).create(null);
|
return new LootContext.Builder(new LootParams(level, Map.of(), Map.of(), 0)).create(Optional.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<CrookRecipe> getCrookRecipes(BlockState state) {
|
public static List<CrookRecipe> getCrookRecipes(BlockState state) {
|
||||||
|
|
@ -407,46 +342,14 @@ public final class RecipeUtil {
|
||||||
return crucibleHeatRecipeCache.getEntries();
|
return crucibleHeatRecipeCache.getEntries();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FluidStack readFluidStack(JsonObject json, String key) {
|
|
||||||
if (json.has(key)) {
|
|
||||||
var fluidJson = json.getAsJsonObject(key);
|
|
||||||
// Since we aren't using codec anymore, we can use consistent naming with other JSON objects
|
|
||||||
if (fluidJson.has("FluidName")) {
|
|
||||||
var stack = new FluidStack(RecipeUtil.readFluid(fluidJson, "FluidName"), GsonHelper.getAsInt(fluidJson, "Amount"));
|
|
||||||
if (fluidJson.has("Tag")) {
|
|
||||||
stack.setTag(CraftingHelper.getNBT(fluidJson.get("Tag")));
|
|
||||||
}
|
|
||||||
return stack;
|
|
||||||
} else {
|
|
||||||
var stack = new FluidStack(RecipeUtil.readFluid(fluidJson, "fluid"), GsonHelper.getAsInt(fluidJson, "amount"));
|
|
||||||
if (fluidJson.has("nbt")) {
|
|
||||||
stack.setTag(CraftingHelper.getNBT(fluidJson.get("nbt")));
|
|
||||||
}
|
|
||||||
return stack;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new JsonSyntaxException("Missing fluid");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static JsonElement writeFluidStackJson(FluidStack fluidStack) {
|
|
||||||
JsonObject object = new JsonObject();
|
|
||||||
object.addProperty("fluid", getFluidId(fluidStack.getFluid()));
|
|
||||||
object.addProperty("amount", fluidStack.getAmount());
|
|
||||||
if (fluidStack.hasTag()) {
|
|
||||||
object.addProperty("nbt", fluidStack.getTag().getAsString());
|
|
||||||
}
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
public static JsonPrimitive writeBlockState(BlockState state) {
|
public static String writeBlockState(BlockState state) {
|
||||||
var registryKey = BuiltInRegistries.BLOCK.getKey(state.getBlock());
|
var registryKey = BuiltInRegistries.BLOCK.getKey(state.getBlock());
|
||||||
|
|
||||||
Collection<Property> properties = (Collection<Property>) ((Collection)state.getProperties());
|
Collection<Property> properties = (Collection<Property>) ((Collection)state.getProperties());
|
||||||
|
|
||||||
if (properties.isEmpty()) {
|
if (properties.isEmpty()) {
|
||||||
return new JsonPrimitive(registryKey.toString());
|
return registryKey.toString();
|
||||||
} else {
|
} else {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
builder.append(registryKey);
|
builder.append(registryKey);
|
||||||
|
|
@ -461,7 +364,7 @@ public final class RecipeUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
builder.append(']');
|
builder.append(']');
|
||||||
return new JsonPrimitive(builder.toString());
|
return builder.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -473,11 +376,11 @@ public final class RecipeUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getFluidId(Fluid baseFluid) {
|
public static void writeTag(FriendlyByteBuf buffer, TagKey<?> ore) {
|
||||||
return BuiltInRegistries.FLUID.getKey(baseFluid).toString();
|
buffer.writeResourceLocation(ore.location());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String writeItemJson(Item result) {
|
public static <T> TagKey<T> readTag(FriendlyByteBuf buffer, ResourceKey<Registry<T>> registry) {
|
||||||
return BuiltInRegistries.ITEM.getKey(result).toString();
|
return TagKey.create(registry, buffer.readResourceLocation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ package thedarkcolour.exdeorum.recipe;
|
||||||
|
|
||||||
import net.minecraft.core.NonNullList;
|
import net.minecraft.core.NonNullList;
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.world.Container;
|
import net.minecraft.world.Container;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.crafting.Ingredient;
|
import net.minecraft.world.item.crafting.Ingredient;
|
||||||
|
|
@ -34,12 +33,10 @@ import net.minecraft.world.level.Level;
|
||||||
* of any container will be checked, so only one slot should be present.
|
* of any container will be checked, so only one slot should be present.
|
||||||
*/
|
*/
|
||||||
public abstract class SingleIngredientRecipe implements Recipe<Container> {
|
public abstract class SingleIngredientRecipe implements Recipe<Container> {
|
||||||
private final ResourceLocation id;
|
|
||||||
public final Ingredient ingredient;
|
public final Ingredient ingredient;
|
||||||
public final boolean dependsOnNbt;
|
public final boolean dependsOnNbt;
|
||||||
|
|
||||||
public SingleIngredientRecipe(ResourceLocation id, Ingredient ingredient) {
|
public SingleIngredientRecipe(Ingredient ingredient) {
|
||||||
this.id = id;
|
|
||||||
this.ingredient = ingredient;
|
this.ingredient = ingredient;
|
||||||
this.dependsOnNbt = !ingredient.isSimple();
|
this.dependsOnNbt = !ingredient.isSimple();
|
||||||
}
|
}
|
||||||
|
|
@ -63,11 +60,6 @@ public abstract class SingleIngredientRecipe implements Recipe<Container> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemStack getResultItem(RegistryAccess access) {
|
public ItemStack getResultItem(RegistryAccess access) {
|
||||||
return ItemStack.EMPTY;
|
return ItemStack.EMPTY;
|
||||||
|
|
|
||||||
|
|
@ -1,123 +0,0 @@
|
||||||
/*
|
|
||||||
* Ex Deorum
|
|
||||||
* Copyright (c) 2024 thedarkcolour
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.recipe;
|
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
|
||||||
import net.minecraft.core.registries.Registries;
|
|
||||||
import net.minecraft.data.recipes.FinishedRecipe;
|
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.tags.TagKey;
|
|
||||||
import net.minecraft.util.GsonHelper;
|
|
||||||
import net.minecraft.world.item.Item;
|
|
||||||
import net.minecraft.world.item.Items;
|
|
||||||
import net.minecraft.world.item.crafting.Recipe;
|
|
||||||
import net.minecraft.world.item.crafting.RecipeManager;
|
|
||||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import thedarkcolour.exdeorum.ExDeorum;
|
|
||||||
import thedarkcolour.exdeorum.compat.PreferredOres;
|
|
||||||
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
|
||||||
|
|
||||||
public class TagResultRecipe {
|
|
||||||
public static class Serializer<T extends Recipe<?>> implements RecipeSerializer<T> {
|
|
||||||
@SuppressWarnings({"deprecation", "unchecked"})
|
|
||||||
@Override
|
|
||||||
public T fromJson(ResourceLocation id, JsonObject json) {
|
|
||||||
var resultTag = GsonHelper.getAsString(json, "result_tag");
|
|
||||||
if (ResourceLocation.isValidResourceLocation(resultTag)) {
|
|
||||||
var tag = TagKey.create(Registries.ITEM, new ResourceLocation(resultTag));
|
|
||||||
var preferredItem = PreferredOres.getPreferredOre(tag);
|
|
||||||
if (preferredItem != Items.AIR) {
|
|
||||||
var recipeJson = GsonHelper.getAsJsonObject(json, "recipe");
|
|
||||||
|
|
||||||
if (recipeJson.has("result")) {
|
|
||||||
var resultJson = GsonHelper.getAsJsonObject(recipeJson, "result");
|
|
||||||
var itemId = preferredItem.builtInRegistryHolder().key().location().toString();
|
|
||||||
|
|
||||||
// replace item id with correct value
|
|
||||||
resultJson.addProperty("item", itemId);
|
|
||||||
|
|
||||||
return (T) RecipeManager.fromJson(id, recipeJson);
|
|
||||||
} else {
|
|
||||||
ExDeorum.LOGGER.error("Skipping recipe {} with unhandled recipe type, \"{}\". Please report to Ex Deorum GitHub.", id, recipeJson.get("type").getAsString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ExDeorum.LOGGER.info("Skipping recipe {} as ExDeorum could not determine substitute for tag {}", id, tag.location());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ExDeorum.LOGGER.error("Invalid resource location for \"result_tag\" in recipe {}", id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable T fromNetwork(ResourceLocation id, FriendlyByteBuf buffer) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void toNetwork(FriendlyByteBuf buffer, T recipe) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Finished implements FinishedRecipe {
|
|
||||||
private final TagKey<Item> resultTag;
|
|
||||||
private final FinishedRecipe recipe;
|
|
||||||
|
|
||||||
public Finished(TagKey<Item> resultTag, FinishedRecipe recipe) {
|
|
||||||
this.resultTag = resultTag;
|
|
||||||
this.recipe = recipe;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void serializeRecipeData(JsonObject json) {
|
|
||||||
JsonObject recipeJson = new JsonObject();
|
|
||||||
this.recipe.serializeRecipeData(recipeJson);
|
|
||||||
recipeJson.addProperty("type", BuiltInRegistries.RECIPE_SERIALIZER.getKey(this.recipe.getType()).toString());
|
|
||||||
|
|
||||||
json.addProperty("result_tag", this.resultTag.location().toString());
|
|
||||||
json.add("recipe", recipeJson);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getId() {
|
|
||||||
return this.recipe.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RecipeSerializer<?> getType() {
|
|
||||||
return ERecipeSerializers.TAG_RESULT.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public JsonObject serializeAdvancement() {
|
|
||||||
return this.recipe.serializeAdvancement();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getAdvancementId() {
|
|
||||||
return this.recipe.getAdvancementId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -23,7 +23,10 @@ import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonSyntaxException;
|
import com.google.gson.JsonSyntaxException;
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectImmutableList;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.util.GsonHelper;
|
import net.minecraft.util.GsonHelper;
|
||||||
import net.minecraft.util.RandomSource;
|
import net.minecraft.util.RandomSource;
|
||||||
|
|
@ -92,10 +95,6 @@ public class WeightedList<T> {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> Builder<T> builder() {
|
|
||||||
return new Builder<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> WeightedList<T> fromNetwork(FriendlyByteBuf buffer, Function<FriendlyByteBuf, T> valueReader) {
|
public static <T> WeightedList<T> fromNetwork(FriendlyByteBuf buffer, Function<FriendlyByteBuf, T> valueReader) {
|
||||||
int size = buffer.readVarInt();
|
int size = buffer.readVarInt();
|
||||||
Object[] values = new Object[size];
|
Object[] values = new Object[size];
|
||||||
|
|
@ -142,6 +141,39 @@ public class WeightedList<T> {
|
||||||
return list.build();
|
return list.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
|
public static <T> Codec<WeightedList<T>> codec(Codec<T> valueCodec) {
|
||||||
|
return Entry.codec(valueCodec).listOf().xmap(entries -> {
|
||||||
|
var builder = WeightedList.<T>builder();
|
||||||
|
for (var entry : entries) {
|
||||||
|
builder.add(entry.weight, entry.value);
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
|
}, list -> {
|
||||||
|
var entries = new Entry[list.values.length];
|
||||||
|
var entryList = new ObjectImmutableList<Entry<T>>(entries);
|
||||||
|
for (int i = 0; i < list.values.length; i++) {
|
||||||
|
entries[i] = new Entry(list.values[i], list.weights[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return entryList;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used only for Codec
|
||||||
|
private record Entry<T>(T value, int weight) {
|
||||||
|
private static <T> Codec<Entry<T>> codec(Codec<T> valueCodec) {
|
||||||
|
return RecordCodecBuilder.create(instance -> instance.group(
|
||||||
|
valueCodec.fieldOf("value").forGetter(Entry::value),
|
||||||
|
Codec.INT.fieldOf("weight").forGetter(Entry::weight)
|
||||||
|
).apply(instance, Entry::new));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Builder<T> builder() {
|
||||||
|
return new Builder<>();
|
||||||
|
}
|
||||||
|
|
||||||
public static class Builder<T> {
|
public static class Builder<T> {
|
||||||
private final ArrayList<T> values = new ArrayList<>();
|
private final ArrayList<T> values = new ArrayList<>();
|
||||||
private final IntArrayList weights = new IntArrayList();
|
private final IntArrayList weights = new IntArrayList();
|
||||||
|
|
|
||||||
|
|
@ -18,23 +18,27 @@
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.recipe.barrel;
|
package thedarkcolour.exdeorum.recipe.barrel;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.util.GsonHelper;
|
|
||||||
import net.minecraft.world.item.crafting.Ingredient;
|
import net.minecraft.world.item.crafting.Ingredient;
|
||||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||||
import net.minecraft.world.item.crafting.RecipeType;
|
import net.minecraft.world.item.crafting.RecipeType;
|
||||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
import thedarkcolour.exdeorum.recipe.CodecUtil;
|
||||||
import thedarkcolour.exdeorum.recipe.SingleIngredientRecipe;
|
import thedarkcolour.exdeorum.recipe.SingleIngredientRecipe;
|
||||||
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
||||||
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
||||||
|
|
||||||
public class BarrelCompostRecipe extends SingleIngredientRecipe {
|
public class BarrelCompostRecipe extends SingleIngredientRecipe {
|
||||||
|
public static final Codec<BarrelCompostRecipe> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||||
|
CodecUtil.ingredientField(),
|
||||||
|
Codec.INT.fieldOf("volume").forGetter(BarrelCompostRecipe::getVolume)
|
||||||
|
).apply(instance, BarrelCompostRecipe::new));
|
||||||
|
|
||||||
private final int volume;
|
private final int volume;
|
||||||
|
|
||||||
public BarrelCompostRecipe(ResourceLocation id, Ingredient ingredient, int volume) {
|
public BarrelCompostRecipe(Ingredient ingredient, int volume) {
|
||||||
super(id, ingredient);
|
super(ingredient);
|
||||||
|
|
||||||
this.volume = volume;
|
this.volume = volume;
|
||||||
}
|
}
|
||||||
|
|
@ -54,12 +58,9 @@ public class BarrelCompostRecipe extends SingleIngredientRecipe {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Serializer implements RecipeSerializer<BarrelCompostRecipe> {
|
public static class Serializer implements RecipeSerializer<BarrelCompostRecipe> {
|
||||||
@Override // Creates the recipe object from a JSON file
|
@Override
|
||||||
public BarrelCompostRecipe fromJson(ResourceLocation name, JsonObject json) {
|
public Codec<BarrelCompostRecipe> codec() {
|
||||||
Ingredient ingredient = RecipeUtil.readIngredient(json, "ingredient");
|
return CODEC;
|
||||||
int volume = GsonHelper.getAsInt(json, "volume");
|
|
||||||
|
|
||||||
return new BarrelCompostRecipe(name, ingredient, volume);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -69,11 +70,11 @@ public class BarrelCompostRecipe extends SingleIngredientRecipe {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BarrelCompostRecipe fromNetwork(ResourceLocation name, FriendlyByteBuf buffer) {
|
public BarrelCompostRecipe fromNetwork(FriendlyByteBuf buffer) {
|
||||||
Ingredient ingredient = Ingredient.fromNetwork(buffer);
|
Ingredient ingredient = Ingredient.fromNetwork(buffer);
|
||||||
int volume = buffer.readVarInt();
|
int volume = buffer.readVarInt();
|
||||||
|
|
||||||
return new BarrelCompostRecipe(name, ingredient, volume);
|
return new BarrelCompostRecipe(ingredient, volume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,11 @@
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.recipe.barrel;
|
package thedarkcolour.exdeorum.recipe.barrel;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.core.RegistryAccess;
|
||||||
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.util.GsonHelper;
|
|
||||||
import net.minecraft.world.Container;
|
import net.minecraft.world.Container;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
|
@ -31,33 +31,30 @@ import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||||
import net.minecraft.world.item.crafting.RecipeType;
|
import net.minecraft.world.item.crafting.RecipeType;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.material.Fluid;
|
import net.minecraft.world.level.material.Fluid;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
import thedarkcolour.exdeorum.recipe.CodecUtil;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
|
||||||
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
||||||
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
// A recipe where two fluids are mixed together, rather than a fluid and an item.
|
// A recipe where two fluids are mixed together, rather than a fluid and an item.
|
||||||
// The additive must be 1000mB or a source block worth of liquid.
|
// The additive must be 1000mB or a source block worth of liquid.
|
||||||
// The additive is not consumed, however. Additives placed in the world are not consumed,
|
// The additive is not consumed, however. Additives placed in the world are not consumed,
|
||||||
// so it would be unfair to consume the handheld additive.
|
// so it would be unfair to consume the handheld additive.
|
||||||
public class BarrelFluidMixingRecipe implements Recipe<Container> {
|
public record BarrelFluidMixingRecipe(
|
||||||
private final ResourceLocation id;
|
Fluid baseFluid,
|
||||||
|
int baseFluidAmount,
|
||||||
public final Fluid baseFluid;
|
Fluid additiveFluid,
|
||||||
public final int baseFluidAmount;
|
Item result,
|
||||||
public final Fluid additiveFluid;
|
boolean consumesAdditive
|
||||||
public final Item result;
|
) implements Recipe<Container> {
|
||||||
public final boolean consumesAdditive;
|
public static final Codec<BarrelFluidMixingRecipe> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||||
|
CodecUtil.fluidField("base_fluid", BarrelFluidMixingRecipe::baseFluid),
|
||||||
public BarrelFluidMixingRecipe(ResourceLocation id, Fluid baseFluid, int baseFluidAmount, Fluid additiveFluid, Item result, boolean consumesAdditive) {
|
Codec.INT.fieldOf("base_fluid_amount").forGetter(BarrelFluidMixingRecipe::baseFluidAmount),
|
||||||
this.id = id;
|
CodecUtil.fluidField("additive_fluid", BarrelFluidMixingRecipe::baseFluid),
|
||||||
this.baseFluid = baseFluid;
|
CodecUtil.itemField("result", BarrelFluidMixingRecipe::result),
|
||||||
this.baseFluidAmount = baseFluidAmount;
|
Codec.BOOL.optionalFieldOf("base_fluid", false).forGetter(BarrelFluidMixingRecipe::consumesAdditive)
|
||||||
this.additiveFluid = additiveFluid;
|
).apply(instance, BarrelFluidMixingRecipe::new));
|
||||||
this.result = result;
|
|
||||||
this.consumesAdditive = consumesAdditive;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(Container pContainer, Level pLevel) {
|
public boolean matches(Container pContainer, Level pLevel) {
|
||||||
|
|
@ -79,11 +76,6 @@ public class BarrelFluidMixingRecipe implements Recipe<Container> {
|
||||||
return new ItemStack(this.result);
|
return new ItemStack(this.result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RecipeSerializer<?> getSerializer() {
|
public RecipeSerializer<?> getSerializer() {
|
||||||
return ERecipeSerializers.BARREL_FLUID_MIXING.get();
|
return ERecipeSerializers.BARREL_FLUID_MIXING.get();
|
||||||
|
|
@ -96,34 +88,28 @@ public class BarrelFluidMixingRecipe implements Recipe<Container> {
|
||||||
|
|
||||||
public static class Serializer implements RecipeSerializer<BarrelFluidMixingRecipe> {
|
public static class Serializer implements RecipeSerializer<BarrelFluidMixingRecipe> {
|
||||||
@Override
|
@Override
|
||||||
public BarrelFluidMixingRecipe fromJson(ResourceLocation id, JsonObject json) {
|
public Codec<BarrelFluidMixingRecipe> codec() {
|
||||||
Fluid baseFluid = RecipeUtil.readFluid(json, "base_fluid");
|
return CODEC;
|
||||||
int baseFluidAmount = GsonHelper.getAsInt(json, "base_fluid_amount");
|
|
||||||
Fluid additiveFluid = RecipeUtil.readFluid(json, "additive_fluid");
|
|
||||||
Item result = RecipeUtil.readItem(json, "result");
|
|
||||||
boolean consumesAdditive = GsonHelper.getAsBoolean(json, "consumes_additive");
|
|
||||||
|
|
||||||
return new BarrelFluidMixingRecipe(id, baseFluid, baseFluidAmount, additiveFluid, result, consumesAdditive);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toNetwork(FriendlyByteBuf buffer, BarrelFluidMixingRecipe recipe) {
|
public void toNetwork(FriendlyByteBuf buffer, BarrelFluidMixingRecipe recipe) {
|
||||||
buffer.writeRegistryId(ForgeRegistries.FLUIDS, recipe.baseFluid);
|
buffer.writeId(BuiltInRegistries.FLUID, recipe.baseFluid);
|
||||||
buffer.writeVarInt(recipe.baseFluidAmount);
|
buffer.writeVarInt(recipe.baseFluidAmount);
|
||||||
buffer.writeRegistryId(ForgeRegistries.FLUIDS, recipe.additiveFluid);
|
buffer.writeId(BuiltInRegistries.FLUID, recipe.additiveFluid);
|
||||||
buffer.writeRegistryId(ForgeRegistries.ITEMS, recipe.result);
|
buffer.writeId(BuiltInRegistries.ITEM, recipe.result);
|
||||||
buffer.writeBoolean(recipe.consumesAdditive);
|
buffer.writeBoolean(recipe.consumesAdditive);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable BarrelFluidMixingRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf buffer) {
|
public BarrelFluidMixingRecipe fromNetwork(FriendlyByteBuf buffer) {
|
||||||
Fluid baseFluid = buffer.readRegistryId();
|
Fluid baseFluid = Objects.requireNonNull(buffer.readById(BuiltInRegistries.FLUID));
|
||||||
int baseFluidAmount = buffer.readVarInt();
|
int baseFluidAmount = buffer.readVarInt();
|
||||||
Fluid additiveFluid = buffer.readRegistryId();
|
Fluid additiveFluid = Objects.requireNonNull(buffer.readById(BuiltInRegistries.FLUID));
|
||||||
Item result = buffer.readRegistryId();
|
Item result = Objects.requireNonNull(buffer.readById(BuiltInRegistries.ITEM));
|
||||||
boolean consumesAdditive = buffer.readBoolean();
|
boolean consumesAdditive = buffer.readBoolean();
|
||||||
|
|
||||||
return new BarrelFluidMixingRecipe(id, baseFluid, baseFluidAmount, additiveFluid, result, consumesAdditive);
|
return new BarrelFluidMixingRecipe(baseFluid, baseFluidAmount, additiveFluid, result, consumesAdditive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,11 @@
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.recipe.barrel;
|
package thedarkcolour.exdeorum.recipe.barrel;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.core.RegistryAccess;
|
||||||
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.util.GsonHelper;
|
|
||||||
import net.minecraft.world.Container;
|
import net.minecraft.world.Container;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
|
@ -31,26 +31,45 @@ import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||||
import net.minecraft.world.item.crafting.RecipeType;
|
import net.minecraft.world.item.crafting.RecipeType;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.material.Fluid;
|
import net.minecraft.world.level.material.Fluid;
|
||||||
import net.minecraftforge.fluids.FluidStack;
|
import net.neoforged.neoforge.fluids.FluidStack;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
import thedarkcolour.exdeorum.recipe.CodecUtil;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
|
||||||
import thedarkcolour.exdeorum.recipe.SingleIngredientRecipe;
|
import thedarkcolour.exdeorum.recipe.SingleIngredientRecipe;
|
||||||
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
||||||
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class BarrelMixingRecipe extends SingleIngredientRecipe {
|
public class BarrelMixingRecipe extends SingleIngredientRecipe {
|
||||||
|
public static final Codec<BarrelMixingRecipe> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||||
|
CodecUtil.ingredientField(),
|
||||||
|
CodecUtil.fluidField("fluid", BarrelMixingRecipe::getFluid),
|
||||||
|
Codec.INT.fieldOf("fluid_amount").forGetter(BarrelMixingRecipe::getFluidAmount),
|
||||||
|
CodecUtil.itemField("result", BarrelMixingRecipe::getResult)
|
||||||
|
).apply(instance, BarrelMixingRecipe::new));
|
||||||
|
|
||||||
public final Fluid fluid;
|
public final Fluid fluid;
|
||||||
public final int fluidAmount;
|
public final int fluidAmount;
|
||||||
public final Item result;
|
public final Item result;
|
||||||
|
|
||||||
public BarrelMixingRecipe(ResourceLocation id, Ingredient ingredient, Fluid fluid, int fluidAmount, Item result) {
|
public BarrelMixingRecipe(Ingredient ingredient, Fluid fluid, int fluidAmount, Item result) {
|
||||||
super(id, ingredient);
|
super(ingredient);
|
||||||
this.fluid = fluid;
|
this.fluid = fluid;
|
||||||
this.fluidAmount = fluidAmount;
|
this.fluidAmount = fluidAmount;
|
||||||
this.result = result;
|
this.result = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Fluid getFluid() {
|
||||||
|
return this.fluid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFluidAmount() {
|
||||||
|
return this.fluidAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item getResult() {
|
||||||
|
return this.result;
|
||||||
|
}
|
||||||
|
|
||||||
// Do not use
|
// Do not use
|
||||||
@Override
|
@Override
|
||||||
@Deprecated
|
@Deprecated
|
||||||
|
|
@ -79,31 +98,26 @@ public class BarrelMixingRecipe extends SingleIngredientRecipe {
|
||||||
|
|
||||||
public static class Serializer implements RecipeSerializer<BarrelMixingRecipe> {
|
public static class Serializer implements RecipeSerializer<BarrelMixingRecipe> {
|
||||||
@Override
|
@Override
|
||||||
public BarrelMixingRecipe fromJson(ResourceLocation id, JsonObject json) {
|
public Codec<BarrelMixingRecipe> codec() {
|
||||||
Ingredient ingredient = RecipeUtil.readIngredient(json, "ingredient");
|
return CODEC;
|
||||||
Fluid fluid = RecipeUtil.readFluid(json, "fluid");
|
|
||||||
int fluidAmount = GsonHelper.getAsInt(json, "fluid_amount");
|
|
||||||
Item result = RecipeUtil.readItem(json, "result");
|
|
||||||
|
|
||||||
return new BarrelMixingRecipe(id, ingredient, fluid, fluidAmount, result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toNetwork(FriendlyByteBuf buffer, BarrelMixingRecipe recipe) {
|
public void toNetwork(FriendlyByteBuf buffer, BarrelMixingRecipe recipe) {
|
||||||
recipe.ingredient.toNetwork(buffer);
|
recipe.ingredient.toNetwork(buffer);
|
||||||
buffer.writeRegistryId(ForgeRegistries.FLUIDS, recipe.fluid);
|
buffer.writeId(BuiltInRegistries.FLUID, recipe.fluid);
|
||||||
buffer.writeVarInt(recipe.fluidAmount);
|
buffer.writeVarInt(recipe.fluidAmount);
|
||||||
buffer.writeRegistryId(ForgeRegistries.ITEMS, recipe.result);
|
buffer.writeId(BuiltInRegistries.ITEM, recipe.result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable BarrelMixingRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf buffer) {
|
public BarrelMixingRecipe fromNetwork(FriendlyByteBuf buffer) {
|
||||||
Ingredient ingredient = Ingredient.fromNetwork(buffer);
|
Ingredient ingredient = Ingredient.fromNetwork(buffer);
|
||||||
Fluid fluid = buffer.readRegistryId();
|
Fluid fluid = Objects.requireNonNull(buffer.readById(BuiltInRegistries.FLUID));
|
||||||
int fluidAmount = buffer.readVarInt();
|
int fluidAmount = buffer.readVarInt();
|
||||||
Item result = buffer.readRegistryId();
|
Item result = Objects.requireNonNull(buffer.readById(BuiltInRegistries.ITEM));
|
||||||
|
|
||||||
return new BarrelMixingRecipe(id, ingredient, fluid, fluidAmount, result);
|
return new BarrelMixingRecipe(ingredient, fluid, fluidAmount, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
/*
|
|
||||||
* Ex Deorum
|
|
||||||
* Copyright (c) 2024 thedarkcolour
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.recipe.barrel;
|
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.world.item.crafting.Ingredient;
|
|
||||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
|
||||||
import thedarkcolour.exdeorum.recipe.EFinishedRecipe;
|
|
||||||
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
|
||||||
|
|
||||||
public class FinishedBarrelCompostRecipe extends EFinishedRecipe {
|
|
||||||
private final Ingredient ingredient;
|
|
||||||
private final int volume;
|
|
||||||
|
|
||||||
public FinishedBarrelCompostRecipe(ResourceLocation id, Ingredient ingredient, int volume) {
|
|
||||||
super(id);
|
|
||||||
this.ingredient = ingredient;
|
|
||||||
this.volume = volume;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void serializeRecipeData(JsonObject json) {
|
|
||||||
json.add("ingredient", this.ingredient.toJson());
|
|
||||||
json.addProperty("volume", this.volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RecipeSerializer<?> getType() {
|
|
||||||
return ERecipeSerializers.BARREL_COMPOST.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
/*
|
|
||||||
* Ex Deorum
|
|
||||||
* Copyright (c) 2024 thedarkcolour
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.recipe.barrel;
|
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.world.item.Item;
|
|
||||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
|
||||||
import net.minecraft.world.level.material.Fluid;
|
|
||||||
import thedarkcolour.exdeorum.recipe.EFinishedRecipe;
|
|
||||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
|
||||||
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
|
||||||
|
|
||||||
public class FinishedBarrelFluidMixingRecipe extends EFinishedRecipe {
|
|
||||||
private final Fluid baseFluid;
|
|
||||||
private final int baseFluidAmount;
|
|
||||||
private final Fluid additiveFluid;
|
|
||||||
private final Item result;
|
|
||||||
private final boolean consumesAdditive;
|
|
||||||
|
|
||||||
public FinishedBarrelFluidMixingRecipe(ResourceLocation id, Fluid baseFluid, int baseFluidAmount, Fluid additiveFluid, Item result, boolean consumesAdditive) {
|
|
||||||
super(id);
|
|
||||||
this.baseFluid = baseFluid;
|
|
||||||
this.baseFluidAmount = baseFluidAmount;
|
|
||||||
this.additiveFluid = additiveFluid;
|
|
||||||
this.result = result;
|
|
||||||
this.consumesAdditive = consumesAdditive;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void serializeRecipeData(JsonObject json) {
|
|
||||||
json.addProperty("base_fluid", RecipeUtil.getFluidId(this.baseFluid));
|
|
||||||
json.addProperty("base_fluid_amount", this.baseFluidAmount);
|
|
||||||
json.addProperty("additive_fluid", RecipeUtil.getFluidId(this.additiveFluid));
|
|
||||||
json.addProperty("consumes_additive", this.consumesAdditive);
|
|
||||||
json.addProperty("result", RecipeUtil.writeItemJson(this.result));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RecipeSerializer<?> getType() {
|
|
||||||
return ERecipeSerializers.BARREL_FLUID_MIXING.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
/*
|
|
||||||
* Ex Deorum
|
|
||||||
* Copyright (c) 2024 thedarkcolour
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.recipe.barrel;
|
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.world.item.Item;
|
|
||||||
import net.minecraft.world.item.crafting.Ingredient;
|
|
||||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
|
||||||
import net.minecraft.world.level.material.Fluid;
|
|
||||||
import thedarkcolour.exdeorum.recipe.EFinishedRecipe;
|
|
||||||
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
|
||||||
|
|
||||||
public class FinishedBarrelMixingRecipe extends EFinishedRecipe {
|
|
||||||
private final Ingredient ingredient;
|
|
||||||
private final Fluid fluid;
|
|
||||||
private final int fluidAmount;
|
|
||||||
private final Item result;
|
|
||||||
|
|
||||||
public FinishedBarrelMixingRecipe(ResourceLocation id, Ingredient ingredient, Fluid fluid, int fluidAmount, Item result) {
|
|
||||||
super(id);
|
|
||||||
this.ingredient = ingredient;
|
|
||||||
this.fluid = fluid;
|
|
||||||
this.fluidAmount = fluidAmount;
|
|
||||||
this.result = result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void serializeRecipeData(JsonObject json) {
|
|
||||||
json.add("ingredient", this.ingredient.toJson());
|
|
||||||
json.addProperty("fluid", BuiltInRegistries.FLUID.getKey(this.fluid).toString());
|
|
||||||
json.addProperty("fluid_amount", this.fluidAmount);
|
|
||||||
json.addProperty("result", BuiltInRegistries.ITEM.getKey(this.result).toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RecipeSerializer<?> getType() {
|
|
||||||
return ERecipeSerializers.BARREL_MIXING.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
/*
|
|
||||||
* Ex Deorum
|
|
||||||
* Copyright (c) 2024 thedarkcolour
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.recipe.barrel;
|
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraft.world.level.material.Fluid;
|
|
||||||
import thedarkcolour.exdeorum.recipe.BlockPredicate;
|
|
||||||
import thedarkcolour.exdeorum.recipe.EFinishedRecipe;
|
|
||||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
|
||||||
import thedarkcolour.exdeorum.recipe.WeightedList;
|
|
||||||
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
|
||||||
|
|
||||||
public class FinishedFluidTransformationRecipe extends EFinishedRecipe {
|
|
||||||
private final Fluid baseFluid;
|
|
||||||
private final Fluid resultFluid;
|
|
||||||
private final int resultColor;
|
|
||||||
private final BlockPredicate catalyst;
|
|
||||||
private final WeightedList<BlockState> byproducts;
|
|
||||||
private final int duration;
|
|
||||||
|
|
||||||
public FinishedFluidTransformationRecipe(ResourceLocation id, Fluid baseFluid, Fluid resultFluid, int resultColor, BlockPredicate catalyst, WeightedList<BlockState> byproducts, int duration) {
|
|
||||||
super(id);
|
|
||||||
this.baseFluid = baseFluid;
|
|
||||||
this.resultFluid = resultFluid;
|
|
||||||
this.resultColor = resultColor;
|
|
||||||
this.catalyst = catalyst;
|
|
||||||
this.byproducts = byproducts;
|
|
||||||
this.duration = duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void serializeRecipeData(JsonObject json) {
|
|
||||||
json.addProperty("base_fluid", RecipeUtil.getFluidId(this.baseFluid));
|
|
||||||
json.addProperty("result_fluid", RecipeUtil.getFluidId(this.resultFluid));
|
|
||||||
json.addProperty("result_color", this.resultColor);
|
|
||||||
json.addProperty("duration", this.duration);
|
|
||||||
json.add("catalyst", this.catalyst.toJson());
|
|
||||||
json.add("byproducts", this.byproducts.toJson(RecipeUtil::writeBlockState));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RecipeSerializer<?> getType() {
|
|
||||||
return ERecipeSerializers.BARREL_FLUID_TRANSFORMATION.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -18,13 +18,11 @@
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.recipe.barrel;
|
package thedarkcolour.exdeorum.recipe.barrel;
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
import com.mojang.serialization.Codec;
|
||||||
import com.google.gson.JsonObject;
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
import com.google.gson.JsonSyntaxException;
|
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.core.RegistryAccess;
|
||||||
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.util.GsonHelper;
|
|
||||||
import net.minecraft.world.Container;
|
import net.minecraft.world.Container;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.crafting.Recipe;
|
import net.minecraft.world.item.crafting.Recipe;
|
||||||
|
|
@ -34,10 +32,8 @@ import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.material.Fluid;
|
import net.minecraft.world.level.material.Fluid;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import thedarkcolour.exdeorum.ExDeorum;
|
|
||||||
import thedarkcolour.exdeorum.recipe.BlockPredicate;
|
import thedarkcolour.exdeorum.recipe.BlockPredicate;
|
||||||
|
import thedarkcolour.exdeorum.recipe.CodecUtil;
|
||||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
||||||
import thedarkcolour.exdeorum.recipe.WeightedList;
|
import thedarkcolour.exdeorum.recipe.WeightedList;
|
||||||
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
||||||
|
|
@ -46,25 +42,22 @@ import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
// todo consider NBT tag of input fluid?
|
// todo consider NBT tag of input fluid?
|
||||||
public class FluidTransformationRecipe implements Recipe<Container> {
|
public record FluidTransformationRecipe(
|
||||||
private final ResourceLocation id;
|
Fluid baseFluid,
|
||||||
|
Fluid resultFluid,
|
||||||
public final Fluid baseFluid;
|
int resultColor,
|
||||||
public final Fluid resultFluid;
|
BlockPredicate catalyst,
|
||||||
public final int resultColor;
|
WeightedList<BlockState> byproducts,
|
||||||
public final BlockPredicate catalyst;
|
int duration
|
||||||
public final WeightedList<BlockState> byproducts;
|
) implements Recipe<Container> {
|
||||||
public final int duration;
|
public static final Codec<FluidTransformationRecipe> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||||
|
CodecUtil.fluidField("base_fluid", FluidTransformationRecipe::baseFluid),
|
||||||
public FluidTransformationRecipe(ResourceLocation id, Fluid baseFluid, Fluid resultFluid, int resultColor, BlockPredicate catalyst, WeightedList<BlockState> byproducts, int duration) {
|
CodecUtil.fluidField("result_fluid", FluidTransformationRecipe::resultFluid),
|
||||||
this.id = id;
|
Codec.INT.fieldOf("result_color").forGetter(FluidTransformationRecipe::resultColor),
|
||||||
this.baseFluid = baseFluid;
|
BlockPredicate.CODEC.fieldOf("catalyst").forGetter(FluidTransformationRecipe::catalyst),
|
||||||
this.resultFluid = resultFluid;
|
WeightedList.codec(Codec.STRING.xmap(RecipeUtil::parseBlockState, RecipeUtil::writeBlockState)).fieldOf("byproducts").forGetter(FluidTransformationRecipe::byproducts),
|
||||||
this.resultColor = resultColor;
|
Codec.INT.fieldOf("duration").forGetter(FluidTransformationRecipe::duration)
|
||||||
this.catalyst = catalyst;
|
).apply(instance, FluidTransformationRecipe::new));
|
||||||
this.byproducts = byproducts;
|
|
||||||
this.duration = duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(Container pContainer, Level pLevel) {
|
public boolean matches(Container pContainer, Level pLevel) {
|
||||||
|
|
@ -86,11 +79,6 @@ public class FluidTransformationRecipe implements Recipe<Container> {
|
||||||
return ItemStack.EMPTY;
|
return ItemStack.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RecipeSerializer<?> getSerializer() {
|
public RecipeSerializer<?> getSerializer() {
|
||||||
return ERecipeSerializers.BARREL_FLUID_TRANSFORMATION.get();
|
return ERecipeSerializers.BARREL_FLUID_TRANSFORMATION.get();
|
||||||
|
|
@ -103,32 +91,14 @@ public class FluidTransformationRecipe implements Recipe<Container> {
|
||||||
|
|
||||||
public static class Serializer implements RecipeSerializer<FluidTransformationRecipe> {
|
public static class Serializer implements RecipeSerializer<FluidTransformationRecipe> {
|
||||||
@Override
|
@Override
|
||||||
public FluidTransformationRecipe fromJson(ResourceLocation id, JsonObject json) {
|
public Codec<FluidTransformationRecipe> codec() {
|
||||||
Fluid baseFluid = RecipeUtil.readFluid(json, "base_fluid");
|
return CODEC;
|
||||||
Fluid resultFluid = RecipeUtil.readFluid(json, "result_fluid");
|
|
||||||
int resultColor = GsonHelper.getAsInt(json, "result_color");
|
|
||||||
int duration = GsonHelper.getAsInt(json, "duration");
|
|
||||||
BlockPredicate catalyst = RecipeUtil.readBlockPredicate(id, json, "catalyst");
|
|
||||||
var byproducts = WeightedList.fromJson(json.getAsJsonArray("byproducts"), element -> {
|
|
||||||
if (element.isJsonPrimitive()) {
|
|
||||||
return RecipeUtil.parseBlockState(element.getAsString());
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (catalyst == null) {
|
|
||||||
throw new JsonSyntaxException("Failed to read barrel fluid transformation recipe catalyst");
|
|
||||||
}
|
|
||||||
if (byproducts == null) {
|
|
||||||
throw new JsonSyntaxException("Failed to read barrel fluid transformation recipe byproducts");
|
|
||||||
}
|
|
||||||
return new FluidTransformationRecipe(id, baseFluid, resultFluid, resultColor, catalyst, byproducts, duration);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toNetwork(FriendlyByteBuf buffer, FluidTransformationRecipe recipe) {
|
public void toNetwork(FriendlyByteBuf buffer, FluidTransformationRecipe recipe) {
|
||||||
buffer.writeRegistryId(ForgeRegistries.FLUIDS, recipe.baseFluid);
|
buffer.writeId(BuiltInRegistries.FLUID, recipe.baseFluid);
|
||||||
buffer.writeRegistryId(ForgeRegistries.FLUIDS, recipe.resultFluid);
|
buffer.writeId(BuiltInRegistries.FLUID, recipe.resultFluid);
|
||||||
buffer.writeInt(recipe.resultColor);
|
buffer.writeInt(recipe.resultColor);
|
||||||
recipe.catalyst.toNetwork(buffer);
|
recipe.catalyst.toNetwork(buffer);
|
||||||
recipe.byproducts.toNetwork(buffer, (buf, state) -> buf.writeId(Block.BLOCK_STATE_REGISTRY, state));
|
recipe.byproducts.toNetwork(buffer, (buf, state) -> buf.writeId(Block.BLOCK_STATE_REGISTRY, state));
|
||||||
|
|
@ -136,30 +106,15 @@ public class FluidTransformationRecipe implements Recipe<Container> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable FluidTransformationRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf buffer) {
|
public FluidTransformationRecipe fromNetwork(FriendlyByteBuf buffer) {
|
||||||
Fluid baseFluid = buffer.readRegistryId();
|
Fluid baseFluid = Objects.requireNonNull(buffer.readById(BuiltInRegistries.FLUID));
|
||||||
Fluid resultFluid = buffer.readRegistryId();
|
Fluid resultFluid = Objects.requireNonNull(buffer.readById(BuiltInRegistries.FLUID));
|
||||||
int resultColor = buffer.readInt();
|
int resultColor = buffer.readInt();
|
||||||
BlockPredicate catalyst = RecipeUtil.readBlockPredicateNetwork(id, buffer);
|
BlockPredicate catalyst = RecipeUtil.readBlockPredicateNetwork(buffer);
|
||||||
if (catalyst == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
WeightedList<BlockState> byproducts = WeightedList.fromNetwork(buffer, buf -> buf.readById(Block.BLOCK_STATE_REGISTRY));
|
WeightedList<BlockState> byproducts = WeightedList.fromNetwork(buffer, buf -> buf.readById(Block.BLOCK_STATE_REGISTRY));
|
||||||
int duration = buffer.readVarInt();
|
int duration = buffer.readVarInt();
|
||||||
return new FluidTransformationRecipe(id, baseFluid, resultFluid, resultColor, catalyst, byproducts, duration);
|
return new FluidTransformationRecipe(baseFluid, resultFluid, resultColor, catalyst, byproducts, duration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
FluidTransformationRecipe that = (FluidTransformationRecipe) o;
|
|
||||||
return this.resultColor == that.resultColor && this.duration == that.duration && Objects.equals(this.id, that.id) && Objects.equals(this.baseFluid, that.baseFluid) && Objects.equals(this.resultFluid, that.resultFluid) && Objects.equals(this.catalyst, that.catalyst) && Objects.equals(this.byproducts, that.byproducts);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(this.id, this.baseFluid, this.resultFluid, this.resultColor, this.catalyst, this.byproducts, this.duration);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,8 +52,9 @@ public class BarrelFluidMixingRecipeCache {
|
||||||
private void buildRecipes() {
|
private void buildRecipes() {
|
||||||
this.recipes = new HashMap<>();
|
this.recipes = new HashMap<>();
|
||||||
|
|
||||||
for (var recipe : this.recipeManager.byType(ERecipeTypes.BARREL_FLUID_MIXING.get()).values()) {
|
for (var holder : this.recipeManager.byType(ERecipeTypes.BARREL_FLUID_MIXING.get()).values()) {
|
||||||
this.recipes.computeIfAbsent(recipe.baseFluid, key -> new HashMap<>()).put(recipe.additiveFluid, recipe);
|
var recipe = holder.value();
|
||||||
|
this.recipes.computeIfAbsent(recipe.baseFluid(), key -> new HashMap<>()).put(recipe.additiveFluid(), recipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.recipeManager = null;
|
this.recipeManager = null;
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,8 @@ public class CrookRecipeCache {
|
||||||
var tempRecipes = new HashMap<BlockState, HashSet<CrookRecipe>>();
|
var tempRecipes = new HashMap<BlockState, HashSet<CrookRecipe>>();
|
||||||
|
|
||||||
for (var recipe : this.recipeManager.byType(ERecipeTypes.CROOK.get()).values()) {
|
for (var recipe : this.recipeManager.byType(ERecipeTypes.CROOK.get()).values()) {
|
||||||
recipe.blockPredicate().possibleStates().forEach(state -> {
|
recipe.value().blockPredicate().possibleStates().forEach(state -> {
|
||||||
tempRecipes.computeIfAbsent(state, key -> new HashSet<>()).add(recipe);
|
tempRecipes.computeIfAbsent(state, key -> new HashSet<>()).add(recipe.value());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// map equal sets to a single list object instead of using a bunch of duplicate sets
|
// map equal sets to a single list object instead of using a bunch of duplicate sets
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,9 @@ public class CrucibleHeatRecipeCache {
|
||||||
private void buildRecipes() {
|
private void buildRecipes() {
|
||||||
this.recipes = new Object2IntOpenHashMap<>();
|
this.recipes = new Object2IntOpenHashMap<>();
|
||||||
|
|
||||||
for (var recipe : this.recipeManager.byType(ERecipeTypes.CRUCIBLE_HEAT_SOURCE.get()).values()) {
|
for (var holder : this.recipeManager.byType(ERecipeTypes.CRUCIBLE_HEAT_SOURCE.get()).values()) {
|
||||||
recipe.blockPredicate().possibleStates().forEach(state -> recipes.put(state, recipe.heatValue()));
|
var recipe = holder.value();
|
||||||
|
recipe.blockPredicate().possibleStates().forEach(state -> this.recipes.put(state, recipe.heatValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.recipeManager = null;
|
this.recipeManager = null;
|
||||||
|
|
|
||||||
|
|
@ -52,9 +52,10 @@ public class FluidTransformationRecipeCache {
|
||||||
private void buildRecipes() {
|
private void buildRecipes() {
|
||||||
this.recipes = new HashMap<>();
|
this.recipes = new HashMap<>();
|
||||||
|
|
||||||
for (var recipe : this.recipeManager.byType(ERecipeTypes.BARREL_FLUID_TRANSFORMATION.get()).values()) {
|
for (var holder : this.recipeManager.byType(ERecipeTypes.BARREL_FLUID_TRANSFORMATION.get()).values()) {
|
||||||
recipe.catalyst.possibleStates().forEach(state -> {
|
var recipe = holder.value();
|
||||||
this.recipes.computeIfAbsent(state, key -> new HashMap<>()).put(recipe.baseFluid, recipe);
|
recipe.catalyst().possibleStates().forEach(state -> {
|
||||||
|
this.recipes.computeIfAbsent(state, key -> new HashMap<>()).put(recipe.baseFluid(), recipe);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,8 @@ public class SieveRecipeCache {
|
||||||
private void buildRecipes() {
|
private void buildRecipes() {
|
||||||
// Group recipes based on their mesh
|
// Group recipes based on their mesh
|
||||||
var tempMap = new HashMap<Item, List<SieveRecipe>>();
|
var tempMap = new HashMap<Item, List<SieveRecipe>>();
|
||||||
for (var recipe : this.recipeManager.byType(ERecipeTypes.SIEVE.get()).values()) {
|
for (var holder : this.recipeManager.byType(ERecipeTypes.SIEVE.get()).values()) {
|
||||||
|
var recipe = holder.value();
|
||||||
tempMap.computeIfAbsent(recipe.mesh, k -> new ArrayList<>()).add(recipe);
|
tempMap.computeIfAbsent(recipe.mesh, k -> new ArrayList<>()).add(recipe);
|
||||||
}
|
}
|
||||||
this.meshCaches = new HashMap<>();
|
this.meshCaches = new HashMap<>();
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ package thedarkcolour.exdeorum.recipe.cache;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeHolder;
|
||||||
import net.minecraft.world.item.crafting.RecipeManager;
|
import net.minecraft.world.item.crafting.RecipeManager;
|
||||||
import net.minecraft.world.item.crafting.RecipeType;
|
import net.minecraft.world.item.crafting.RecipeType;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
@ -39,20 +40,12 @@ public class SingleIngredientRecipeCache<T extends SingleIngredientRecipe> {
|
||||||
private Map<Item, T> simpleRecipes;
|
private Map<Item, T> simpleRecipes;
|
||||||
@Nullable
|
@Nullable
|
||||||
private List<T> complexRecipes;
|
private List<T> complexRecipes;
|
||||||
@Nullable
|
|
||||||
private Collection<T> allRecipes;
|
|
||||||
private boolean trackAllRecipes;
|
|
||||||
|
|
||||||
public SingleIngredientRecipeCache(RecipeManager recipeManager, Supplier<RecipeType<T>> recipeType) {
|
public SingleIngredientRecipeCache(RecipeManager recipeManager, Supplier<RecipeType<T>> recipeType) {
|
||||||
this.recipeType = recipeType;
|
this.recipeType = recipeType;
|
||||||
this.recipeManager = recipeManager;
|
this.recipeManager = recipeManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SingleIngredientRecipeCache<T> trackAllRecipes() {
|
|
||||||
this.trackAllRecipes = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public T getRecipe(Item item) {
|
public T getRecipe(Item item) {
|
||||||
return getRecipe(new ItemStack(item));
|
return getRecipe(new ItemStack(item));
|
||||||
|
|
@ -81,21 +74,12 @@ public class SingleIngredientRecipeCache<T extends SingleIngredientRecipe> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<T> getAllRecipes() {
|
|
||||||
if (this.simpleRecipes == null) {
|
|
||||||
buildRecipes();
|
|
||||||
}
|
|
||||||
return this.allRecipes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when this recipe cache is first queried. First, scans available recipes for recipes with "simple"
|
* Called when this recipe cache is first queried. First, scans available recipes for recipes with "simple"
|
||||||
* ingredients that do not check an item's NBT. All of these recipes are added to the {@link #simpleRecipes}
|
* ingredients that do not check an item's NBT. All of these recipes are added to the {@link #simpleRecipes}
|
||||||
* map, which is indexed by the item(s) the recipe's ingredient accepts. Recipes whose ingredients are "complex"
|
* map, which is indexed by the item(s) the recipe's ingredient accepts. Recipes whose ingredients are "complex"
|
||||||
* and consider an item's NBT are added to the separate {@link #complexRecipes} list. Unlike simpleRecipes,
|
* and consider an item's NBT are added to the separate {@link #complexRecipes} list. Unlike simpleRecipes,
|
||||||
* complexRecipes may be null after this method call if no complex recipes are found. The {@link #allRecipes}
|
* complexRecipes may be null after this method call if no complex recipes are found. Finally, after all recipes
|
||||||
* field contains all recipes, simple and complex, in one collection. If this recipe cache is not set to track
|
|
||||||
* all recipes by {@link #trackAllRecipes}, then this list is discarded afterward. Finally, after all recipes
|
|
||||||
* have been scanned, the {@link #recipeManager} is set to null, since it is no longer needed.
|
* have been scanned, the {@link #recipeManager} is set to null, since it is no longer needed.
|
||||||
*/
|
*/
|
||||||
private void buildRecipes() {
|
private void buildRecipes() {
|
||||||
|
|
@ -104,7 +88,8 @@ public class SingleIngredientRecipeCache<T extends SingleIngredientRecipe> {
|
||||||
|
|
||||||
var allRecipes = this.recipeManager.byType(this.recipeType.get()).values();
|
var allRecipes = this.recipeManager.byType(this.recipeType.get()).values();
|
||||||
|
|
||||||
for (var recipe : allRecipes) {
|
for (var holder : allRecipes) {
|
||||||
|
var recipe = holder.value();
|
||||||
var ingredient = recipe.getIngredient();
|
var ingredient = recipe.getIngredient();
|
||||||
|
|
||||||
if (ingredient.isSimple()) {
|
if (ingredient.isSimple()) {
|
||||||
|
|
@ -120,10 +105,6 @@ public class SingleIngredientRecipeCache<T extends SingleIngredientRecipe> {
|
||||||
if (this.complexRecipes.isEmpty()) {
|
if (this.complexRecipes.isEmpty()) {
|
||||||
this.complexRecipes = null;
|
this.complexRecipes = null;
|
||||||
}
|
}
|
||||||
// Track list of simple and complex recipes (only used by hammer so far)
|
|
||||||
if (this.trackAllRecipes) {
|
|
||||||
this.allRecipes = allRecipes;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.recipeManager = null;
|
this.recipeManager = null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,25 +18,33 @@
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.recipe.crook;
|
package thedarkcolour.exdeorum.recipe.crook;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.world.Container;
|
import net.minecraft.world.Container;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.Items;
|
|
||||||
import net.minecraft.world.item.crafting.Recipe;
|
import net.minecraft.world.item.crafting.Recipe;
|
||||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||||
import net.minecraft.world.item.crafting.RecipeType;
|
import net.minecraft.world.item.crafting.RecipeType;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import thedarkcolour.exdeorum.recipe.BlockPredicate;
|
import thedarkcolour.exdeorum.recipe.BlockPredicate;
|
||||||
|
import thedarkcolour.exdeorum.recipe.CodecUtil;
|
||||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
||||||
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
||||||
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
||||||
|
|
||||||
public record CrookRecipe(ResourceLocation id, BlockPredicate blockPredicate, Item result, float chance) implements Recipe<Container> {
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public record CrookRecipe(BlockPredicate blockPredicate, Item result, float chance) implements Recipe<Container> {
|
||||||
|
public static final Codec<CrookRecipe> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||||
|
BlockPredicate.CODEC.fieldOf("block_predicate").forGetter(CrookRecipe::blockPredicate),
|
||||||
|
CodecUtil.itemField("result", CrookRecipe::result),
|
||||||
|
Codec.FLOAT.fieldOf("chance").forGetter(CrookRecipe::chance)
|
||||||
|
).apply(instance, CrookRecipe::new));
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(Container pContainer, Level pLevel) {
|
public boolean matches(Container pContainer, Level pLevel) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -57,11 +65,6 @@ public record CrookRecipe(ResourceLocation id, BlockPredicate blockPredicate, It
|
||||||
return new ItemStack(this.result);
|
return new ItemStack(this.result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RecipeSerializer<?> getSerializer() {
|
public RecipeSerializer<?> getSerializer() {
|
||||||
return ERecipeSerializers.CROOK.get();
|
return ERecipeSerializers.CROOK.get();
|
||||||
|
|
@ -72,32 +75,19 @@ public record CrookRecipe(ResourceLocation id, BlockPredicate blockPredicate, It
|
||||||
return ERecipeTypes.CROOK.get();
|
return ERecipeTypes.CROOK.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public static class Serializer implements RecipeSerializer<CrookRecipe> {
|
public static class Serializer implements RecipeSerializer<CrookRecipe> {
|
||||||
@Override
|
@Override
|
||||||
public CrookRecipe fromJson(ResourceLocation id, JsonObject json) {
|
public Codec<CrookRecipe> codec() {
|
||||||
BlockPredicate blockPredicate = RecipeUtil.readBlockPredicate(id, json, "block_predicate");
|
return CODEC;
|
||||||
if (blockPredicate == null) return null;
|
|
||||||
|
|
||||||
Item result = RecipeUtil.readItem(json, "result");
|
|
||||||
float chance = json.get("chance").getAsFloat();
|
|
||||||
|
|
||||||
|
|
||||||
return new CrookRecipe(id, blockPredicate, result, chance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CrookRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf buffer) {
|
public CrookRecipe fromNetwork(FriendlyByteBuf buffer) {
|
||||||
BlockPredicate blockPredicate = RecipeUtil.readBlockPredicateNetwork(id, buffer);
|
BlockPredicate blockPredicate = RecipeUtil.readBlockPredicateNetwork(buffer);
|
||||||
if (blockPredicate == null) return null;
|
Item result = Objects.requireNonNull(buffer.readById(BuiltInRegistries.ITEM));
|
||||||
|
|
||||||
Item result = buffer.readById(BuiltInRegistries.ITEM);
|
|
||||||
if (result == null || result == Items.AIR) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
float chance = buffer.readFloat();
|
float chance = buffer.readFloat();
|
||||||
|
|
||||||
return new CrookRecipe(id, blockPredicate, result, chance);
|
return new CrookRecipe(blockPredicate, result, chance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
/*
|
|
||||||
* Ex Deorum
|
|
||||||
* Copyright (c) 2024 thedarkcolour
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.recipe.crook;
|
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.world.item.Item;
|
|
||||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
|
||||||
import thedarkcolour.exdeorum.recipe.BlockPredicate;
|
|
||||||
import thedarkcolour.exdeorum.recipe.EFinishedRecipe;
|
|
||||||
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
|
||||||
|
|
||||||
public class FinishedCrookRecipe extends EFinishedRecipe {
|
|
||||||
private final BlockPredicate predicate;
|
|
||||||
private final Item result;
|
|
||||||
private final float chance;
|
|
||||||
|
|
||||||
public FinishedCrookRecipe(ResourceLocation id, BlockPredicate predicate, Item result, float chance) {
|
|
||||||
super(id);
|
|
||||||
this.predicate = predicate;
|
|
||||||
this.result = result;
|
|
||||||
this.chance = chance;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void serializeRecipeData(JsonObject json) {
|
|
||||||
json.add("block_predicate", this.predicate.toJson());
|
|
||||||
json.addProperty("result", BuiltInRegistries.ITEM.getKey(this.result).toString());
|
|
||||||
json.addProperty("chance", this.chance);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RecipeSerializer<?> getType() {
|
|
||||||
return ERecipeSerializers.CROOK.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -18,10 +18,10 @@
|
||||||
|
|
||||||
package thedarkcolour.exdeorum.recipe.crucible;
|
package thedarkcolour.exdeorum.recipe.crucible;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.world.Container;
|
import net.minecraft.world.Container;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.crafting.Recipe;
|
import net.minecraft.world.item.crafting.Recipe;
|
||||||
|
|
@ -33,7 +33,12 @@ import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
||||||
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
||||||
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
||||||
|
|
||||||
public record CrucibleHeatRecipe(ResourceLocation id, BlockPredicate blockPredicate, int heatValue) implements Recipe<Container> {
|
public record CrucibleHeatRecipe(BlockPredicate blockPredicate, int heatValue) implements Recipe<Container> {
|
||||||
|
public static final Codec<CrucibleHeatRecipe> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||||
|
BlockPredicate.CODEC.fieldOf("block_predicate").forGetter(CrucibleHeatRecipe::blockPredicate),
|
||||||
|
Codec.INT.fieldOf("heat_value").forGetter(CrucibleHeatRecipe::heatValue)
|
||||||
|
).apply(instance, CrucibleHeatRecipe::new));
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(Container pContainer, Level pLevel) {
|
public boolean matches(Container pContainer, Level pLevel) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -54,11 +59,6 @@ public record CrucibleHeatRecipe(ResourceLocation id, BlockPredicate blockPredic
|
||||||
return ItemStack.EMPTY;
|
return ItemStack.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getId() {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RecipeSerializer<?> getSerializer() {
|
public RecipeSerializer<?> getSerializer() {
|
||||||
return ERecipeSerializers.CRUCIBLE_HEAT_SOURCE.get();
|
return ERecipeSerializers.CRUCIBLE_HEAT_SOURCE.get();
|
||||||
|
|
@ -71,19 +71,15 @@ public record CrucibleHeatRecipe(ResourceLocation id, BlockPredicate blockPredic
|
||||||
|
|
||||||
public static class Serializer implements RecipeSerializer<CrucibleHeatRecipe> {
|
public static class Serializer implements RecipeSerializer<CrucibleHeatRecipe> {
|
||||||
@Override
|
@Override
|
||||||
public CrucibleHeatRecipe fromJson(ResourceLocation id, JsonObject json) {
|
public Codec<CrucibleHeatRecipe> codec() {
|
||||||
BlockPredicate blockPredicate = RecipeUtil.readBlockPredicate(id, json, "block_predicate");
|
return CODEC;
|
||||||
if (blockPredicate == null) return null;
|
|
||||||
int heatValue = json.get("heat_value").getAsInt();
|
|
||||||
return new CrucibleHeatRecipe(id, blockPredicate, heatValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CrucibleHeatRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf buffer) {
|
public CrucibleHeatRecipe fromNetwork(FriendlyByteBuf buffer) {
|
||||||
BlockPredicate blockPredicate = RecipeUtil.readBlockPredicateNetwork(id, buffer);
|
BlockPredicate blockPredicate = RecipeUtil.readBlockPredicateNetwork(buffer);
|
||||||
if (blockPredicate == null) return null;
|
|
||||||
int heatValue = buffer.readVarInt();
|
int heatValue = buffer.readVarInt();
|
||||||
return new CrucibleHeatRecipe(id, blockPredicate, heatValue);
|
return new CrucibleHeatRecipe(blockPredicate, heatValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user