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'
|
||||
}
|
||||
|
||||
version = '1.26'
|
||||
version = '2.0'
|
||||
group = 'thedarkcolour.exdeorum'
|
||||
base {
|
||||
archivesName = 'exdeorum'
|
||||
|
|
@ -103,18 +103,18 @@ dependencies {
|
|||
// JEI OPTIONAL
|
||||
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:${jei_version}")
|
||||
// REI OPTIONAL
|
||||
implementation("me.shedaniel:RoughlyEnoughItems-forge:${rei_version}")
|
||||
implementation("me.shedaniel.cloth:cloth-config-neoforge:${cloth_config_version}")
|
||||
implementation("curse.maven:reipc-521393:4837449")
|
||||
runtimeOnly("mezz.jei:jei-${mc_version}-neoforge:${jei_version}")
|
||||
// REI OPTIONAL todo add
|
||||
compileOnly("me.shedaniel:RoughlyEnoughItems-forge:${rei_version}")
|
||||
compileOnly("me.shedaniel.cloth:cloth-config-neoforge:${cloth_config_version}")
|
||||
//implementation("curse.maven:reipc-521393:4837449")
|
||||
// KubeJS OPTIONAL todo add when KubeJS updates
|
||||
//implementation("dev.architectury:architectury-neoforge:${architectury_version}")
|
||||
//implementation("dev.latvian.mods:rhino-neoforge:${rhino_version}")
|
||||
//implementation("dev.latvian.mods:kubejs-neoforge:${kubejs_version}")
|
||||
|
||||
// ModKit DEV ONLY
|
||||
implementation('com.github.thedarkcolour:Modkit:f4039e5b6b')
|
||||
implementation('com.github.thedarkcolour:Modkit:e9334176e0')
|
||||
|
||||
// Oculus + Embeddium OPTIONAL
|
||||
compileOnly('maven.modrinth:oculus:1.20.1-1.6.9')
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ org.gradle.jvmargs=-Xmx3G
|
|||
org.gradle.parallel=true
|
||||
|
||||
mc_version=1.20.4
|
||||
neo_version=20.4.80-beta
|
||||
neo_version=20.4.198
|
||||
neo_version_range=[20.4,)
|
||||
loader_version_range=[2,)
|
||||
|
||||
|
|
|
|||
|
|
@ -18,19 +18,22 @@
|
|||
|
||||
package thedarkcolour.exdeorum;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.common.ForgeMod;
|
||||
import net.minecraftforge.data.loading.DatagenModLoader;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import net.minecraftforge.fml.ModLoadingContext;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.bus.api.IEventBus;
|
||||
import net.neoforged.fml.ModList;
|
||||
import net.neoforged.fml.ModLoadingContext;
|
||||
import net.neoforged.fml.common.Mod;
|
||||
import net.neoforged.fml.config.ModConfig;
|
||||
import net.neoforged.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import net.neoforged.fml.loading.FMLEnvironment;
|
||||
import net.neoforged.neoforge.common.NeoForgeMod;
|
||||
import net.neoforged.neoforge.data.loading.DatagenModLoader;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import thedarkcolour.exdeorum.client.ClientHandler;
|
||||
import thedarkcolour.exdeorum.config.EConfig;
|
||||
import thedarkcolour.exdeorum.data.Data;
|
||||
import thedarkcolour.exdeorum.data.ModCompatData;
|
||||
import thedarkcolour.exdeorum.event.EventHandler;
|
||||
import thedarkcolour.exdeorum.material.DefaultMaterials;
|
||||
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 IS_JUNE = Calendar.getInstance().get(Calendar.MONTH) == Calendar.JUNE;
|
||||
|
||||
public ExDeorum() {
|
||||
createRegistries();
|
||||
NetworkHandler.register();
|
||||
public ExDeorum(IEventBus modBus) {
|
||||
createRegistries(modBus);
|
||||
|
||||
// Still enabled in Dev environment because KubeJS enables milk fluid
|
||||
if (DatagenModLoader.isRunningDataGen()) {
|
||||
ForgeMod.enableMilkFluid();
|
||||
NeoForgeMod.enableMilkFluid();
|
||||
ModCompatData.registerModData(modBus);
|
||||
modBus.addListener(Data::generateData);
|
||||
}
|
||||
|
||||
// Game Events
|
||||
EventHandler.register();
|
||||
// Client init
|
||||
DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> ClientHandlerRegistrar::register);
|
||||
EventHandler.register(modBus);
|
||||
// Client init (todo test that this doesn't crash servers)
|
||||
if (FMLEnvironment.dist == Dist.CLIENT) {
|
||||
ClientHandler.register(modBus);
|
||||
}
|
||||
// Config init
|
||||
ModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, EConfig.SERVER_SPEC);
|
||||
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, EConfig.COMMON_SPEC);
|
||||
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, EConfig.CLIENT_SPEC);
|
||||
}
|
||||
|
||||
private static void createRegistries() {
|
||||
var modBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||
|
||||
private static void createRegistries(IEventBus modBus) {
|
||||
EBlocks.BLOCKS.register(modBus);
|
||||
EBlockEntities.BLOCK_ENTITIES.register(modBus);
|
||||
EChunkGenerators.CHUNK_GENERATORS.register(modBus);
|
||||
|
|
@ -82,10 +86,4 @@ public class ExDeorum {
|
|||
ENumberProviders.NUMBER_PROVIDERS.register(modBus);
|
||||
DefaultMaterials.registerMaterials();
|
||||
}
|
||||
|
||||
private interface ClientHandlerRegistrar {
|
||||
private static void register() {
|
||||
ClientHandler.register();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import thedarkcolour.exdeorum.voidworld.VoidChunkGenerator;
|
|||
|
||||
import java.util.Properties;
|
||||
|
||||
// todo test that all of these patches still work properly
|
||||
@SuppressWarnings("unused")
|
||||
public final class ASMHooks {
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -45,9 +45,11 @@ public abstract class AbstractCrucibleBlock extends EBlock {
|
|||
|
||||
@Override
|
||||
public int getLightEmission(BlockState state, BlockGetter level, BlockPos pos) {
|
||||
if (level.getExistingBlockEntity(pos) instanceof AbstractCrucibleBlockEntity crucible) {
|
||||
return crucible.getTank().getFluid().getFluid().getFluidType().getLightLevel();
|
||||
}
|
||||
// todo look at auxiliary light manager
|
||||
//if (level.getBlockEntity(pos) instanceof AbstractCrucibleBlockEntity crucible) {
|
||||
// return crucible.getTank().getFluid().getFluid().getFluidType().getLightLevel();
|
||||
//}
|
||||
//return pos == BlockPos.ZERO ? 1 : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import net.minecraft.world.item.ItemStack;
|
|||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
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.EntityBlock;
|
||||
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) {
|
||||
if (player != null) {
|
||||
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
|
||||
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) {
|
||||
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.properties.BooleanProperty;
|
||||
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 thedarkcolour.exdeorum.blockentity.MechanicalHammerBlockEntity;
|
||||
import thedarkcolour.exdeorum.blockentity.MechanicalSieveBlockEntity;
|
||||
import thedarkcolour.exdeorum.config.EConfig;
|
||||
import thedarkcolour.exdeorum.data.TranslationKeys;
|
||||
import thedarkcolour.exdeorum.registry.EBlockEntities;
|
||||
|
|
@ -88,7 +87,7 @@ public class MechanicalHammerBlock extends EBlock {
|
|||
}
|
||||
|
||||
@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.getBlockEntity(pos) instanceof MechanicalHammerBlockEntity sieve) {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ import net.minecraft.world.level.pathfinder.PathComputationType;
|
|||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import net.neoforged.neoforge.items.ItemStackHandler;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import thedarkcolour.exdeorum.blockentity.MechanicalSieveBlockEntity;
|
||||
import thedarkcolour.exdeorum.config.EConfig;
|
||||
|
|
@ -90,7 +90,7 @@ public class MechanicalSieveBlock extends EBlock {
|
|||
|
||||
// Drops the item for creative mode players
|
||||
@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.getBlockEntity(pos) instanceof MechanicalSieveBlockEntity sieve) {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ import net.minecraft.world.level.ServerLevelAccessor;
|
|||
import net.minecraft.world.level.block.LiquidBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.FlowingFluid;
|
||||
import net.minecraftforge.event.ForgeEventFactory;
|
||||
import net.neoforged.neoforge.event.EventHooks;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import thedarkcolour.exdeorum.config.EConfig;
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ public class WitchWaterBlock extends LiquidBlock {
|
|||
zombieVillager.setTradeOffers(villager.getOffers().createTag());
|
||||
zombieVillager.setVillagerXp(villager.getVillagerXp());
|
||||
|
||||
net.minecraftforge.event.ForgeEventFactory.onLivingConvert(villager, zombieVillager);
|
||||
EventHooks.onLivingConvert(villager, zombieVillager);
|
||||
|
||||
villager.discard();
|
||||
}
|
||||
|
|
@ -123,7 +123,7 @@ public class WitchWaterBlock extends LiquidBlock {
|
|||
if (newEntity != null) {
|
||||
var serverLevel = (ServerLevelAccessor) level;
|
||||
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());
|
||||
|
||||
if (entity.hasCustomName()) {
|
||||
|
|
@ -132,7 +132,7 @@ public class WitchWaterBlock extends LiquidBlock {
|
|||
}
|
||||
|
||||
newEntity.setPersistenceRequired();
|
||||
net.minecraftforge.event.ForgeEventFactory.onLivingConvert((LivingEntity) entity, newEntity);
|
||||
EventHooks.onLivingConvert((LivingEntity) entity, newEntity);
|
||||
serverLevel.addFreshEntityWithPassengers(newEntity);
|
||||
entity.discard();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
package thedarkcolour.exdeorum.blockentity;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
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.material.Fluid;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
||||
import net.minecraftforge.common.util.Lazy;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.FluidUtil;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
import net.minecraftforge.fluids.capability.templates.FluidTank;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||
import net.neoforged.neoforge.common.util.Lazy;
|
||||
import net.neoforged.neoforge.fluids.FluidStack;
|
||||
import net.neoforged.neoforge.fluids.FluidUtil;
|
||||
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
|
||||
import net.neoforged.neoforge.fluids.capability.templates.FluidTank;
|
||||
import net.neoforged.neoforge.items.IItemHandler;
|
||||
import net.neoforged.neoforge.items.ItemStackHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import thedarkcolour.exdeorum.blockentity.helper.FluidHelper;
|
||||
|
|
@ -61,7 +57,6 @@ import thedarkcolour.exdeorum.registry.EItems;
|
|||
import java.util.HashMap;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public abstract class AbstractCrucibleBlockEntity extends EBlockEntity {
|
||||
public static final Lazy<HashMap<Item, Block>> MELT_OVERRIDES = Lazy.concurrentOf(() -> {
|
||||
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.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
|
||||
private Block lastMelted;
|
||||
|
|
@ -88,35 +80,18 @@ public abstract class AbstractCrucibleBlockEntity extends EBlockEntity {
|
|||
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
|
||||
@Override
|
||||
public void saveAdditional(CompoundTag nbt) {
|
||||
super.saveAdditional(nbt);
|
||||
|
||||
nbt.put("Tank", this.tank.writeToNBT(new CompoundTag()));
|
||||
nbt.putString("LastMelted", ForgeRegistries.BLOCKS.getKey(this.lastMelted).toString());
|
||||
nbt.putString("Fluid", ForgeRegistries.FLUIDS.getKey(this.fluid).toString());
|
||||
if (this.lastMelted != null) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -125,8 +100,8 @@ public abstract class AbstractCrucibleBlockEntity extends EBlockEntity {
|
|||
super.load(nbt);
|
||||
|
||||
this.tank.readFromNBT(nbt.getCompound("Tank"));
|
||||
this.lastMelted = ForgeRegistries.BLOCKS.getValue(new ResourceLocation(nbt.getString("LastMelted")));
|
||||
this.fluid = ForgeRegistries.FLUIDS.getValue(new ResourceLocation(nbt.getString("Fluid")));
|
||||
this.lastMelted = BuiltInRegistries.BLOCK.get(new ResourceLocation(nbt.getString("LastMelted")));
|
||||
this.fluid = BuiltInRegistries.FLUID.get(new ResourceLocation(nbt.getString("Fluid")));
|
||||
this.solids = nbt.getShort("Solids");
|
||||
this.needsLightUpdate = true;
|
||||
}
|
||||
|
|
@ -156,7 +131,7 @@ public abstract class AbstractCrucibleBlockEntity extends EBlockEntity {
|
|||
public InteractionResult use(Level level, Player player, InteractionHand 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;
|
||||
}
|
||||
|
||||
|
|
@ -247,6 +222,10 @@ public abstract class AbstractCrucibleBlockEntity extends EBlockEntity {
|
|||
return this.tank;
|
||||
}
|
||||
|
||||
public IItemHandler getItem() {
|
||||
return this.item;
|
||||
}
|
||||
|
||||
public abstract Block getDefaultMeltBlock();
|
||||
|
||||
@Nullable
|
||||
|
|
@ -254,13 +233,6 @@ public abstract class AbstractCrucibleBlockEntity extends EBlockEntity {
|
|||
return this.lastMelted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRemoved() {
|
||||
this.itemHandler.invalidate();
|
||||
this.fluidHandler.invalidate();
|
||||
super.setRemoved();
|
||||
}
|
||||
|
||||
private static void addMeltOverrides(HashMap<Item, Block> overrides) {
|
||||
overrides.put(Items.OAK_SAPLING, Blocks.OAK_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.CRIMSON_NYLIUM_SPORES.get(), Blocks.CRIMSON_NYLIUM);
|
||||
|
||||
for (var sapling : ForgeRegistries.BLOCKS.getEntries()) {
|
||||
for (var sapling : BuiltInRegistries.BLOCK.entrySet()) {
|
||||
var item = sapling.getValue().asItem();
|
||||
|
||||
if (!overrides.containsKey(item)) {
|
||||
var key = sapling.getKey().location();
|
||||
|
||||
if (key.getPath().endsWith("sapling")) {
|
||||
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) {
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
package thedarkcolour.exdeorum.blockentity;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
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.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.energy.EnergyStorage;
|
||||
import net.minecraftforge.network.NetworkHooks;
|
||||
import net.neoforged.neoforge.energy.IEnergyStorage;
|
||||
import net.neoforged.neoforge.items.IItemHandler;
|
||||
import thedarkcolour.exdeorum.blockentity.helper.EnergyHelper;
|
||||
import thedarkcolour.exdeorum.blockentity.helper.ItemHelper;
|
||||
import thedarkcolour.exdeorum.client.screen.RedstoneControlWidget;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.function.Function;
|
||||
|
||||
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
|
||||
protected boolean hasRedstonePower;
|
||||
|
||||
private final LazyOptional<ItemHelper> capabilityInventory;
|
||||
private final LazyOptional<EnergyStorage> capabilityEnergy;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public AbstractMachineBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state, Function<M, ItemHelper> inventory, int maxEnergy) {
|
||||
super(type, pos, state);
|
||||
|
||||
this.inventory = inventory.apply((M) this);
|
||||
this.energy = new EnergyHelper(maxEnergy);
|
||||
|
||||
this.capabilityInventory = LazyOptional.of(() -> this.inventory);
|
||||
this.capabilityEnergy = LazyOptional.of(() -> this.energy);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -99,31 +88,10 @@ public abstract class AbstractMachineBlockEntity<M extends AbstractMachineBlockE
|
|||
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
|
||||
public InteractionResult use(Level level, Player player, InteractionHand hand) {
|
||||
if (player instanceof ServerPlayer serverPlayer) {
|
||||
NetworkHooks.openScreen(serverPlayer, this, buffer -> {
|
||||
serverPlayer.openMenu(this, buffer -> {
|
||||
buffer.writeBlockPos(getBlockPos());
|
||||
buffer.writeByte(this.redstoneMode);
|
||||
});
|
||||
|
|
@ -151,6 +119,14 @@ public abstract class AbstractMachineBlockEntity<M extends AbstractMachineBlockE
|
|||
|
||||
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> {
|
||||
@Override
|
||||
public void tick(Level level, BlockPos pos, BlockState state, M machine) {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
package thedarkcolour.exdeorum.blockentity;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
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.material.FlowingFluid;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
import net.minecraftforge.common.ForgeMod;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.FluidType;
|
||||
import net.minecraftforge.fluids.FluidUtil;
|
||||
import net.minecraftforge.fluids.IFluidTank;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||
import net.neoforged.neoforge.common.NeoForgeMod;
|
||||
import net.neoforged.neoforge.fluids.FluidStack;
|
||||
import net.neoforged.neoforge.fluids.FluidType;
|
||||
import net.neoforged.neoforge.fluids.FluidUtil;
|
||||
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
|
||||
import net.neoforged.neoforge.fluids.capability.templates.FluidTank;
|
||||
import net.neoforged.neoforge.items.IItemHandler;
|
||||
import net.neoforged.neoforge.items.ItemHandlerHelper;
|
||||
import net.neoforged.neoforge.items.ItemStackHandler;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import thedarkcolour.exdeorum.block.BarrelBlock;
|
||||
import thedarkcolour.exdeorum.blockentity.helper.FluidHelper;
|
||||
|
|
@ -84,33 +81,12 @@ public class BarrelBlockEntity extends EBlockEntity {
|
|||
@Nullable
|
||||
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) {
|
||||
super(EBlockEntities.BARREL.get(), pos, state);
|
||||
|
||||
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
|
||||
public void saveAdditional(CompoundTag nbt) {
|
||||
super.saveAdditional(nbt);
|
||||
|
|
@ -177,6 +153,7 @@ public class BarrelBlockEntity extends EBlockEntity {
|
|||
return this.compost <= 0 && this.item.getStackInSlot(0).isEmpty();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean hasFullWater() {
|
||||
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;
|
||||
}
|
||||
|
||||
private void spawnParticlesIfBurning() {
|
||||
private void spawnParticlesIfBurning(Level level) {
|
||||
if (isBurning()) {
|
||||
BlockPos pos = getBlockPos();
|
||||
int burnTicks = (int) (this.progress * 300);
|
||||
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
public IFluidTank getTank() {
|
||||
public FluidTank getTank() {
|
||||
return this.tank;
|
||||
}
|
||||
|
||||
|
|
@ -264,19 +241,18 @@ public class BarrelBlockEntity extends EBlockEntity {
|
|||
}
|
||||
|
||||
// Otherwise, mix the item's fluid into the barrel's fluid
|
||||
var itemFluidCapOptional = playerItem.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).resolve();
|
||||
if (itemFluidCapOptional.isPresent()) {
|
||||
var itemFluidCap = itemFluidCapOptional.get();
|
||||
var itemFluidCap = playerItem.getCapability(Capabilities.FluidHandler.ITEM);
|
||||
if (itemFluidCap != null) {
|
||||
var itemFluid = itemFluidCap.drain(1000, IFluidHandler.FluidAction.SIMULATE);
|
||||
BarrelFluidMixingRecipe recipe = RecipeUtil.getFluidMixingRecipe(this.tank.getFluid(), itemFluid.getFluid());
|
||||
|
||||
// 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) {
|
||||
this.tank.drain(recipe.baseFluidAmount, IFluidHandler.FluidAction.EXECUTE);
|
||||
setItem(new ItemStack(recipe.result));
|
||||
this.tank.drain(recipe.baseFluidAmount(), IFluidHandler.FluidAction.EXECUTE);
|
||||
setItem(new ItemStack(recipe.result()));
|
||||
|
||||
if (recipe.consumesAdditive) {
|
||||
if (recipe.consumesAdditive()) {
|
||||
itemFluidCap.drain(1000, IFluidHandler.FluidAction.EXECUTE);
|
||||
player.setItemInHand(hand, itemFluidCap.getContainer());
|
||||
}
|
||||
|
|
@ -443,14 +419,14 @@ public class BarrelBlockEntity extends EBlockEntity {
|
|||
if (recipe != null) {
|
||||
// If additive is not consumed, just craft
|
||||
// If additive is consumed, check that the additive can be consumed before crafting
|
||||
if (!recipe.consumesAdditive) {
|
||||
this.tank.drain(recipe.baseFluidAmount, IFluidHandler.FluidAction.EXECUTE);
|
||||
setItem(new ItemStack(recipe.result));
|
||||
if (!recipe.consumesAdditive()) {
|
||||
this.tank.drain(recipe.baseFluidAmount(), IFluidHandler.FluidAction.EXECUTE);
|
||||
setItem(new ItemStack(recipe.result()));
|
||||
} else if (aboveBlockState.getBlock() instanceof BucketPickup pickup) {
|
||||
// If something was picked up, we can craft
|
||||
if (!pickup.pickupBlock(this.level, abovePos, aboveBlockState).isEmpty()) {
|
||||
this.tank.drain(recipe.baseFluidAmount, IFluidHandler.FluidAction.EXECUTE);
|
||||
setItem(new ItemStack(recipe.result));
|
||||
if (!pickup.pickupBlock(null, this.level, abovePos, aboveBlockState).isEmpty()) {
|
||||
this.tank.drain(recipe.baseFluidAmount(), IFluidHandler.FluidAction.EXECUTE);
|
||||
setItem(new ItemStack(recipe.result()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -468,7 +444,7 @@ public class BarrelBlockEntity extends EBlockEntity {
|
|||
this.currentTransformRecipe = RecipeUtil.getFluidTransformationRecipe(this.tank.getFluid().getFluid(), belowState);
|
||||
|
||||
if (this.currentTransformRecipe != null) {
|
||||
var color = this.currentTransformRecipe.resultColor;
|
||||
var color = this.currentTransformRecipe.resultColor();
|
||||
this.r = (short) ((color >> 16) & 0xff);
|
||||
this.g = (short) ((color >> 8) & 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> {
|
||||
@Override
|
||||
public void tick(Level level, BlockPos pos, BlockState state, BarrelBlockEntity barrel) {
|
||||
|
|
@ -503,17 +483,17 @@ public class BarrelBlockEntity extends EBlockEntity {
|
|||
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)) {
|
||||
if (recipe.catalyst.test(level.getBlockState(cursor))) {
|
||||
if (recipe.catalyst().test(level.getBlockState(cursor))) {
|
||||
catalysts++;
|
||||
|
||||
if (!recipe.byproducts.isEmpty()) {
|
||||
if (!recipe.byproducts().isEmpty()) {
|
||||
var rand = level.random;
|
||||
|
||||
if (rand.nextInt(1500) == 0) {
|
||||
var above = cursor.above();
|
||||
|
||||
if (level.getBlockState(above).isAir()) {
|
||||
var byproduct = recipe.byproducts.getRandom(rand);
|
||||
var byproduct = recipe.byproducts().getRandom(rand);
|
||||
if (byproduct.canSurvive(level, above)) {
|
||||
level.setBlockAndUpdate(above, byproduct);
|
||||
}
|
||||
|
|
@ -526,7 +506,7 @@ public class BarrelBlockEntity extends EBlockEntity {
|
|||
if (catalysts == 0) {
|
||||
barrel.currentTransformRecipe = null;
|
||||
} else {
|
||||
barrel.progress += catalysts * (1.0f / barrel.currentTransformRecipe.duration);
|
||||
barrel.progress += catalysts * (1.0f / barrel.currentTransformRecipe.duration());
|
||||
if (barrel.progress >= 1.0f - Mth.EPSILON) {
|
||||
// Reset progress
|
||||
barrel.progress = 0.0f;
|
||||
|
|
@ -537,7 +517,7 @@ public class BarrelBlockEntity extends EBlockEntity {
|
|||
barrel.markUpdated();
|
||||
}
|
||||
} 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;
|
||||
// Leak water to create moss (only wooden barrels do this)
|
||||
if (state.ignitedByLava() && rand.nextInt(500) == 0) {
|
||||
|
|
@ -553,7 +533,7 @@ public class BarrelBlockEntity extends EBlockEntity {
|
|||
}
|
||||
}
|
||||
} 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.entity.BlockEntityTicker;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.client.model.data.ModelData;
|
||||
import net.minecraftforge.client.model.data.ModelProperty;
|
||||
import net.neoforged.neoforge.client.model.data.ModelData;
|
||||
import net.neoforged.neoforge.client.model.data.ModelProperty;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import thedarkcolour.exdeorum.block.InfestedLeavesBlock;
|
||||
import thedarkcolour.exdeorum.registry.EBlockEntities;
|
||||
import thedarkcolour.exdeorum.registry.EBlocks;
|
||||
|
||||
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 ModelProperty<BlockState> MIMIC_PROPERTY = new ModelProperty<>();
|
||||
|
||||
// A percentage of how much this leaf is infested
|
||||
// todo change this to a short between 0 and 16000
|
||||
private float progress;
|
||||
// value between 0 and 16000 representing infestation progress
|
||||
private short progress;
|
||||
// A timer that determines when this block should try to spread
|
||||
private int spreadTimer;
|
||||
// The state this block should render as
|
||||
|
|
@ -57,33 +59,33 @@ public class InfestedLeavesBlockEntity extends EBlockEntity {
|
|||
|
||||
@Override
|
||||
public void writeVisualData(FriendlyByteBuf buffer) {
|
||||
buffer.writeFloat(this.progress);
|
||||
buffer.writeShort(this.progress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readVisualData(FriendlyByteBuf buffer) {
|
||||
buffer.readFloat();
|
||||
buffer.readShort();
|
||||
}
|
||||
|
||||
// Attempt to convert a leaf block within 1 block radius around this block
|
||||
private void trySpread() {
|
||||
private void trySpread(Level level) {
|
||||
// Get random offset
|
||||
int x = this.level.random.nextInt(3) - 1;
|
||||
int y = this.level.random.nextInt(3) - 1;
|
||||
int z = this.level.random.nextInt(3) - 1;
|
||||
int x = level.random.nextInt(3) - 1;
|
||||
int y = level.random.nextInt(3) - 1;
|
||||
int z = level.random.nextInt(3) - 1;
|
||||
|
||||
// Get the block in the world
|
||||
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
|
||||
if (state.is(BlockTags.LEAVES) && state.getBlock() != EBlocks.INFESTED_LEAVES.get()) {
|
||||
// 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.PERSISTENT, state.getValue(LeavesBlock.PERSISTENT)),
|
||||
2);
|
||||
var te = this.level.getBlockEntity(targetPos);
|
||||
var te = level.getBlockEntity(targetPos);
|
||||
|
||||
// Set mimic state of other block
|
||||
if (te instanceof InfestedLeavesBlockEntity leaves) {
|
||||
|
|
@ -98,10 +100,9 @@ public class InfestedLeavesBlockEntity extends EBlockEntity {
|
|||
super.load(nbt);
|
||||
|
||||
// From PistonMovingBlockEntity
|
||||
@SuppressWarnings("deprecation")
|
||||
var holderLookup = this.level != null ? this.level.holderLookup(Registries.BLOCK) : BuiltInRegistries.BLOCK.asLookup();
|
||||
this.mimic = NbtUtils.readBlockState(holderLookup, nbt.getCompound("mimic"));
|
||||
this.progress = nbt.getFloat("progress");
|
||||
this.progress = nbt.getShort("progress");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -115,11 +116,11 @@ public class InfestedLeavesBlockEntity extends EBlockEntity {
|
|||
nbt.putFloat("progress", this.progress);
|
||||
}
|
||||
|
||||
public float getProgress() {
|
||||
public int getProgress() {
|
||||
return this.progress;
|
||||
}
|
||||
|
||||
public void setProgress(float progress) {
|
||||
public void setProgress(short progress) {
|
||||
this.progress = progress;
|
||||
}
|
||||
|
||||
|
|
@ -140,8 +141,8 @@ public class InfestedLeavesBlockEntity extends EBlockEntity {
|
|||
@Override
|
||||
public void tick(Level level, BlockPos pos, BlockState state, InfestedLeavesBlockEntity leaves) {
|
||||
// Do progress
|
||||
if (leaves.progress < 1.0f) {
|
||||
leaves.progress = Math.min(1.0f, leaves.progress + PROGRESS_INTERVAL);
|
||||
if (leaves.progress < MAX_PROGRESS) {
|
||||
leaves.progress = (short) Math.min(MAX_PROGRESS, leaves.progress + PROGRESS_INTERVAL);
|
||||
|
||||
if (leaves.progress == 1.0f) {
|
||||
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
|
||||
if (leaves.spreadTimer >= SPREAD_INTERVAL) {
|
||||
leaves.trySpread();
|
||||
leaves.trySpread(level);
|
||||
leaves.spreadTimer = level.random.nextInt(10);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import thedarkcolour.exdeorum.blockentity.helper.ItemHelper;
|
|||
import thedarkcolour.exdeorum.config.EConfig;
|
||||
import thedarkcolour.exdeorum.data.TranslationKeys;
|
||||
import thedarkcolour.exdeorum.loot.HammerLootModifier;
|
||||
import thedarkcolour.exdeorum.menu.MechanicalHammerMenu;
|
||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
||||
import thedarkcolour.exdeorum.recipe.hammer.HammerRecipe;
|
||||
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.item.ItemStack;
|
||||
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.logic.SieveLogic;
|
||||
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.level.Level;
|
||||
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.config.EConfig;
|
||||
import thedarkcolour.exdeorum.registry.EBlockEntities;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
package thedarkcolour.exdeorum.blockentity.helper;
|
||||
|
||||
import net.minecraftforge.energy.EnergyStorage;
|
||||
import net.neoforged.neoforge.energy.EnergyStorage;
|
||||
|
||||
public class EnergyHelper extends EnergyStorage {
|
||||
public EnergyHelper(int capacity) {
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@
|
|||
package thedarkcolour.exdeorum.blockentity.helper;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.capability.templates.FluidTank;
|
||||
import net.neoforged.neoforge.fluids.FluidStack;
|
||||
import net.neoforged.neoforge.fluids.capability.templates.FluidTank;
|
||||
|
||||
// Changed behavior from FluidTank:
|
||||
// - 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.item.ItemStack;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import net.minecraftforge.items.SlotItemHandler;
|
||||
import net.neoforged.neoforge.items.ItemStackHandler;
|
||||
import net.neoforged.neoforge.items.SlotItemHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
// Has same behavior as ItemStackHandler but is more customizable.
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ public class SieveLogic {
|
|||
|
||||
public void saveNbt(CompoundTag nbt) {
|
||||
if (!this.contents.isEmpty()) {
|
||||
nbt.put("contents", this.contents.serializeNBT());
|
||||
nbt.put("contents", this.contents.save(new CompoundTag()));
|
||||
}
|
||||
if (this.saveMesh && !this.mesh.isEmpty()) {
|
||||
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.vertex.DefaultVertexFormat;
|
||||
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.WorldCreationUiState;
|
||||
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.resources.ResourceLocation;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraftforge.client.event.ClientPlayerNetworkEvent;
|
||||
import net.minecraftforge.client.event.EntityRenderersEvent;
|
||||
import net.minecraftforge.client.event.ModelEvent;
|
||||
import net.minecraftforge.client.event.RegisterClientReloadListenersEvent;
|
||||
import net.minecraftforge.client.event.RegisterShadersEvent;
|
||||
import net.minecraftforge.client.event.ScreenEvent;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
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 net.neoforged.bus.api.IEventBus;
|
||||
import net.neoforged.fml.ModList;
|
||||
import net.neoforged.fml.event.config.ModConfigEvent;
|
||||
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
import net.neoforged.neoforge.client.event.*;
|
||||
import net.neoforged.neoforge.common.NeoForge;
|
||||
import net.neoforged.neoforge.event.TagsUpdatedEvent;
|
||||
import thedarkcolour.exdeorum.ExDeorum;
|
||||
import thedarkcolour.exdeorum.client.screen.MechanicalHammerScreen;
|
||||
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.
|
||||
public static boolean needsRecipeCacheRefresh;
|
||||
|
||||
public static void register() {
|
||||
var modBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||
var fmlBus = MinecraftForge.EVENT_BUS;
|
||||
public static void register(IEventBus modBus) {
|
||||
var fmlBus = NeoForge.EVENT_BUS;
|
||||
|
||||
modBus.addListener(ClientHandler::clientSetup);
|
||||
modBus.addListener(ClientHandler::registerMenuScreens);
|
||||
modBus.addListener(ClientHandler::registerRenderers);
|
||||
modBus.addListener(ClientHandler::registerShaders);
|
||||
modBus.addListener(ClientHandler::addClientReloadListeners);
|
||||
|
|
@ -99,11 +93,12 @@ public class ClientHandler {
|
|||
}
|
||||
|
||||
private static void clientSetup(FMLClientSetupEvent event) {
|
||||
event.enqueueWork(() -> {
|
||||
setRenderLayers();
|
||||
MenuScreens.register(EMenus.MECHANICAL_SIEVE.get(), MechanicalSieveScreen::new);
|
||||
MenuScreens.register(EMenus.MECHANICAL_HAMMER.get(), MechanicalHammerScreen::new);
|
||||
});
|
||||
event.enqueueWork(ClientHandler::setRenderLayers);
|
||||
}
|
||||
|
||||
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() {
|
||||
|
|
|
|||
|
|
@ -28,17 +28,17 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
|||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectSet;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.inventory.InventoryMenu;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.client.model.data.ModelData;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import net.minecraftforge.fml.loading.FMLEnvironment;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.fml.ModList;
|
||||
import net.neoforged.fml.loading.FMLEnvironment;
|
||||
import net.neoforged.neoforge.client.model.data.ModelData;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Vector3i;
|
||||
|
|
@ -54,11 +54,7 @@ import java.io.InputStreamReader;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
// 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
|
||||
image.downloadTexture(0, false);
|
||||
|
||||
for (var entry : ForgeRegistries.ITEMS.getEntries()) {
|
||||
var item = entry.getValue();
|
||||
for (var item : BuiltInRegistries.ITEM) {
|
||||
var model = Minecraft.getInstance().getItemRenderer().getItemModelShaper().getItemModel(item);
|
||||
|
||||
if (model != null) {
|
||||
|
|
@ -147,11 +142,12 @@ public class CompostColors {
|
|||
private static void loadModded() {
|
||||
var readMods = readModdedColorFiles();
|
||||
|
||||
for (var entry : ForgeRegistries.ITEMS.getEntries()) {
|
||||
var modid = entry.getKey().location().getNamespace();
|
||||
for (var entry : BuiltInRegistries.ITEM.entrySet()) {
|
||||
var key = entry.getKey().location();
|
||||
var modid = key.getNamespace();
|
||||
|
||||
if (!readMods.contains(modid)) {
|
||||
var id = entry.getKey().location().getPath();
|
||||
var id = key.getPath();
|
||||
var modFile = ModList.get().getModFileById(modid);
|
||||
if (modFile == null)
|
||||
continue;
|
||||
|
|
@ -209,8 +205,10 @@ public class CompostColors {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
var entries = COLORS.keySet().stream().sorted(Comparator.comparing(ForgeRegistries.ITEMS::getKey)).collect(Collectors.groupingBy(item -> ForgeRegistries.ITEMS.getKey(item).getNamespace()));
|
||||
// todo should i sort the registry before iterating it, or should I keep the sort here?
|
||||
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()) {
|
||||
if (!readMods.contains(entry.getKey())) {
|
||||
|
|
@ -317,11 +315,11 @@ public class CompostColors {
|
|||
var tokenizer = new StringTokenizer(line, ", #");
|
||||
try {
|
||||
var id = new ResourceLocation(modid, tokenizer.nextToken());
|
||||
var item = ForgeRegistries.ITEMS.getValue(id);
|
||||
var item = BuiltInRegistries.ITEM.get(id);
|
||||
String token = tokenizer.nextToken();
|
||||
var color = Integer.parseInt(token, 16);
|
||||
|
||||
if (item != null && item != Items.AIR) {
|
||||
if (item != Items.AIR) {
|
||||
readColors++;
|
||||
|
||||
COLORS.put(item, new Vector3i(
|
||||
|
|
@ -353,9 +351,8 @@ public class CompostColors {
|
|||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
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
|
||||
|
|
@ -370,13 +367,13 @@ public class CompostColors {
|
|||
try (var writer = new BufferedWriter(fileWriter)) {
|
||||
// sort file entries alphabetically
|
||||
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");
|
||||
|
||||
for (var item : alphabeticalItems) {
|
||||
if (COLORS.containsKey(item)) {
|
||||
writer.write(ForgeRegistries.ITEMS.getKey(item).getPath());
|
||||
writer.write(BuiltInRegistries.ITEM.getKey(item).getPath());
|
||||
writer.write(", #");
|
||||
var colorVec = COLORS.get(item);
|
||||
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);
|
||||
} 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;
|
||||
|
||||
// todo consider getting rid of this interface
|
||||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ import net.minecraft.client.renderer.texture.TextureAtlas;
|
|||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
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.levelgen.LegacyRandomSource;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions;
|
||||
import net.minecraftforge.client.model.CompositeModel;
|
||||
import net.minecraftforge.client.model.data.ModelData;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import org.joml.Matrix4f;
|
||||
import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions;
|
||||
import net.neoforged.neoforge.client.model.CompositeModel;
|
||||
import net.neoforged.neoforge.client.model.data.ModelData;
|
||||
import org.joml.Vector3f;
|
||||
import thedarkcolour.exdeorum.ExDeorum;
|
||||
import thedarkcolour.exdeorum.client.ter.SieveRenderer;
|
||||
|
|
@ -148,7 +147,7 @@ public class RenderUtil {
|
|||
}
|
||||
|
||||
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/"));
|
||||
// for stuff like azalea bush, retry to get the top texture
|
||||
if (isMissingTexture(sprite)) {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import net.minecraft.util.Mth;
|
|||
import net.minecraft.world.entity.player.Inventory;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import thedarkcolour.exdeorum.ExDeorum;
|
||||
import thedarkcolour.exdeorum.blockentity.MechanicalHammerMenu;
|
||||
import thedarkcolour.exdeorum.menu.MechanicalHammerMenu;
|
||||
import thedarkcolour.exdeorum.config.EConfig;
|
||||
import thedarkcolour.exdeorum.data.TranslationKeys;
|
||||
|
||||
|
|
@ -79,7 +79,7 @@ public class MechanicalHammerScreen extends AbstractContainerScreen<MechanicalHa
|
|||
|
||||
@Override
|
||||
public void render(GuiGraphics graphics, int mx, int my, float pPartialTick) {
|
||||
renderBackground(graphics);
|
||||
renderBackground(graphics, mx, my, pPartialTick);
|
||||
super.render(graphics, mx, my, pPartialTick);
|
||||
renderTooltip(graphics, mx, my);
|
||||
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ public class MechanicalSieveScreen extends AbstractContainerScreen<MechanicalSie
|
|||
|
||||
@Override
|
||||
public void render(GuiGraphics graphics, int mx, int my, float partialTicks) {
|
||||
renderBackground(graphics);
|
||||
renderBackground(graphics, mx, my, partialTicks);
|
||||
super.render(graphics, mx, my, partialTicks);
|
||||
renderTooltip(graphics, mx, my);
|
||||
|
||||
|
|
|
|||
|
|
@ -33,13 +33,13 @@ import net.minecraft.util.Mth;
|
|||
import net.minecraft.world.inventory.InventoryMenu;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.ItemDisplayContext;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraftforge.client.model.data.ModelData;
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
||||
import net.neoforged.neoforge.client.model.data.ModelData;
|
||||
import thedarkcolour.exdeorum.ExDeorum;
|
||||
import thedarkcolour.exdeorum.blockentity.BarrelBlockEntity;
|
||||
import thedarkcolour.exdeorum.client.RenderUtil;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class BarrelRenderer implements BlockEntityRenderer<BarrelBlockEntity> {
|
||||
public static final ResourceLocation COMPOST_DIRT_TEXTURE = new ResourceLocation(ExDeorum.ID, "block/compost_dirt");
|
||||
private final BlockRenderDispatcher blockRenderer;
|
||||
|
|
@ -63,6 +63,7 @@ public class BarrelRenderer implements BlockEntityRenderer<BarrelBlockEntity> {
|
|||
stack.translate(2 / 16f, 2 / 16f, 2 / 16f);
|
||||
stack.scale(12 / 16f, 12 / 16f, 12 / 16f);
|
||||
|
||||
//noinspection DataFlowIssue
|
||||
this.blockRenderer.renderSingleBlock(state, stack, buffers, light, overlay, ModelData.EMPTY, null);
|
||||
|
||||
stack.popPose();
|
||||
|
|
@ -74,37 +75,36 @@ public class BarrelRenderer implements BlockEntityRenderer<BarrelBlockEntity> {
|
|||
stack.popPose();
|
||||
}
|
||||
|
||||
barrel.getCapability(ForgeCapabilities.FLUID_HANDLER).ifPresent(tank -> {
|
||||
var fluidStack = tank.getFluidInTank(0);
|
||||
var tank = barrel.getTank();
|
||||
var fluidStack = tank.getFluidInTank(0);
|
||||
|
||||
if (!fluidStack.isEmpty()) { // Get texture
|
||||
var fluid = fluidStack.getFluid();
|
||||
var level = barrel.getLevel();
|
||||
var pos = barrel.getBlockPos();
|
||||
var percentage = fluidStack.getAmount() / 1000.0f;
|
||||
var y = Mth.lerp(percentage, 1.0f, 14.0f) / 16f;
|
||||
var inputFluidColor = RenderUtil.getFluidColor(fluid, level, pos);
|
||||
// Split into RGB components
|
||||
var r = (inputFluidColor >> 16) & 0xff;
|
||||
var g = (inputFluidColor >> 8) & 0xff;
|
||||
var b = inputFluidColor & 0xff;
|
||||
if (!fluidStack.isEmpty()) { // Get texture
|
||||
var fluid = fluidStack.getFluid();
|
||||
var level = Objects.requireNonNull(barrel.getLevel());
|
||||
var pos = barrel.getBlockPos();
|
||||
var percentage = fluidStack.getAmount() / 1000.0f;
|
||||
var y = Mth.lerp(percentage, 1.0f, 14.0f) / 16f;
|
||||
var inputFluidColor = RenderUtil.getFluidColor(fluid, level, pos);
|
||||
// Split into RGB components
|
||||
var r = (inputFluidColor >> 16) & 0xff;
|
||||
var g = (inputFluidColor >> 8) & 0xff;
|
||||
var b = inputFluidColor & 0xff;
|
||||
|
||||
if (barrel.isBrewing()) {
|
||||
float progress = barrel.progress;
|
||||
if (barrel.isBrewing()) {
|
||||
float progress = barrel.progress;
|
||||
|
||||
// Transition between water color and witch water color (200B41)
|
||||
r = (int) Mth.lerp(progress, r, barrel.r);
|
||||
g = (int) Mth.lerp(progress, g, barrel.g);
|
||||
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);
|
||||
}
|
||||
// Transition between water color and witch water color (200B41)
|
||||
r = (int) Mth.lerp(progress, r, barrel.r);
|
||||
g = (int) Mth.lerp(progress, g, barrel.g);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// render compost
|
||||
if (barrel.compost > 0) {
|
||||
|
|
@ -126,9 +126,9 @@ public class BarrelRenderer implements BlockEntityRenderer<BarrelBlockEntity> {
|
|||
}
|
||||
|
||||
// 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
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,51 +23,48 @@ import net.minecraft.client.Minecraft;
|
|||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
||||
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.client.RenderUtil;
|
||||
|
||||
public class CrucibleRenderer implements BlockEntityRenderer<AbstractCrucibleBlockEntity> {
|
||||
@Override
|
||||
public void render(AbstractCrucibleBlockEntity crucible, float partialTicks, PoseStack stack, MultiBufferSource buffers, int light, int overlay) {
|
||||
crucible.getCapability(ForgeCapabilities.FLUID_HANDLER).ifPresent(tank -> {
|
||||
var level = crucible.getLevel();
|
||||
if (level == null) return;
|
||||
var tank = crucible.getTank();
|
||||
var level = crucible.getLevel();
|
||||
if (level == null) return;
|
||||
|
||||
var fluidStack = tank.getFluidInTank(0);
|
||||
var fluidStack = tank.getFluidInTank(0);
|
||||
|
||||
// These are percentages
|
||||
var solids = (float) crucible.getSolids() / (float) AbstractCrucibleBlockEntity.MAX_SOLIDS;
|
||||
var liquid = (float) fluidStack.getAmount() / (float) tank.getTankCapacity(0);
|
||||
// These are percentages
|
||||
var solids = (float) crucible.getSolids() / (float) AbstractCrucibleBlockEntity.MAX_SOLIDS;
|
||||
var liquid = (float) fluidStack.getAmount() / (float) tank.getTankCapacity(0);
|
||||
|
||||
if (solids != 0 || liquid != 0) {
|
||||
var pos = crucible.getBlockPos();
|
||||
if (solids != 0 || liquid != 0) {
|
||||
var pos = crucible.getBlockPos();
|
||||
|
||||
if (liquid != 0) {
|
||||
var fluid = fluidStack.getFluid();
|
||||
var color = RenderUtil.getFluidColor(fluid, level, pos);
|
||||
float y = Mth.lerp(liquid, 4.0f, 14.0f) / 16f;
|
||||
if (liquid != 0) {
|
||||
var fluid = fluidStack.getFluid();
|
||||
var color = RenderUtil.getFluidColor(fluid, level, pos);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
|
||||
}
|
||||
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);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import net.minecraft.client.Minecraft;
|
|||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
||||
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.client.RenderUtil;
|
||||
import thedarkcolour.exdeorum.config.EConfig;
|
||||
|
|
@ -46,7 +46,7 @@ public class InfestedLeavesRenderer implements BlockEntityRenderer<InfestedLeave
|
|||
}
|
||||
|
||||
// Get infested percentage
|
||||
int progress = Math.min((int) (te.getProgress() * 16000), 16000);
|
||||
int progress = Math.min(te.getProgress(), 16000);
|
||||
// Render
|
||||
var model = mc.getBlockRenderer().getBlockModel(state);
|
||||
var pos = te.getBlockPos();
|
||||
|
|
|
|||
|
|
@ -59,7 +59,6 @@ public class SieveRenderer<T extends EBlockEntity & SieveLogic.Owner> implements
|
|||
if (MESH_TEXTURES.containsKey(meshItem)) {
|
||||
meshSprite = MESH_TEXTURES.get(meshItem);
|
||||
} else {
|
||||
@SuppressWarnings("deprecation")
|
||||
ResourceLocation registryName = BuiltInRegistries.ITEM.getKey(meshItem);
|
||||
ResourceLocation textureLoc = registryName.withPrefix("item/mesh/");
|
||||
meshSprite = RenderUtil.blockAtlas.getSprite(textureLoc);
|
||||
|
|
|
|||
|
|
@ -18,15 +18,25 @@
|
|||
|
||||
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.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.recipe.sieve.SieveRecipe;
|
||||
import thedarkcolour.exdeorum.registry.EItems;
|
||||
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
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) {
|
||||
List<Item> barrels = new ArrayList<>();
|
||||
for (var material : DefaultMaterials.BARRELS) {
|
||||
|
|
@ -72,7 +82,15 @@ public class CompatHelper {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
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.ImmutableList;
|
||||
import com.google.common.collect.Multimap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
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.NumberProvider;
|
||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
||||
import thedarkcolour.exdeorum.recipe.sieve.SieveRecipe;
|
||||
import thedarkcolour.exdeorum.registry.EItems;
|
||||
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
||||
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
|
||||
// Since no JEI code is used here, this can be reused for REI
|
||||
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() {
|
||||
maxSieveRows = 1;
|
||||
|
||||
// copy the list so we can do removals
|
||||
List<SieveRecipe> recipes = new ArrayList<>(Objects.requireNonNull(Minecraft.getInstance().level).getRecipeManager().getAllRecipesFor(ERecipeTypes.SIEVE.get()));
|
||||
var recipes = CompatUtil.collectAllRecipes(ERecipeTypes.SIEVE.value(), Function.identity());
|
||||
Multimap<Ingredient, SieveRecipe> ingredientGrouper = ArrayListMultimap.create();
|
||||
|
||||
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());
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
|
@ -109,7 +112,6 @@ public record GroupedSieveRecipe(Ingredient ingredient, ItemStack mesh, List<Res
|
|||
return jeiRecipes.build();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static int meshOrder(Item mesh) {
|
||||
if (mesh == EItems.STRING_MESH.get()) {
|
||||
return -5;
|
||||
|
|
|
|||
|
|
@ -26,9 +26,8 @@ import net.minecraft.resources.ResourceLocation;
|
|||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.neoforged.fml.ModList;
|
||||
import net.neoforged.neoforge.common.ModConfigSpec;
|
||||
import thedarkcolour.exdeorum.ExDeorum;
|
||||
import thedarkcolour.exdeorum.config.EConfig;
|
||||
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 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, ForgeConfigSpec.ConfigValue<String> config, Item defaultOre) {
|
||||
var item = ForgeRegistries.ITEMS.getValue(new ResourceLocation(config.get()));
|
||||
private static void putPreferredOre(TagKey<Item> tag, ModConfigSpec.ConfigValue<String> config, Item defaultOre) {
|
||||
var item = BuiltInRegistries.ITEM.get(new ResourceLocation(config.get()));
|
||||
|
||||
if (item == Items.AIR) {
|
||||
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);
|
||||
}
|
||||
|
|
@ -84,7 +82,6 @@ public class PreferredOres {
|
|||
* @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.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public static Item getPreferredOre(TagKey<Item> tag) {
|
||||
Item preferred = PREFERRED_ORE_ITEMS.get(tag);
|
||||
|
||||
|
|
@ -96,10 +93,10 @@ public class PreferredOres {
|
|||
if (collection.isEmpty()) {
|
||||
return Items.AIR;
|
||||
} 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?
|
||||
return collection.get(0).get();
|
||||
return collection.get(0).value();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -175,9 +172,9 @@ public class PreferredOres {
|
|||
|
||||
if (modId != null) {
|
||||
if (modId.equals(ModIds.FACTORIUM)) {
|
||||
return ForgeRegistries.ITEMS.getValue(new ResourceLocation(modId, "mat_" + path));
|
||||
return BuiltInRegistries.ITEM.get(new ResourceLocation(modId, "mat_" + path));
|
||||
} else {
|
||||
return ForgeRegistries.ITEMS.getValue(new ResourceLocation(modId, path));
|
||||
return BuiltInRegistries.ITEM.get(new ResourceLocation(modId, path));
|
||||
}
|
||||
} else {
|
||||
return Items.AIR;
|
||||
|
|
|
|||
|
|
@ -108,12 +108,12 @@ public abstract class BarrelMixingCategory<T> implements IRecipeCategory<T> {
|
|||
|
||||
@Override
|
||||
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);
|
||||
IRecipeSlotBuilder additiveSlot = builder.addSlot(RecipeIngredientRole.INPUT, 33, 1).addFluidStack(recipe.additiveFluid, 1000).setFluidRenderer(1000, false, 16, 16);
|
||||
if (recipe.consumesAdditive) {
|
||||
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);
|
||||
if (recipe.consumesAdditive()) {
|
||||
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
|
||||
|
|
@ -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) {
|
||||
super.draw(recipe, recipeSlotsView, graphics, mouseX, mouseY);
|
||||
|
||||
if (recipe.consumesAdditive) {
|
||||
if (recipe.consumesAdditive()) {
|
||||
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.math.Axis;
|
||||
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.IIngredientType;
|
||||
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.material.FluidState;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import net.neoforged.fml.ModList;
|
||||
import net.neoforged.neoforge.fluids.FluidStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
|
|
@ -194,31 +193,33 @@ class ClientJeiUtil {
|
|||
}
|
||||
|
||||
// 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())) {
|
||||
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) {
|
||||
recipesGui.show(focusFactory.createFocus(RecipeIngredientRole.OUTPUT, ingredient));
|
||||
} 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) {
|
||||
// input + catalyst
|
||||
recipesGui.show(List.of(focusFactory.createFocus(RecipeIngredientRole.INPUT, ingredient), focusFactory.createFocus(RecipeIngredientRole.CATALYST, ingredient)));
|
||||
} 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
|
||||
public static Component formatChance(double probability) {
|
||||
static Component formatChance(double probability) {
|
||||
var chance = FORMATTER.format(probability * 100);
|
||||
return Component.translatable(TranslationKeys.SIEVE_RECIPE_CHANCE, chance).withStyle(ChatFormatting.GRAY);
|
||||
}
|
||||
|
|
@ -239,6 +240,7 @@ class ClientJeiUtil {
|
|||
return 1;
|
||||
}
|
||||
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
@Override
|
||||
public LevelLightEngine getLightEngine() {
|
||||
return Minecraft.getInstance().level.getLightEngine();
|
||||
|
|
|
|||
|
|
@ -40,8 +40,8 @@ import net.minecraft.network.chat.Component;
|
|||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.client.RenderTypeHelper;
|
||||
import net.minecraftforge.client.model.data.ModelData;
|
||||
import net.neoforged.neoforge.client.RenderTypeHelper;
|
||||
import net.neoforged.neoforge.client.model.data.ModelData;
|
||||
import thedarkcolour.exdeorum.data.TranslationKeys;
|
||||
import thedarkcolour.exdeorum.registry.EBlocks;
|
||||
import thedarkcolour.exdeorum.registry.EItems;
|
||||
|
|
@ -124,7 +124,8 @@ public class CrookCategory implements IRecipeCategory<CrookJeiRecipe> {
|
|||
});
|
||||
} else {
|
||||
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.gson.JsonObject;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
|
||||
import mezz.jei.api.recipe.RecipeIngredientRole;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.advancements.critereon.StatePropertiesPredicate;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.network.chat.Component;
|
||||
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 org.jetbrains.annotations.Nullable;
|
||||
import thedarkcolour.exdeorum.recipe.BlockPredicate;
|
||||
import thedarkcolour.exdeorum.recipe.CodecUtil;
|
||||
import thedarkcolour.exdeorum.recipe.crook.CrookRecipe;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -99,7 +102,7 @@ public sealed abstract class CrookJeiRecipe {
|
|||
|
||||
ImmutableList.Builder<Component> requirements = ImmutableList.builder();
|
||||
if (predicate != null) {
|
||||
var json = predicate.properties().serializeToJson();
|
||||
var json = CodecUtil.encode(StatePropertiesPredicate.CODEC, predicate.properties());
|
||||
if (json instanceof JsonObject obj) {
|
||||
for (var entry : obj.entrySet()) {
|
||||
requirements.add(Component.literal(" " + entry.getKey() + "=" + entry.getValue().toString()).withStyle(ChatFormatting.GRAY));
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ final class CrucibleHeatSourceRecipe {
|
|||
@Nullable
|
||||
private final Object ingredient;
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
CrucibleHeatSourceRecipe(int meltRate, BlockState blockState, @Nullable IIngredientType ingredientType, @Nullable Object ingredient) {
|
||||
this.meltRate = meltRate;
|
||||
this.blockState = blockState;
|
||||
|
|
|
|||
|
|
@ -34,10 +34,10 @@ import mezz.jei.api.runtime.IIngredientManager;
|
|||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.TooltipFlag;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import thedarkcolour.exdeorum.data.TranslationKeys;
|
||||
import thedarkcolour.exdeorum.material.DefaultMaterials;
|
||||
|
||||
|
|
@ -88,7 +88,7 @@ class CrucibleHeatSourcesCategory implements IRecipeCategory<CrucibleHeatSourceR
|
|||
|
||||
@Override
|
||||
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());
|
||||
} else {
|
||||
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);
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
|
@ -111,12 +112,12 @@ class CrucibleHeatSourcesCategory implements IRecipeCategory<CrucibleHeatSourceR
|
|||
@Override
|
||||
public List<Component> getTooltipStrings(CrucibleHeatSourceRecipe recipe, IRecipeSlotsView recipeSlotsView, double mouseX, double mouseY) {
|
||||
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);
|
||||
return this.modIdHelper.addModNameToIngredientTooltip(tooltip, recipe.ingredient(), this.ingredientManager.getIngredientHelper(recipe.ingredientType()));
|
||||
} else {
|
||||
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)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@ import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
|||
import mezz.jei.api.IModPlugin;
|
||||
import mezz.jei.api.JeiPlugin;
|
||||
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.IGuiContainerHandler;
|
||||
import mezz.jei.api.neoforge.NeoForgeTypes;
|
||||
import mezz.jei.api.recipe.RecipeType;
|
||||
import mezz.jei.api.registration.IGuiHandlerRegistration;
|
||||
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.LiquidBlock;
|
||||
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.client.screen.MechanicalHammerScreen;
|
||||
import thedarkcolour.exdeorum.client.screen.MechanicalSieveScreen;
|
||||
import thedarkcolour.exdeorum.compat.CompatHelper;
|
||||
import thedarkcolour.exdeorum.compat.CompatUtil;
|
||||
import thedarkcolour.exdeorum.compat.GroupedSieveRecipe;
|
||||
import thedarkcolour.exdeorum.data.TranslationKeys;
|
||||
import thedarkcolour.exdeorum.item.WateringCanItem;
|
||||
|
|
@ -65,6 +65,7 @@ import java.util.ArrayList;
|
|||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@JeiPlugin
|
||||
|
|
@ -105,10 +106,10 @@ public class ExDeorumJeiPlugin implements IModPlugin {
|
|||
|
||||
@Override
|
||||
public void registerRecipeCatalysts(IRecipeCatalystRegistration registration) {
|
||||
var barrels = CompatHelper.getAvailableBarrels(true);
|
||||
var sieves = CompatHelper.getAvailableSieves(true, true);
|
||||
var lavaCrucibles = CompatHelper.getAvailableLavaCrucibles(true);
|
||||
var waterCrucibles = CompatHelper.getAvailableWaterCrucibles(true);
|
||||
var barrels = CompatUtil.getAvailableBarrels(true);
|
||||
var sieves = CompatUtil.getAvailableSieves(true, true);
|
||||
var lavaCrucibles = CompatUtil.getAvailableLavaCrucibles(true);
|
||||
var waterCrucibles = CompatUtil.getAvailableWaterCrucibles(true);
|
||||
|
||||
for (var barrel : barrels) {
|
||||
var stack = new ItemStack(barrel);
|
||||
|
|
@ -143,12 +144,12 @@ public class ExDeorumJeiPlugin implements IModPlugin {
|
|||
@Override
|
||||
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(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(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);
|
||||
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.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));
|
||||
|
|
@ -187,11 +188,7 @@ public class ExDeorumJeiPlugin implements IModPlugin {
|
|||
addRecipes(registration, LAVA_CRUCIBLE, ERecipeTypes.LAVA_CRUCIBLE);
|
||||
addRecipes(registration, WATER_CRUCIBLE, ERecipeTypes.WATER_CRUCIBLE);
|
||||
addRecipes(registration, HAMMER, ERecipeTypes.HAMMER);
|
||||
var crookRecipes = new ArrayList<CrookJeiRecipe>();
|
||||
for (var recipe : Objects.requireNonNull(Minecraft.getInstance().level).getRecipeManager().getAllRecipesFor(ERecipeTypes.CROOK.get())) {
|
||||
crookRecipes.add(CrookJeiRecipe.create(recipe));
|
||||
}
|
||||
registration.addRecipes(CROOK, crookRecipes);
|
||||
registration.addRecipes(CROOK, CompatUtil.collectAllRecipes(ERecipeTypes.CROOK.get(), CrookJeiRecipe::create));
|
||||
registration.addRecipes(SIEVE, GroupedSieveRecipe.getAllRecipesGrouped());
|
||||
|
||||
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) {
|
||||
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.NumberProvider;
|
||||
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.data.TranslationKeys;
|
||||
import thedarkcolour.exdeorum.loot.SummationGenerator;
|
||||
|
|
@ -110,14 +110,14 @@ class SieveCategory implements IRecipeCategory<GroupedSieveRecipe> {
|
|||
slot.setCustomRenderer(VanillaTypes.ITEM_STACK, ClientJeiUtil.AsteriskItemRenderer.INSTANCE);
|
||||
}
|
||||
if (provider instanceof BinomialDistributionGenerator binomial) {
|
||||
if (binomial.n instanceof ConstantValue constant && constant.value == 1) {
|
||||
var chanceLabel = ClientJeiUtil.formatChance(RecipeUtil.getExpectedValue(binomial.p));
|
||||
if (binomial.n() instanceof ConstantValue constant && constant.value() == 1) {
|
||||
var chanceLabel = ClientJeiUtil.formatChance(RecipeUtil.getExpectedValue(binomial.p()));
|
||||
tooltipLines.add(chanceLabel);
|
||||
} else {
|
||||
addAvgOutput(tooltipLines, RecipeUtil.getExpectedValue(provider));
|
||||
}
|
||||
|
||||
addMinMaxes(tooltipLines, 0, getMax(binomial.n));
|
||||
addMinMaxes(tooltipLines, 0, getMax(binomial.n()));
|
||||
} else if (provider.getClass() != ConstantValue.class) {
|
||||
var val = RecipeUtil.getExpectedValue(provider);
|
||||
if (val != -1.0) {
|
||||
|
|
@ -137,9 +137,9 @@ class SieveCategory implements IRecipeCategory<GroupedSieveRecipe> {
|
|||
|
||||
private static double getMin(NumberProvider provider) {
|
||||
if (provider instanceof ConstantValue value) {
|
||||
return value.value;
|
||||
return value.value();
|
||||
} else if (provider instanceof UniformGenerator uniform) {
|
||||
return getMin(uniform.min);
|
||||
return getMin(uniform.min());
|
||||
} else if (provider instanceof BinomialDistributionGenerator) {
|
||||
return 0;
|
||||
} else if (provider instanceof SummationGenerator summation) {
|
||||
|
|
@ -157,11 +157,11 @@ class SieveCategory implements IRecipeCategory<GroupedSieveRecipe> {
|
|||
|
||||
private static double getMax(NumberProvider provider) {
|
||||
if (provider instanceof ConstantValue value) {
|
||||
return value.value;
|
||||
return value.value();
|
||||
} else if (provider instanceof UniformGenerator uniform) {
|
||||
return getMax(uniform.max);
|
||||
return getMax(uniform.max());
|
||||
} else if (provider instanceof BinomialDistributionGenerator binomial) {
|
||||
return getMax(binomial.n);
|
||||
return getMax(binomial.n());
|
||||
} else if (provider instanceof SummationGenerator summation) {
|
||||
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.forge.REIPluginClient;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import thedarkcolour.exdeorum.compat.CompatHelper;
|
||||
import thedarkcolour.exdeorum.compat.CompatUtil;
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
@REIPluginClient
|
||||
|
|
@ -35,16 +35,16 @@ public class ExDeorumReiPlugin implements REIClientPlugin {
|
|||
rule.hide(() -> {
|
||||
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)));
|
||||
}
|
||||
for (var sieve : CompatHelper.getAvailableSieves(false, false)) {
|
||||
for (var sieve : CompatUtil.getAvailableSieves(false, false)) {
|
||||
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)));
|
||||
}
|
||||
for (var crucible : CompatHelper.getAvailableWaterCrucibles(false)) {
|
||||
for (var crucible : CompatUtil.getAvailableWaterCrucibles(false)) {
|
||||
builder.add(EntryStack.of(VanillaEntryTypes.ITEM, new ItemStack(crucible)));
|
||||
}
|
||||
return builder.build();
|
||||
|
|
|
|||
|
|
@ -19,11 +19,11 @@
|
|||
package thedarkcolour.exdeorum.config;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
import net.minecraftforge.common.ForgeConfigSpec.BooleanValue;
|
||||
import net.minecraftforge.common.ForgeConfigSpec.ConfigValue;
|
||||
import net.minecraftforge.common.ForgeConfigSpec.DoubleValue;
|
||||
import net.minecraftforge.common.ForgeConfigSpec.IntValue;
|
||||
import net.neoforged.neoforge.common.ModConfigSpec;
|
||||
import net.neoforged.neoforge.common.ModConfigSpec.BooleanValue;
|
||||
import net.neoforged.neoforge.common.ModConfigSpec.ConfigValue;
|
||||
import net.neoforged.neoforge.common.ModConfigSpec.IntValue;
|
||||
import net.neoforged.neoforge.common.ModConfigSpec.DoubleValue;
|
||||
import org.apache.commons.lang3.text.WordUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import thedarkcolour.exdeorum.compat.ModIds;
|
||||
|
|
@ -31,9 +31,9 @@ import thedarkcolour.exdeorum.compat.ModIds;
|
|||
import java.util.List;
|
||||
|
||||
public class EConfig {
|
||||
public static final ForgeConfigSpec CLIENT_SPEC;
|
||||
public static final ForgeConfigSpec COMMON_SPEC;
|
||||
public static final ForgeConfigSpec SERVER_SPEC;
|
||||
public static final ModConfigSpec CLIENT_SPEC;
|
||||
public static final ModConfigSpec COMMON_SPEC;
|
||||
public static final ModConfigSpec SERVER_SPEC;
|
||||
public static final Client CLIENT;
|
||||
public static final Common COMMON;
|
||||
public static final Server SERVER;
|
||||
|
|
@ -42,7 +42,7 @@ public class EConfig {
|
|||
public final BooleanValue useFastInfestedLeaves;
|
||||
public final BooleanValue setVoidWorldAsDefault;
|
||||
|
||||
public Client(ForgeConfigSpec.Builder builder) {
|
||||
public Client(ModConfigSpec.Builder builder) {
|
||||
builder.comment("Client configuration for Ex Deorum").push("client");
|
||||
|
||||
this.useFastInfestedLeaves = builder
|
||||
|
|
@ -78,7 +78,7 @@ public class EConfig {
|
|||
public final BooleanValue voidNetherGeneration;
|
||||
public final BooleanValue voidEndGeneration;
|
||||
|
||||
public Common(ForgeConfigSpec.Builder builder) {
|
||||
public Common(ModConfigSpec.Builder builder) {
|
||||
// Preferred items
|
||||
builder.comment("Common configuration for Ex Deorum").push("common");
|
||||
|
||||
|
|
@ -138,7 +138,7 @@ public class EConfig {
|
|||
public final IntValue mechanicalHammerEnergyConsumption;
|
||||
public final IntValue sieveIntervalTicks;
|
||||
|
||||
public Server(ForgeConfigSpec.Builder builder) {
|
||||
public Server(ModConfigSpec.Builder builder) {
|
||||
builder.comment("Server configuration for Ex Deorum").push("server");
|
||||
|
||||
this.startingTorch = builder
|
||||
|
|
@ -200,7 +200,7 @@ public class EConfig {
|
|||
}
|
||||
|
||||
@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
|
||||
.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));
|
||||
|
|
@ -208,17 +208,17 @@ public class EConfig {
|
|||
|
||||
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_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_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_SPEC = specPair.getRight();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,16 +18,17 @@
|
|||
|
||||
package thedarkcolour.exdeorum.data;
|
||||
|
||||
import net.minecraft.advancements.Advancement;
|
||||
import net.minecraft.advancements.FrameType;
|
||||
import net.minecraft.advancements.AdvancementHolder;
|
||||
import net.minecraft.advancements.AdvancementType;
|
||||
import net.minecraft.advancements.CriteriaTriggers;
|
||||
import net.minecraft.advancements.critereon.ImpossibleTrigger;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||
import net.minecraftforge.common.data.ForgeAdvancementProvider;
|
||||
import net.neoforged.neoforge.common.data.AdvancementProvider;
|
||||
import net.neoforged.neoforge.common.data.ExistingFileHelper;
|
||||
import thedarkcolour.exdeorum.ExDeorum;
|
||||
import thedarkcolour.exdeorum.material.DefaultMaterials;
|
||||
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.ItemPredicate.Builder.item;
|
||||
|
||||
class Advancements extends ForgeAdvancementProvider {
|
||||
class Advancements extends AdvancementProvider {
|
||||
public Advancements(PackOutput output, CompletableFuture<HolderLookup.Provider> registries, ExistingFileHelper existingFileHelper) {
|
||||
super(output, registries, existingFileHelper, List.of(new CoreAchievements()));
|
||||
}
|
||||
|
|
@ -52,20 +53,20 @@ class Advancements extends ForgeAdvancementProvider {
|
|||
|
||||
public static class CoreAchievements implements AdvancementGenerator {
|
||||
@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()
|
||||
.display(
|
||||
Blocks.OAK_SAPLING,
|
||||
Component.translatable(TranslationKeys.ROOT_ADVANCEMENT_TITLE),
|
||||
Component.translatable(TranslationKeys.ROOT_ADVANCEMENT_DESCRIPTION),
|
||||
modLoc("textures/gui/advancements/backgrounds/void.png"),
|
||||
FrameType.TASK,
|
||||
AdvancementType.TASK,
|
||||
true,
|
||||
true,
|
||||
false
|
||||
)
|
||||
// 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);
|
||||
var crook = advancement()
|
||||
.parent(root)
|
||||
|
|
@ -74,7 +75,7 @@ class Advancements extends ForgeAdvancementProvider {
|
|||
Component.translatable(TranslationKeys.CROOK_ADVANCEMENT_TITLE),
|
||||
Component.translatable(TranslationKeys.CROOK_ADVANCEMENT_DESCRIPTION),
|
||||
null,
|
||||
FrameType.TASK,
|
||||
AdvancementType.TASK,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
|
|
@ -88,7 +89,7 @@ class Advancements extends ForgeAdvancementProvider {
|
|||
Component.translatable(TranslationKeys.BARREL_ADVANCEMENT_TITLE),
|
||||
Component.translatable(TranslationKeys.BARREL_ADVANCEMENT_DESCRIPTION),
|
||||
null,
|
||||
FrameType.TASK,
|
||||
AdvancementType.TASK,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
|
|
@ -102,7 +103,7 @@ class Advancements extends ForgeAdvancementProvider {
|
|||
Component.translatable(TranslationKeys.SILK_WORM_ADVANCEMENT_TITLE),
|
||||
Component.translatable(TranslationKeys.SILK_WORM_ADVANCEMENT_DESCRIPTION),
|
||||
null,
|
||||
FrameType.TASK,
|
||||
AdvancementType.TASK,
|
||||
true,
|
||||
true,
|
||||
false
|
||||
|
|
@ -116,7 +117,7 @@ class Advancements extends ForgeAdvancementProvider {
|
|||
Component.translatable(TranslationKeys.STRING_MESH_ADVANCEMENT_TITLE),
|
||||
Component.translatable(TranslationKeys.STRING_MESH_ADVANCEMENT_DESCRIPTION),
|
||||
null,
|
||||
FrameType.TASK,
|
||||
AdvancementType.TASK,
|
||||
true,
|
||||
true,
|
||||
false
|
||||
|
|
|
|||
|
|
@ -18,12 +18,12 @@
|
|||
|
||||
package thedarkcolour.exdeorum.data;
|
||||
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraftforge.client.model.generators.BlockModelBuilder;
|
||||
import net.minecraftforge.client.model.generators.ConfiguredModel;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.neoforged.neoforge.client.model.generators.BlockModelBuilder;
|
||||
import net.neoforged.neoforge.client.model.generators.ConfiguredModel;
|
||||
import thedarkcolour.exdeorum.material.DefaultMaterials;
|
||||
import thedarkcolour.exdeorum.registry.EBlocks;
|
||||
import thedarkcolour.modkit.data.MKBlockModelProvider;
|
||||
|
|
@ -196,7 +196,7 @@ class BlockModels {
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,8 @@
|
|||
package thedarkcolour.exdeorum.data;
|
||||
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraftforge.data.event.GatherDataEvent;
|
||||
import net.minecraftforge.data.loading.DatagenModLoader;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.neoforged.fml.common.Mod;
|
||||
import net.neoforged.neoforge.data.event.GatherDataEvent;
|
||||
import thedarkcolour.exdeorum.ExDeorum;
|
||||
import thedarkcolour.exdeorum.data.recipe.Recipes;
|
||||
import thedarkcolour.modkit.data.DataHelper;
|
||||
|
|
@ -30,13 +28,6 @@ import thedarkcolour.modkit.data.DataHelper;
|
|||
// these two annotations are equivalent to modEventBus.addListener(Data::generateData)
|
||||
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
|
||||
public class Data {
|
||||
static {
|
||||
if (DatagenModLoader.isRunningDataGen()) {
|
||||
ModCompatData.registerModData();
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void generateData(GatherDataEvent event) {
|
||||
// Two things used by data generators
|
||||
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.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraftforge.data.loading.DatagenModLoader;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import net.minecraftforge.registries.DeferredRegister;
|
||||
import net.minecraftforge.registries.RegistryObject;
|
||||
import net.neoforged.bus.api.IEventBus;
|
||||
import net.neoforged.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import net.neoforged.neoforge.data.loading.DatagenModLoader;
|
||||
import net.neoforged.neoforge.registries.DeferredBlock;
|
||||
import net.neoforged.neoforge.registries.DeferredItem;
|
||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||
import thedarkcolour.exdeorum.compat.ModIds;
|
||||
|
||||
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.
|
||||
public class ModCompatData {
|
||||
// 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<Block>> blockRegistries = new HashMap<>();
|
||||
private static final Map<String, DeferredRegister.Items> itemRegistries = new HashMap<>();
|
||||
private static final Map<String, DeferredRegister.Blocks> blockRegistries = new HashMap<>();
|
||||
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
private static RegistryObject<Item> item(String modid, String name) {
|
||||
private static DeferredItem<Item> item(String modid, String name) {
|
||||
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()));
|
||||
} else {
|
||||
return null;
|
||||
|
|
@ -49,9 +51,9 @@ public class ModCompatData {
|
|||
}
|
||||
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
private static RegistryObject<Block> block(String modid, String name) {
|
||||
private static DeferredBlock<Block> block(String modid, String name) {
|
||||
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()));
|
||||
} else {
|
||||
return null;
|
||||
|
|
@ -59,13 +61,13 @@ public class ModCompatData {
|
|||
}
|
||||
|
||||
// Ender IO
|
||||
public static final RegistryObject<Item>
|
||||
public static final DeferredItem<Item>
|
||||
GRAINS_OF_INFINITY = item(ModIds.ENDERIO, "grains_of_infinity");
|
||||
// Bigger reactors
|
||||
public static final RegistryObject<Item>
|
||||
public static final DeferredItem<Item>
|
||||
YELLORIUM_DUST = item(ModIds.BIGGER_REACTORS, "yellorium_dust");
|
||||
// Biomes O' Plenty
|
||||
public static final RegistryObject<Block>
|
||||
public static final DeferredBlock<Block>
|
||||
FIR_PLANKS = block(ModIds.BIOMES_O_PLENTY, "fir_planks"),
|
||||
REDWOOD_PLANKS = block(ModIds.BIOMES_O_PLENTY, "redwood_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"),
|
||||
UMBRAN_LOG = block(ModIds.BIOMES_O_PLENTY, "umbran_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"),
|
||||
REDWOOD_PLANKS_ITEM = item(ModIds.BIOMES_O_PLENTY, "redwood_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"),
|
||||
HELLBARK_SAPLING = item(ModIds.BIOMES_O_PLENTY, "hellbark_sapling");
|
||||
// Applied Energistics 2
|
||||
public static final RegistryObject<Item>
|
||||
public static final DeferredItem<Item>
|
||||
CERTUS_QUARTZ_CRYSTAL = item(ModIds.APPLIED_ENERGISTICS_2, "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"),
|
||||
SKY_STONE_DUST = item(ModIds.APPLIED_ENERGISTICS_2, "sky_dust");
|
||||
// Ars Nouveau
|
||||
public static final RegistryObject<Block>
|
||||
public static final DeferredBlock<Block>
|
||||
CASCADING_ARCHWOOD_LOG = block(ModIds.ARS_NOUVEAU, "blue_archwood_log"),
|
||||
BLAZING_ARCHWOOD_LOG = block(ModIds.ARS_NOUVEAU, "red_archwood_log"),
|
||||
VEXING_ARCHWOOD_LOG = block(ModIds.ARS_NOUVEAU, "purple_archwood_log"),
|
||||
FLOURISHING_ARCHWOOD_LOG = block(ModIds.ARS_NOUVEAU, "green_archwood_log"),
|
||||
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"),
|
||||
RED_ARCHWOOD_SAPLING = item(ModIds.ARS_NOUVEAU, "red_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_PLANKS_ITEM = item(ModIds.ARS_NOUVEAU, "archwood_planks");
|
||||
// Aether
|
||||
public static final RegistryObject<Block>
|
||||
public static final DeferredBlock<Block>
|
||||
SKYROOT_PLANKS = block(ModIds.AETHER, "skyroot_planks"),
|
||||
SKYROOT_LOG = block(ModIds.AETHER, "skyroot_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_PLANKS_ITEM = item(ModIds.AETHER, "skyroot_planks"),
|
||||
GOLDEN_OAK_LOG_ITEM = item(ModIds.AETHER, "golden_oak_log"),
|
||||
SKYROOT_LOG_ITEM = item(ModIds.AETHER, "skyroot_log");
|
||||
// Blue Skies
|
||||
public static final RegistryObject<Block>
|
||||
public static final DeferredBlock<Block>
|
||||
BLUEBRIGHT_PLANKS = block(ModIds.BLUE_SKIES, "bluebright_planks"),
|
||||
STARLIT_PLANKS = block(ModIds.BLUE_SKIES, "starlit_planks"),
|
||||
FROSTBRIGHT_PLANKS = block(ModIds.BLUE_SKIES, "frostbright_planks"),
|
||||
|
|
@ -187,7 +189,7 @@ public class ModCompatData {
|
|||
DUSK_LOG = block(ModIds.BLUE_SKIES, "dusk_log"),
|
||||
MAPLE_LOG = block(ModIds.BLUE_SKIES, "maple_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"),
|
||||
STARLIT_PLANKS_ITEM = item(ModIds.BLUE_SKIES, "starlit_planks"),
|
||||
FROSTBRIGHT_PLANKS_ITEM = item(ModIds.BLUE_SKIES, "frostbright_planks"),
|
||||
|
|
@ -225,9 +227,7 @@ public class ModCompatData {
|
|||
}
|
||||
}
|
||||
|
||||
public static void registerModData() {
|
||||
var modBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||
|
||||
public static void registerModData(IEventBus modBus) {
|
||||
for (var registry : itemRegistries.values()) {
|
||||
registry.register(modBus);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ package thedarkcolour.exdeorum.data.recipe;
|
|||
|
||||
import net.minecraft.advancements.critereon.StatePropertiesPredicate;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.data.recipes.FinishedRecipe;
|
||||
import net.minecraft.data.recipes.RecipeCategory;
|
||||
import net.minecraft.data.recipes.RecipeOutput;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
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.NumberProvider;
|
||||
import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator;
|
||||
import net.minecraftforge.common.ForgeMod;
|
||||
import net.minecraftforge.common.Tags;
|
||||
import net.minecraftforge.common.crafting.conditions.ICondition;
|
||||
import net.minecraftforge.common.crafting.conditions.ModLoadedCondition;
|
||||
import net.minecraftforge.common.crafting.conditions.NotCondition;
|
||||
import net.minecraftforge.common.crafting.conditions.TagEmptyCondition;
|
||||
import net.minecraftforge.registries.RegistryObject;
|
||||
import org.apache.commons.lang3.mutable.MutableObject;
|
||||
import net.neoforged.neoforge.common.NeoForgeMod;
|
||||
import net.neoforged.neoforge.common.Tags;
|
||||
import net.neoforged.neoforge.common.conditions.ICondition;
|
||||
import net.neoforged.neoforge.common.conditions.ModLoadedCondition;
|
||||
import net.neoforged.neoforge.common.conditions.NotCondition;
|
||||
import net.neoforged.neoforge.common.conditions.TagEmptyCondition;
|
||||
import net.neoforged.neoforge.fluids.FluidStack;
|
||||
import thedarkcolour.exdeorum.ExDeorum;
|
||||
import thedarkcolour.exdeorum.block.InfestedLeavesBlock;
|
||||
import thedarkcolour.exdeorum.compat.ModIds;
|
||||
import thedarkcolour.exdeorum.data.ModCompatData;
|
||||
import thedarkcolour.exdeorum.material.DefaultMaterials;
|
||||
import thedarkcolour.exdeorum.recipe.TagResultRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.OreChunkRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.WeightedList;
|
||||
import thedarkcolour.exdeorum.recipe.barrel.*;
|
||||
import thedarkcolour.exdeorum.recipe.BlockPredicate;
|
||||
import thedarkcolour.exdeorum.recipe.crook.FinishedCrookRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.crucible.FinishedCrucibleHeatRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.crucible.FinishedCrucibleRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.hammer.FinishedHammerRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.crook.CrookRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.crucible.CrucibleHeatRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.crucible.CrucibleRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.hammer.HammerRecipe;
|
||||
import thedarkcolour.exdeorum.registry.EBlocks;
|
||||
import thedarkcolour.exdeorum.registry.EFluids;
|
||||
import thedarkcolour.exdeorum.registry.EItems;
|
||||
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
||||
import thedarkcolour.exdeorum.tag.EItemTags;
|
||||
import thedarkcolour.modkit.data.MKRecipeProvider;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
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 {
|
||||
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);
|
||||
smeltingRecipes(recipes);
|
||||
SieveRecipes.sieveRecipes(writer);
|
||||
|
|
@ -92,7 +89,7 @@ public class Recipes {
|
|||
fluidTransformationRecipes(writer);
|
||||
}
|
||||
|
||||
private static void craftingRecipes(Consumer<FinishedRecipe> writer, MKRecipeProvider recipes) {
|
||||
private static void craftingRecipes(RecipeOutput writer, MKRecipeProvider recipes) {
|
||||
// Crooks
|
||||
shapedCrook(recipes, EItems.CROOK, ingredient(Tags.Items.RODS_WOODEN));
|
||||
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());
|
||||
|
||||
// Pebbles and ore chunks
|
||||
recipes.grid2x2(Items.COBBLESTONE, ingredient(EItems.STONE_PEBBLE));
|
||||
recipes.grid2x2(Items.ANDESITE, ingredient(EItems.ANDESITE_PEBBLE));
|
||||
recipes.grid2x2(Items.DIORITE, ingredient(EItems.DIORITE_PEBBLE));
|
||||
recipes.grid2x2(Items.GRANITE, ingredient(EItems.GRANITE_PEBBLE));
|
||||
recipes.grid2x2(Items.COBBLED_DEEPSLATE, ingredient(EItems.DEEPSLATE_PEBBLE));
|
||||
recipes.grid2x2(Items.TUFF, ingredient(EItems.TUFF_PEBBLE));
|
||||
recipes.grid2x2(Items.CALCITE, ingredient(EItems.CALCITE_PEBBLE));
|
||||
recipes.grid2x2(Items.BLACKSTONE, ingredient(EItems.BLACKSTONE_PEBBLE));
|
||||
recipes.grid2x2(Items.BASALT, ingredient(EItems.BASALT_PEBBLE));
|
||||
recipes.grid2x2(Items.IRON_ORE, ingredient(EItems.IRON_ORE_CHUNK));
|
||||
recipes.grid2x2(Items.GOLD_ORE, ingredient(EItems.GOLD_ORE_CHUNK));
|
||||
recipes.grid2x2(Items.COPPER_ORE, ingredient(EItems.COPPER_ORE_CHUNK));
|
||||
recipes.grid2x2(Items.MOSS_BLOCK, ingredient(EItems.GRASS_SEEDS));
|
||||
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.COBBLESTONE, ingredient(EItems.STONE_PEBBLE));
|
||||
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.ANDESITE, ingredient(EItems.ANDESITE_PEBBLE));
|
||||
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.DIORITE, ingredient(EItems.DIORITE_PEBBLE));
|
||||
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.GRANITE, ingredient(EItems.GRANITE_PEBBLE));
|
||||
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.COBBLED_DEEPSLATE, ingredient(EItems.DEEPSLATE_PEBBLE));
|
||||
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.TUFF, ingredient(EItems.TUFF_PEBBLE));
|
||||
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.CALCITE, ingredient(EItems.CALCITE_PEBBLE));
|
||||
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.BLACKSTONE, ingredient(EItems.BLACKSTONE_PEBBLE));
|
||||
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.BASALT, ingredient(EItems.BASALT_PEBBLE));
|
||||
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.IRON_ORE, ingredient(EItems.IRON_ORE_CHUNK));
|
||||
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.GOLD_ORE, ingredient(EItems.GOLD_ORE_CHUNK));
|
||||
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.COPPER_ORE, ingredient(EItems.COPPER_ORE_CHUNK));
|
||||
recipes.grid2x2(RecipeCategory.BUILDING_BLOCKS, Items.MOSS_BLOCK, ingredient(EItems.GRASS_SEEDS));
|
||||
|
||||
// Modded ores
|
||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_ALUMINUM, ingredient(EItems.ALUMINUM_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_COBALT, ingredient(EItems.COBALT_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_SILVER, ingredient(EItems.SILVER_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_LEAD, ingredient(EItems.LEAD_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_PLATINUM, ingredient(EItems.PLATINUM_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_NICKEL, ingredient(EItems.NICKEL_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_URANIUM, ingredient(EItems.URANIUM_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_OSMIUM, ingredient(EItems.OSMIUM_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_TIN, ingredient(EItems.TIN_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_ZINC, ingredient(EItems.ZINC_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_IRIDIUM, ingredient(EItems.IRIDIUM_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_THORIUM, ingredient(EItems.THORIUM_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_MAGNESIUM, ingredient(EItems.MAGNESIUM_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_LITHIUM, ingredient(EItems.LITHIUM_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, recipes, EItemTags.ORES_BORON, ingredient(EItems.BORON_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, EItemTags.ORES_ALUMINUM, ingredient(EItems.ALUMINUM_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, EItemTags.ORES_COBALT, ingredient(EItems.COBALT_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, EItemTags.ORES_SILVER, ingredient(EItems.SILVER_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, EItemTags.ORES_LEAD, ingredient(EItems.LEAD_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, EItemTags.ORES_PLATINUM, ingredient(EItems.PLATINUM_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, EItemTags.ORES_NICKEL, ingredient(EItems.NICKEL_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, EItemTags.ORES_URANIUM, ingredient(EItems.URANIUM_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, EItemTags.ORES_OSMIUM, ingredient(EItems.OSMIUM_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, EItemTags.ORES_TIN, ingredient(EItems.TIN_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, EItemTags.ORES_ZINC, ingredient(EItems.ZINC_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, EItemTags.ORES_IRIDIUM, ingredient(EItems.IRIDIUM_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, EItemTags.ORES_THORIUM, ingredient(EItems.THORIUM_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, EItemTags.ORES_MAGNESIUM, ingredient(EItems.MAGNESIUM_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, EItemTags.ORES_LITHIUM, ingredient(EItems.LITHIUM_ORE_CHUNK));
|
||||
grid2x2TagResult(writer, EItemTags.ORES_BORON, ingredient(EItems.BORON_ORE_CHUNK));
|
||||
|
||||
// Sieves
|
||||
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 -> {
|
||||
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 -> {
|
||||
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) {
|
||||
// capture the generated recipe and wrap it in a TagResultRecipe
|
||||
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 grid2x2TagResult(RecipeOutput writer, TagKey<Item> resultTag, Ingredient ingredient) {
|
||||
writer.accept(new ResourceLocation(resultTag.location().getPath() + "_from_chunks"), new OreChunkRecipe(ingredient, resultTag), null, tagNotEmpty(resultTag));
|
||||
}
|
||||
|
||||
private static void shapedCrook(MKRecipeProvider recipes, RegistryObject<? extends Item> crook, Ingredient stick) {
|
||||
recipes.shapedCrafting(RecipeCategory.TOOLS, crook.get(), recipe -> {
|
||||
private static void shapedCrook(MKRecipeProvider recipes, ItemLike crook, Ingredient stick) {
|
||||
recipes.shapedCrafting(RecipeCategory.TOOLS, crook, recipe -> {
|
||||
recipe.define('x', stick);
|
||||
recipe.pattern("xx");
|
||||
recipe.pattern(" x");
|
||||
|
|
@ -356,8 +344,8 @@ public class Recipes {
|
|||
});
|
||||
}
|
||||
|
||||
private static void shapedHammer(MKRecipeProvider recipes, RegistryObject<? extends Item> hammer, Ingredient material) {
|
||||
recipes.shapedCrafting(RecipeCategory.TOOLS, hammer.get(), recipe -> {
|
||||
private static void shapedHammer(MKRecipeProvider recipes, ItemLike hammer, Ingredient material) {
|
||||
recipes.shapedCrafting(RecipeCategory.TOOLS, hammer, recipe -> {
|
||||
recipe.define('m', material);
|
||||
recipe.define('s', Tags.Items.RODS_WOODEN);
|
||||
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 -> {
|
||||
recipe.define('O', planks);
|
||||
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) {
|
||||
recipes.shapedCrafting(newMesh.getId().getPath() + "_from_" + previousMesh.getId().getPath(), RecipeCategory.MISC, newMesh.get(), recipe -> {
|
||||
private static void meshUpgrade(MKRecipeProvider recipes, ItemLike newMesh, ItemLike previousMesh, Ingredient ingredient) {
|
||||
recipes.shapedCrafting(path(newMesh) + "_from_" + path(previousMesh), RecipeCategory.MISC, newMesh, recipe -> {
|
||||
recipe.define('#', ingredient);
|
||||
recipe.define('M', previousMesh.get());
|
||||
recipe.define('M', previousMesh);
|
||||
recipe.pattern(" # ");
|
||||
recipe.pattern("#M#");
|
||||
recipe.pattern(" # ");
|
||||
|
|
@ -423,7 +411,7 @@ public class Recipes {
|
|||
|
||||
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, "stone", ingredient(Tags.Items.STONE), 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, "seeds_and_spores", SPORES_AND_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, "sweet_berries", ingredient(Items.SWEET_BERRIES, Items.GLOW_BERRIES), 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);
|
||||
}
|
||||
|
||||
private static void lavaCrucible(Consumer<FinishedRecipe> 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));
|
||||
private static void lavaCrucible(RecipeOutput writer, String id, Ingredient ingredient, int 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) {
|
||||
writer.accept(new FinishedCrucibleRecipe(new ResourceLocation(ExDeorum.ID, "water_crucible/" + id), ERecipeSerializers.WATER_CRUCIBLE.get(), ingredient, Fluids.WATER, volume));
|
||||
private static void waterCrucible(RecipeOutput writer, String id, Ingredient ingredient, int 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
|
||||
hammerRecipe(writer, "gravel", ingredient(Items.COBBLESTONE, Items.DIORITE, Items.GRANITE, Items.ANDESITE), Blocks.GRAVEL);
|
||||
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));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
private static void hammerRecipe(Consumer<FinishedRecipe> writer, String name, Ingredient block, ItemLike result, NumberProvider resultAmount) {
|
||||
writer.accept(new FinishedHammerRecipe(new ResourceLocation(ExDeorum.ID, "hammer/" + name), block, result.asItem(), resultAmount));
|
||||
private static void hammerRecipe(RecipeOutput writer, String name, Ingredient block, ItemLike result, NumberProvider 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);
|
||||
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, "string_roll_1", fullyInfestedLeaves, Items.STRING, 0.4f);
|
||||
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) {
|
||||
writer.accept(new FinishedCrookRecipe(new ResourceLocation(ExDeorum.ID, "crook/" + name), blockPredicate, result.asItem(), chance));
|
||||
private static void crookRecipe(RecipeOutput writer, String name, BlockPredicate blockPredicate, ItemLike result, float 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.WALL_TORCH, 1);
|
||||
crucibleHeatSource(writer, Blocks.LANTERN, 1);
|
||||
|
|
@ -531,19 +521,19 @@ public class Recipes {
|
|||
crucibleHeatSource(writer, Blocks.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_soul_campfire", BlockPredicate.blockState(Blocks.SOUL_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().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);
|
||||
}
|
||||
|
||||
private static void crucibleHeatSource(Consumer<FinishedRecipe> writer, String name, BlockPredicate blockPredicate, int heatValue) {
|
||||
writer.accept(new FinishedCrucibleHeatRecipe(new ResourceLocation(ExDeorum.ID, "crucible_heat_source/" + name), blockPredicate, heatValue));
|
||||
private static void crucibleHeatSource(RecipeOutput writer, String name, BlockPredicate blockPredicate, int 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
|
||||
barrelCompost(writer, "saplings", ingredient(ItemTags.SAPLINGS), 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, "sugar_cane", ingredient(Items.SUGAR_CANE), 80);
|
||||
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, "seagrass", ingredient(Items.SEAGRASS), 80);
|
||||
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);
|
||||
}
|
||||
|
||||
private static void barrelCompost(Consumer<FinishedRecipe> writer, String id, Ingredient ingredient, int volume) {
|
||||
writer.accept(new FinishedBarrelCompostRecipe(new ResourceLocation(ExDeorum.ID, "barrel_compost/" + id), ingredient, volume));
|
||||
private static void barrelCompost(RecipeOutput writer, String id, Ingredient ingredient, int 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
|
||||
barrelMixing(writer, ingredient(EItems.DUST.get()), Fluids.WATER, Items.CLAY);
|
||||
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);
|
||||
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);
|
||||
barrelFluidMixing(writer, Fluids.WATER, Fluids.LAVA, Items.STONE, false);
|
||||
// lava
|
||||
|
|
@ -637,20 +627,20 @@ public class Recipes {
|
|||
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);
|
||||
}
|
||||
|
||||
private static void barrelMixing(Consumer<FinishedRecipe> 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));
|
||||
private static void barrelMixing(RecipeOutput writer, String suffix, Ingredient ingredient, Fluid fluidType, Item 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) {
|
||||
writer.accept(new FinishedBarrelFluidMixingRecipe(new ResourceLocation(ExDeorum.ID, "barrel_fluid_mixing/" + path(result)), base, 1000, additive, result, consumesAdditive));
|
||||
private static void barrelFluidMixing(RecipeOutput writer, Fluid base, Fluid additive, Item result, boolean consumesAdditive) {
|
||||
writer.accept(modLoc("barrel_fluid_mixing/" + path(result)), new BarrelFluidMixingRecipe(base, 1000, additive, result, consumesAdditive), null);
|
||||
}
|
||||
|
||||
private static void fluidTransformationRecipes(Consumer<FinishedRecipe> 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));
|
||||
private static void fluidTransformationRecipes(RecipeOutput writer) {
|
||||
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) {
|
||||
|
|
|
|||
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.Items;
|
||||
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.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.Heightmap;
|
||||
import net.minecraft.world.level.levelgen.XoroshiroRandomSource;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.client.event.ClientChatEvent;
|
||||
import net.minecraftforge.common.ForgeMod;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.AddReloadListenerEvent;
|
||||
import net.minecraftforge.event.OnDatapackSyncEvent;
|
||||
import net.minecraftforge.event.TickEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.event.level.LevelEvent;
|
||||
import net.minecraftforge.event.server.ServerStoppingEvent;
|
||||
import net.minecraftforge.fluids.FluidInteractionRegistry;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.fml.InterModComms;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import net.minecraftforge.fml.loading.FMLEnvironment;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.bus.api.IEventBus;
|
||||
import net.neoforged.fml.DistExecutor;
|
||||
import net.neoforged.fml.InterModComms;
|
||||
import net.neoforged.fml.ModList;
|
||||
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.neoforged.fml.event.lifecycle.InterModEnqueueEvent;
|
||||
import net.neoforged.fml.loading.FMLEnvironment;
|
||||
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent;
|
||||
import net.neoforged.neoforge.client.event.ClientChatEvent;
|
||||
import net.neoforged.neoforge.common.NeoForge;
|
||||
import net.neoforged.neoforge.common.NeoForgeMod;
|
||||
import net.neoforged.neoforge.event.AddReloadListenerEvent;
|
||||
import net.neoforged.neoforge.event.OnDatapackSyncEvent;
|
||||
import net.neoforged.neoforge.event.TickEvent;
|
||||
import net.neoforged.neoforge.event.entity.player.PlayerEvent;
|
||||
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.blockentity.helper.ItemHelper;
|
||||
import thedarkcolour.exdeorum.client.CompostColors;
|
||||
import thedarkcolour.exdeorum.compat.ModIds;
|
||||
import thedarkcolour.exdeorum.compat.top.ExDeorumTopCompat;
|
||||
import thedarkcolour.exdeorum.config.EConfig;
|
||||
import thedarkcolour.exdeorum.item.PorcelainBucket;
|
||||
import thedarkcolour.exdeorum.item.WateringCanItem;
|
||||
import thedarkcolour.exdeorum.material.BarrelMaterial;
|
||||
import thedarkcolour.exdeorum.network.ClientMessageHandler;
|
||||
import thedarkcolour.exdeorum.network.MenuPropertyMessage;
|
||||
import thedarkcolour.exdeorum.network.NetworkHandler;
|
||||
import thedarkcolour.exdeorum.network.VisualUpdateTracker;
|
||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
||||
import thedarkcolour.exdeorum.registry.EBlockEntities;
|
||||
import thedarkcolour.exdeorum.registry.EFluids;
|
||||
import thedarkcolour.exdeorum.registry.EItems;
|
||||
import thedarkcolour.exdeorum.tag.EBiomeTags;
|
||||
|
|
@ -81,9 +89,8 @@ import java.util.Set;
|
|||
import java.util.UUID;
|
||||
|
||||
public final class EventHandler {
|
||||
public static void register() {
|
||||
var fmlBus = MinecraftForge.EVENT_BUS;
|
||||
var modBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||
public static void register(IEventBus modBus) {
|
||||
var fmlBus = NeoForge.EVENT_BUS;
|
||||
|
||||
fmlBus.addListener(EventHandler::onPlayerLogin);
|
||||
fmlBus.addListener(EventHandler::onDataSynced);
|
||||
|
|
@ -91,8 +98,10 @@ public final class EventHandler {
|
|||
fmlBus.addListener(EventHandler::createSpawnTree);
|
||||
modBus.addListener(EventHandler::interModEnqueue);
|
||||
modBus.addListener(EventHandler::onCommonSetup);
|
||||
modBus.addListener(EventHandler::registerPayloadHandler);
|
||||
fmlBus.addListener(EventHandler::serverShutdown);
|
||||
fmlBus.addListener(EventHandler::serverTick);
|
||||
fmlBus.addListener(EventHandler::registerCapabilities);
|
||||
|
||||
if (ExDeorum.DEBUG) {
|
||||
fmlBus.addListener(EventHandler::handleDebugCommands);
|
||||
|
|
@ -147,10 +156,10 @@ public final class EventHandler {
|
|||
|
||||
for (var entry : EBiomeTags.TREE_TAGS.entrySet()) {
|
||||
if (biome.is(entry.getKey())) {
|
||||
var optional = entry.getValue().getHolder();
|
||||
var optional = entry.getValue();
|
||||
|
||||
if (optional.isPresent()) {
|
||||
holder = (optional.get());
|
||||
if (optional.isBound()) {
|
||||
holder = optional;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -171,14 +180,14 @@ public final class EventHandler {
|
|||
|
||||
private static void onCommonSetup(FMLCommonSetupEvent event) {
|
||||
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(),
|
||||
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 rng = RandomSource.create();
|
||||
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)
|
||||
));
|
||||
|
||||
|
|
@ -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) {
|
||||
UUID excludedUUID = null;
|
||||
|
||||
if (FMLEnvironment.dist == Dist.CLIENT) {
|
||||
// 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);
|
||||
if (player == null) {
|
||||
return;
|
||||
|
|
@ -219,7 +233,7 @@ public final class EventHandler {
|
|||
// tries to account for other SkyBlock generator mods like SkyBlockBuilder
|
||||
if (generator instanceof VoidChunkGenerator || generator.getClass().getName().toLowerCase(Locale.ROOT).contains("skyblock")) {
|
||||
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 (!player.getAdvancements().getOrStartProgress(advancement).isDone()) {
|
||||
|
|
@ -262,4 +276,30 @@ public final class EventHandler {
|
|||
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.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions;
|
||||
import net.minecraftforge.common.SoundActions;
|
||||
import net.minecraftforge.fluids.FluidType;
|
||||
import net.minecraftforge.fluids.ForgeFlowingFluid;
|
||||
import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions;
|
||||
import net.neoforged.neoforge.common.SoundActions;
|
||||
import net.neoforged.neoforge.fluids.BaseFlowingFluid;
|
||||
import net.neoforged.neoforge.fluids.FluidType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.joml.Vector3f;
|
||||
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 OVERLAY_TEXTURE = new ResourceLocation("block/water_overlay");
|
||||
|
||||
public static ForgeFlowingFluid.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);
|
||||
public static BaseFlowingFluid.Properties properties() {
|
||||
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() {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ import net.minecraft.world.item.enchantment.Enchantment;
|
|||
import net.minecraft.world.item.enchantment.Enchantments;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.common.Tags;
|
||||
import net.neoforged.neoforge.common.Tags;
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -19,19 +19,28 @@
|
|||
package thedarkcolour.exdeorum.item;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.DiggerItem;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Tier;
|
||||
import net.minecraft.world.item.crafting.RecipeHolder;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
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 thedarkcolour.exdeorum.recipe.RecipeUtil;
|
||||
import thedarkcolour.exdeorum.recipe.hammer.HammerRecipe;
|
||||
import thedarkcolour.exdeorum.registry.EItems;
|
||||
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
public class HammerItem extends DiggerItem {
|
||||
|
|
@ -42,11 +51,17 @@ public class HammerItem extends DiggerItem {
|
|||
}
|
||||
|
||||
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());
|
||||
|
||||
for (var recipe : hammerRecipes) {
|
||||
for (var item : recipe.getIngredient().getItems()) {
|
||||
for (var item : recipe.value().getIngredient().getItems()) {
|
||||
if (item.getItem() instanceof BlockItem blockItem) {
|
||||
validBlocks.add(blockItem.getBlock());
|
||||
}
|
||||
|
|
@ -71,10 +86,11 @@ public class HammerItem extends DiggerItem {
|
|||
|
||||
@Override
|
||||
public boolean isCorrectToolForDrops(BlockState state) {
|
||||
if (net.minecraftforge.common.TierSortingRegistry.isTierSorted(getTier())) {
|
||||
return net.minecraftforge.common.TierSortingRegistry.isCorrectTierForDrops(getTier(), state) && getValidBlocks().contains(state.getBlock());
|
||||
var tier = getTier();
|
||||
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)) {
|
||||
return false;
|
||||
} else if (i < 2 && state.is(BlockTags.NEEDS_IRON_TOOL)) {
|
||||
|
|
@ -87,7 +103,7 @@ public class HammerItem extends DiggerItem {
|
|||
// FORGE START
|
||||
@Override
|
||||
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
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ package thedarkcolour.exdeorum.item;
|
|||
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.common.Tags;
|
||||
import net.neoforged.neoforge.common.Tags;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
|
|
|||
|
|
@ -20,9 +20,7 @@ package thedarkcolour.exdeorum.item;
|
|||
|
||||
import net.minecraft.advancements.CriteriaTriggers;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
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.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraftforge.common.ForgeMod;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
||||
import net.minecraftforge.common.capabilities.ICapabilityProvider;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
|
||||
import net.neoforged.neoforge.common.NeoForgeMod;
|
||||
import net.neoforged.neoforge.common.SoundActions;
|
||||
import net.neoforged.neoforge.event.EventHooks;
|
||||
import net.neoforged.neoforge.fluids.FluidStack;
|
||||
import net.neoforged.neoforge.fluids.FluidUtil;
|
||||
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
|
||||
import net.neoforged.neoforge.fluids.capability.IFluidHandlerItem;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import thedarkcolour.exdeorum.registry.EFluids;
|
||||
|
|
@ -94,7 +91,7 @@ public class PorcelainBucket extends Item {
|
|||
public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand pHand) {
|
||||
var stack = player.getItemInHand(pHand);
|
||||
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 (hitResult.getType() == HitResult.Type.MISS) {
|
||||
return InteractionResultHolder.pass(stack);
|
||||
|
|
@ -109,13 +106,13 @@ public class PorcelainBucket extends Item {
|
|||
var state = level.getBlockState(pos);
|
||||
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) {
|
||||
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());
|
||||
} else if (fluidType == ForgeMod.LAVA_TYPE.get()) {
|
||||
} else if (fluidType == NeoForgeMod.LAVA_TYPE.value()) {
|
||||
result = new ItemStack(EItems.PORCELAIN_LAVA_BUCKET.get());
|
||||
} else {
|
||||
result = new ItemStack(EItems.PORCELAIN_WITCH_WATER_BUCKET.get());
|
||||
|
|
@ -138,7 +135,7 @@ public class PorcelainBucket extends Item {
|
|||
return InteractionResultHolder.fail(stack);
|
||||
} else {
|
||||
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 (player instanceof ServerPlayer serverPlayer) {
|
||||
|
|
@ -176,8 +173,8 @@ public class PorcelainBucket extends Item {
|
|||
var state = level.getBlockState(pos);
|
||||
var block = state.getBlock();
|
||||
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 containedFluidStack = java.util.Optional.ofNullable(container).flatMap(net.minecraftforge.fluids.FluidUtil::getFluidContained);
|
||||
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(FluidUtil::getFluidContained);
|
||||
|
||||
if (!canPlaceAtPos) {
|
||||
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;
|
||||
} 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));
|
||||
playEmptySound(player, level, pos);
|
||||
return true;
|
||||
|
|
@ -215,7 +212,7 @@ public class PorcelainBucket extends Item {
|
|||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
protected boolean canBlockContainFluid(Level level, BlockPos pos, BlockState state) {
|
||||
return state.getBlock() instanceof LiquidBlockContainer block && block.canPlaceLiquid(level, pos, state, this.fluid.get());
|
||||
protected boolean canBlockContainFluid(Player player, Level level, BlockPos pos, BlockState state) {
|
||||
return state.getBlock() instanceof LiquidBlockContainer block && block.canPlaceLiquid(player, level, pos, state, this.fluid.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
public static class ItemHandler implements IFluidHandlerItem {
|
||||
private ItemStack container;
|
||||
|
||||
public CapabilityProvider(ItemStack container) {
|
||||
public ItemHandler(ItemStack container) {
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
|
|
@ -246,12 +237,6 @@ public class PorcelainBucket extends Item {
|
|||
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
|
||||
public int getTanks() {
|
||||
return 1;
|
||||
|
|
@ -270,7 +255,7 @@ public class PorcelainBucket extends Item {
|
|||
|
||||
@Override
|
||||
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
|
||||
|
|
@ -328,8 +313,8 @@ public class PorcelainBucket extends Item {
|
|||
return new FluidStack(Fluids.WATER, 1000);
|
||||
} else if (item == EItems.PORCELAIN_WITCH_WATER_BUCKET.get()) {
|
||||
return new FluidStack(EFluids.WITCH_WATER.get(), 1000);
|
||||
} else if (item == EItems.PORCELAIN_MILK_BUCKET.get() && ForgeMod.MILK.isPresent()) {
|
||||
return new FluidStack(ForgeMod.MILK.get(), 1000);
|
||||
} else if (item == EItems.PORCELAIN_MILK_BUCKET.get() && NeoForgeMod.MILK.isBound()) {
|
||||
return new FluidStack(NeoForgeMod.MILK.get(), 1000);
|
||||
}
|
||||
|
||||
return FluidStack.EMPTY;
|
||||
|
|
@ -344,7 +329,7 @@ public class PorcelainBucket extends Item {
|
|||
this.container = new ItemStack(EItems.PORCELAIN_WATER_BUCKET.get());
|
||||
} else if (fluidStack.getFluid() == EFluids.WITCH_WATER.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());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,17 +18,11 @@
|
|||
|
||||
package thedarkcolour.exdeorum.item;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.MilkBucketItem;
|
||||
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;
|
||||
|
||||
public class PorcelainMilkBucket extends MilkBucketItem {
|
||||
|
|
@ -46,20 +40,4 @@ public class PorcelainMilkBucket extends MilkBucketItem {
|
|||
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.Direction;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
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.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraftforge.client.extensions.common.IClientItemExtensions;
|
||||
import net.minecraftforge.common.ForgeMod;
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
||||
import net.minecraftforge.common.capabilities.ICapabilityProvider;
|
||||
import net.minecraftforge.common.util.FakePlayer;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
import net.minecraftforge.fluids.capability.templates.FluidHandlerItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||
import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions;
|
||||
import net.neoforged.neoforge.common.NeoForgeMod;
|
||||
import net.neoforged.neoforge.common.util.FakePlayer;
|
||||
import net.neoforged.neoforge.fluids.FluidStack;
|
||||
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
|
||||
import net.neoforged.neoforge.fluids.capability.templates.FluidHandlerItemStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import thedarkcolour.exdeorum.blockentity.BarrelBlockEntity;
|
||||
import thedarkcolour.exdeorum.data.TranslationKeys;
|
||||
|
|
@ -97,13 +94,21 @@ public class WateringCanItem extends Item {
|
|||
|
||||
public static ItemStack getFull(Supplier<? extends Item> wateringCan) {
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
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
|
||||
|
|
@ -113,9 +118,12 @@ public class WateringCanItem extends Item {
|
|||
|
||||
@Override
|
||||
public int getBarWidth(ItemStack stack) {
|
||||
return stack.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).map(fluidHandler -> {
|
||||
return Math.round((float) fluidHandler.getFluidInTank(0).getAmount() * 13.0F / (float) this.capacity);
|
||||
}).orElse(0);
|
||||
var fluidHandler = stack.getCapability(Capabilities.FluidHandler.ITEM);
|
||||
if (fluidHandler != null) {
|
||||
return Math.round((float) fluidHandler.getFluidInTank(0).getAmount() * 13f / (float) this.capacity);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -130,16 +138,18 @@ public class WateringCanItem extends Item {
|
|||
|
||||
@Override
|
||||
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
|
||||
tooltip.add(Component.translatable("block.minecraft.water").append(Component.translatable(TranslationKeys.FRACTION_DISPLAY, fluidHandler.getFluidInTank(0).getAmount(), this.capacity)).withStyle(ChatFormatting.GRAY));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand 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) {
|
||||
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 (!level.isClientSide) {
|
||||
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));
|
||||
}
|
||||
|
||||
|
|
@ -170,8 +180,8 @@ public class WateringCanItem extends Item {
|
|||
|
||||
return InteractionResultHolder.consume(itemInHand);
|
||||
}
|
||||
return InteractionResultHolder.pass(itemInHand);
|
||||
}).orElse(InteractionResultHolder.pass(itemInHand));
|
||||
}
|
||||
return InteractionResultHolder.pass(itemInHand);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -179,10 +189,11 @@ public class WateringCanItem extends Item {
|
|||
var useTicks = 72000 - remainingTicks;
|
||||
|
||||
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()) {
|
||||
// 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);
|
||||
|
||||
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 (!(living instanceof Player player && player.getAbilities().instabuild)) {
|
||||
((CapabilityProvider) fluidHandler).drain();
|
||||
((FluidHandler) fluidHandler).drain();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -215,7 +226,7 @@ public class WateringCanItem extends Item {
|
|||
living.stopUsingItem();
|
||||
isWatering = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -236,7 +247,7 @@ public class WateringCanItem extends Item {
|
|||
} else if (state.getBlock() instanceof SugarCaneBlock block) {
|
||||
var cursor = pos.mutable();
|
||||
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
|
||||
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
|
||||
public void initializeClient(Consumer<IClientItemExtensions> consumer) {
|
||||
consumer.accept(ClientExtensions.INSTANCE);
|
||||
}
|
||||
|
||||
private static class CapabilityProvider extends FluidHandlerItemStack {
|
||||
public CapabilityProvider(@NotNull ItemStack container, int capacity) {
|
||||
super(container, capacity);
|
||||
public static class FluidHandler extends FluidHandlerItemStack {
|
||||
public FluidHandler(ItemStack container) {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -18,21 +18,11 @@
|
|||
|
||||
package thedarkcolour.exdeorum.item;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
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;
|
||||
|
||||
public class WitchWaterBucketItem extends BucketItem {
|
||||
public WitchWaterBucketItem(Properties 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.parameters.LootContextParams;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
||||
import net.minecraftforge.common.loot.IGlobalLootModifier;
|
||||
import net.minecraftforge.common.loot.LootModifier;
|
||||
import net.neoforged.neoforge.common.loot.IGlobalLootModifier;
|
||||
import net.neoforged.neoforge.common.loot.LootModifier;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
||||
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.parameters.LootContextParams;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
||||
import net.minecraftforge.common.loot.IGlobalLootModifier;
|
||||
import net.minecraftforge.common.loot.LootModifier;
|
||||
import net.neoforged.neoforge.common.loot.IGlobalLootModifier;
|
||||
import net.neoforged.neoforge.common.loot.LootModifier;
|
||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@
|
|||
|
||||
package thedarkcolour.exdeorum.loot;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
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 thedarkcolour.exdeorum.registry.ELootFunctions;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -52,11 +56,4 @@ public class MachineLootFunction extends LootItemConditionalFunction {
|
|||
public static LootItemConditionalFunction.Builder<?> machineLoot() {
|
||||
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;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
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.NumberProvider;
|
||||
import net.minecraft.world.level.storage.loot.providers.number.NumberProviders;
|
||||
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
|
||||
public float getFloat(LootContext context) {
|
||||
float sum = 0f;
|
||||
|
|
@ -42,26 +44,4 @@ public record SummationGenerator(NumberProvider[] providers) implements NumberPr
|
|||
public LootNumberProviderType getType() {
|
||||
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.SoundType;
|
||||
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 {
|
||||
// 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
|
||||
public final String requiredModId;
|
||||
|
||||
RegistryObject<Block> block;
|
||||
RegistryObject<BlockItem> item;
|
||||
DeferredBlock<Block> block;
|
||||
DeferredItem<BlockItem> item;
|
||||
|
||||
protected AbstractMaterial(SoundType soundType, float strength, boolean needsCorrectTool, int mapColor, String requiredModId) {
|
||||
this.soundType = soundType;
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ import com.google.gson.JsonPrimitive;
|
|||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.block.SoundType;
|
||||
import net.minecraftforge.common.util.ForgeSoundType;
|
||||
import net.minecraftforge.registries.RegistryObject;
|
||||
import net.neoforged.neoforge.common.util.DeferredSoundType;
|
||||
import net.neoforged.neoforge.registries.DeferredHolder;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import thedarkcolour.exdeorum.ExDeorum;
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ public class MaterialParser {
|
|||
|
||||
if (soundTypeJson.isJsonPrimitive()) {
|
||||
String soundTypeString = soundTypeJson.getAsString();
|
||||
var soundType = SoundTypeResolver.VANILLA_SOUND_TYPES.get(soundTypeString);
|
||||
var soundType = SoundTypeResolver.resolve(soundTypeString);
|
||||
|
||||
if (soundType == null) {
|
||||
ExDeorum.LOGGER.error("Unknown sound type \"{}\" for material {}", soundTypeString, this.jsonPath);
|
||||
|
|
@ -59,12 +59,12 @@ public class MaterialParser {
|
|||
}
|
||||
} 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")) {
|
||||
return new ForgeSoundType(1.0f, 1.0f,
|
||||
RegistryObject.create(new ResourceLocation(soundTypeObj.get("break_sound").getAsString()), Registries.SOUND_EVENT, ExDeorum.ID),
|
||||
RegistryObject.create(new ResourceLocation(soundTypeObj.get("step_sound").getAsString()), Registries.SOUND_EVENT, ExDeorum.ID),
|
||||
RegistryObject.create(new ResourceLocation(soundTypeObj.get("place_sound").getAsString()), Registries.SOUND_EVENT, ExDeorum.ID),
|
||||
RegistryObject.create(new ResourceLocation(soundTypeObj.get("hit_sound").getAsString()), Registries.SOUND_EVENT, ExDeorum.ID),
|
||||
RegistryObject.create(new ResourceLocation(soundTypeObj.get("fall_sound").getAsString()), Registries.SOUND_EVENT, ExDeorum.ID)
|
||||
return new DeferredSoundType(1.0f, 1.0f,
|
||||
DeferredHolder.create(Registries.SOUND_EVENT, new ResourceLocation(soundTypeObj.get("break_sound").getAsString())),
|
||||
DeferredHolder.create(Registries.SOUND_EVENT, new ResourceLocation(soundTypeObj.get("step_sound").getAsString())),
|
||||
DeferredHolder.create(Registries.SOUND_EVENT, new ResourceLocation(soundTypeObj.get("place_sound").getAsString())),
|
||||
DeferredHolder.create(Registries.SOUND_EVENT, new ResourceLocation(soundTypeObj.get("hit_sound").getAsString())),
|
||||
DeferredHolder.create(Registries.SOUND_EVENT, new ResourceLocation(soundTypeObj.get("fall_sound").getAsString()))
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import com.google.gson.JsonParser;
|
|||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
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 thedarkcolour.exdeorum.ExDeorum;
|
||||
import thedarkcolour.exdeorum.client.CompostColors;
|
||||
|
|
|
|||
|
|
@ -18,126 +18,24 @@
|
|||
|
||||
package thedarkcolour.exdeorum.material;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import net.minecraft.world.level.block.SoundType;
|
||||
import net.minecraftforge.fml.loading.FMLLoader;
|
||||
import thedarkcolour.exdeorum.ExDeorum;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
|
||||
class SoundTypeResolver {
|
||||
static final Map<String, SoundType> VANILLA_SOUND_TYPES;
|
||||
private static final HashMap<String, SoundType> VANILLA_SOUND_TYPES = new HashMap<>();
|
||||
|
||||
static {
|
||||
if (ExDeorum.DEBUG && !FMLLoader.versionInfo().mcVersion().equals("1.20.1")) {
|
||||
throw new RuntimeException("Update the BarrelMaterial map");
|
||||
}
|
||||
// Very long line of put calls that put each SoundType field and its lowercase name into the map
|
||||
ImmutableMap.Builder<String, SoundType> temp = ImmutableMap.builder();
|
||||
temp.put("empty", SoundType.EMPTY);
|
||||
temp.put("wood", SoundType.WOOD);
|
||||
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();
|
||||
@Nullable
|
||||
static SoundType resolve(String name) {
|
||||
return VANILLA_SOUND_TYPES.computeIfAbsent(name.toUpperCase(Locale.ROOT), (fieldName) -> {
|
||||
try {
|
||||
var field = SoundType.class.getDeclaredField(fieldName);
|
||||
return (SoundType) field.get(null);
|
||||
} catch (NoSuchFieldException | IllegalAccessException ignored) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
* 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.resources.ResourceLocation;
|
||||
|
|
@ -26,7 +26,7 @@ import net.minecraft.world.inventory.DataSlot;
|
|||
import net.minecraft.world.inventory.InventoryMenu;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import thedarkcolour.exdeorum.ExDeorum;
|
||||
import thedarkcolour.exdeorum.menu.AbstractMachineMenu;
|
||||
import thedarkcolour.exdeorum.blockentity.MechanicalHammerBlockEntity;
|
||||
import thedarkcolour.exdeorum.registry.EMenus;
|
||||
import thedarkcolour.exdeorum.tag.EItemTags;
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ public class ClientMessageHandler {
|
|||
}
|
||||
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
public static void handleVisualUpdate(VisualUpdateMessage msg) {
|
||||
static void handleVisualUpdate(VisualUpdateMessage msg) {
|
||||
ClientLevel level = Minecraft.getInstance().level;
|
||||
if (level != null && level.getBlockEntity(msg.pos) instanceof EBlockEntity blockEntity) {
|
||||
// payload should be nonnull on the client side
|
||||
|
|
|
|||
|
|
@ -19,27 +19,27 @@
|
|||
package thedarkcolour.exdeorum.network;
|
||||
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import thedarkcolour.exdeorum.ExDeorum;
|
||||
|
||||
// Like ClientboundContainerSetDataPacket except that the value is 32 bits instead of 16 bits
|
||||
public record MenuPropertyMessage(int containerId, int index, int value) {
|
||||
public static void encode(MenuPropertyMessage msg, FriendlyByteBuf buffer) {
|
||||
buffer.writeByte(msg.containerId);
|
||||
buffer.writeShort(msg.index);
|
||||
buffer.writeVarInt(msg.value);
|
||||
public record MenuPropertyMessage(int containerId, int index, int value) implements CustomPacketPayload {
|
||||
public static final ResourceLocation ID = new ResourceLocation(ExDeorum.ID, "menu_property");
|
||||
|
||||
@Override
|
||||
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) {
|
||||
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;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraftforge.network.NetworkDirection;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
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;
|
||||
import net.neoforged.neoforge.network.PacketDistributor;
|
||||
import net.neoforged.neoforge.network.registration.IPayloadRegistrar;
|
||||
|
||||
public final class NetworkHandler {
|
||||
public static final String PROTOCOL_VERSION = "1";
|
||||
public static final SimpleChannel CHANNEL = NetworkRegistry.newSimpleChannel(new ResourceLocation(ExDeorum.ID, "channel"), () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals, PROTOCOL_VERSION::equals);
|
||||
|
||||
public static void register() {
|
||||
CHANNEL.registerMessage(0, VoidWorldMessage.class, VoidWorldMessage::encode, VoidWorldMessage::decode, VoidWorldMessage::handle);
|
||||
CHANNEL.registerMessage(1, PlayerDataMessage.class, (msg, buffer) -> {}, buffer -> new PlayerDataMessage(), PlayerDataMessage::handle);
|
||||
CHANNEL.registerMessage(2, VisualUpdateMessage.class, VisualUpdateMessage::encode, VisualUpdateMessage::decode, VisualUpdateMessage::handle);
|
||||
CHANNEL.registerMessage(3, MenuPropertyMessage.class, MenuPropertyMessage::encode, MenuPropertyMessage::decode, MenuPropertyMessage::handle);
|
||||
public static void register(IPayloadRegistrar registrar) {
|
||||
registrar.play(MenuPropertyMessage.ID, MenuPropertyMessage::decode, sidedHandler -> {
|
||||
sidedHandler.client((msg, ctx) -> ClientMessageHandler.handleMenuProperty(msg));
|
||||
});
|
||||
registrar.play(VisualUpdateMessage.ID, VisualUpdateMessage::decode, sidedHandler -> {
|
||||
sidedHandler.client((msg, ctx) -> ClientMessageHandler.handleVisualUpdate(msg));
|
||||
});
|
||||
// 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) {
|
||||
CHANNEL.sendTo(new VoidWorldMessage(), pPlayer.connection.connection, NetworkDirection.PLAY_TO_CLIENT);
|
||||
public static void sendVoidWorld(ServerPlayer player) {
|
||||
PacketDistributor.PLAYER.with(player).send(VoidWorldMessage.INSTANCE);
|
||||
}
|
||||
|
||||
public static void sendRecipeCacheReset(ServerPlayer player) {
|
||||
CHANNEL.sendTo(new PlayerDataMessage(), player.connection.connection, NetworkDirection.PLAY_TO_CLIENT);
|
||||
}
|
||||
|
||||
static void handle(Supplier<NetworkEvent.Context> ctxSupplier, Consumer<NetworkEvent.Context> handler) {
|
||||
var ctx = ctxSupplier.get();
|
||||
ctx.enqueueWork(() -> handler.accept(ctx));
|
||||
ctx.setPacketHandled(true);
|
||||
PacketDistributor.PLAYER.with(player).send(RecipeCacheResetMessage.INSTANCE);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import thedarkcolour.exdeorum.ExDeorum;
|
||||
|
||||
// Server -> Client
|
||||
// Fired whenever a player joins an LAN world or dedicated server to load the recipe caches
|
||||
// Also fired whenever those servers reload data
|
||||
public class PlayerDataMessage {
|
||||
public void handle(Supplier<NetworkEvent.Context> ctxSupplier) {
|
||||
NetworkHandler.handle(ctxSupplier, ctx -> {
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> ClientMessageHandler::reloadClientRecipeCache);
|
||||
});
|
||||
public enum RecipeCacheResetMessage implements CustomPacketPayload {
|
||||
INSTANCE;
|
||||
|
||||
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.registries.BuiltInRegistries;
|
||||
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.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import thedarkcolour.exdeorum.ExDeorum;
|
||||
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 BlockPos pos;
|
||||
// Null on the client side
|
||||
|
|
@ -40,6 +41,7 @@ class VisualUpdateMessage {
|
|||
@Nullable
|
||||
final FriendlyByteBuf payload;
|
||||
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
public VisualUpdateMessage(BlockPos pos, @Nullable EBlockEntity blockEntity, @Nullable FriendlyByteBuf payload) {
|
||||
this.pos = pos;
|
||||
this.blockEntity = blockEntity;
|
||||
|
|
@ -54,20 +56,21 @@ class VisualUpdateMessage {
|
|||
}
|
||||
}
|
||||
|
||||
public static void encode(VisualUpdateMessage msg, FriendlyByteBuf buffer) {
|
||||
buffer.writeBlockPos(msg.pos);
|
||||
buffer.writeId(BuiltInRegistries.BLOCK_ENTITY_TYPE, msg.blockEntityType);
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
@Override
|
||||
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
|
||||
msg.blockEntity.writeVisualData(buffer);
|
||||
this.blockEntity.writeVisualData(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation id() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public static VisualUpdateMessage decode(FriendlyByteBuf 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.world.level.chunk.LevelChunk;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
import net.neoforged.neoforge.network.PacketDistributor;
|
||||
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
|
||||
// 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.
|
||||
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
|
||||
private static final Map<LevelChunk, Set<BlockPos>> UPDATES = new WeakHashMap<>();
|
||||
|
||||
|
|
@ -57,7 +60,7 @@ public class VisualUpdateTracker {
|
|||
|
||||
if (chunk.getBlockEntity(updatePos) instanceof EBlockEntity blockEntity) {
|
||||
// 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;
|
||||
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import thedarkcolour.exdeorum.ExDeorum;
|
||||
|
||||
// Server -> Client
|
||||
// used to tell the client to disable the cave darkness rendering in a void world
|
||||
public class VoidWorldMessage {
|
||||
public static void encode(VoidWorldMessage msg, FriendlyByteBuf packet) {
|
||||
public enum VoidWorldMessage implements CustomPacketPayload {
|
||||
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) {
|
||||
return new VoidWorldMessage();
|
||||
}
|
||||
|
||||
public static void handle(VoidWorldMessage msg, Supplier<NetworkEvent.Context> ctxSupplier) {
|
||||
NetworkHandler.handle(ctxSupplier, ctx -> {
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> ClientMessageHandler::disableVoidFogRendering);
|
||||
});
|
||||
@Override
|
||||
public ResourceLocation id() {
|
||||
return ID;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,9 +18,16 @@
|
|||
|
||||
package thedarkcolour.exdeorum.recipe;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
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.core.Registry;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
|
|
@ -36,11 +43,13 @@ import java.util.function.Predicate;
|
|||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public sealed interface BlockPredicate extends Predicate<BlockState> {
|
||||
// used for network
|
||||
byte SINGLE_BLOCK = 0, BLOCK_STATE = 1, BLOCK_TAG = 2;
|
||||
|
||||
// todo test this
|
||||
Codec<BlockPredicate> CODEC = new BlockPredicate.SpecialCodec();
|
||||
|
||||
JsonObject toJson();
|
||||
|
||||
void toNetwork(FriendlyByteBuf buffer);
|
||||
|
|
@ -70,7 +79,7 @@ public sealed interface BlockPredicate extends Predicate<BlockState> {
|
|||
if (block == Blocks.AIR) return null;
|
||||
|
||||
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 {
|
||||
return new SingleBlockPredicate(block);
|
||||
}
|
||||
|
|
@ -84,14 +93,24 @@ public sealed interface BlockPredicate extends Predicate<BlockState> {
|
|||
@Nullable
|
||||
static BlockPredicate fromNetwork(FriendlyByteBuf buffer) {
|
||||
return switch (buffer.readByte()) {
|
||||
case SINGLE_BLOCK -> new SingleBlockPredicate(buffer.readById(BuiltInRegistries.BLOCK));
|
||||
case BLOCK_STATE -> new BlockStatePredicate(buffer.readById(BuiltInRegistries.BLOCK), StatePropertiesPredicate.fromJson(JsonParser.parseString(buffer.readUtf())));
|
||||
case BLOCK_TAG -> new TagPredicate(TagKey.create(Registries.BLOCK, buffer.readResourceLocation()));
|
||||
case SINGLE_BLOCK -> new SingleBlockPredicate(Objects.requireNonNull(buffer.readById(BuiltInRegistries.BLOCK)));
|
||||
case BLOCK_STATE -> new BlockStatePredicate(Objects.requireNonNull(buffer.readById(BuiltInRegistries.BLOCK)), decodeStatePredicate(JsonParser.parseString(buffer.readUtf())));
|
||||
case BLOCK_TAG -> new TagPredicate(RecipeUtil.readTag(buffer, Registries.BLOCK));
|
||||
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 {
|
||||
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
|
||||
public JsonObject toJson() {
|
||||
var json = new JsonObject();
|
||||
|
|
@ -102,7 +121,7 @@ public sealed interface BlockPredicate extends Predicate<BlockState> {
|
|||
@Override
|
||||
public void toNetwork(FriendlyByteBuf buffer) {
|
||||
buffer.writeByte(BLOCK_TAG);
|
||||
buffer.writeResourceLocation(this.tag.location());
|
||||
RecipeUtil.writeTag(buffer, this.tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -114,16 +133,20 @@ public sealed interface BlockPredicate extends Predicate<BlockState> {
|
|||
public Stream<BlockState> possibleStates() {
|
||||
return StreamSupport.stream(BuiltInRegistries.BLOCK.getTagOrEmpty(this.tag).spliterator(), false)
|
||||
.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 {
|
||||
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
|
||||
public JsonObject toJson() {
|
||||
var json = new JsonObject();
|
||||
json.addProperty("block", BuiltInRegistries.BLOCK.getKey(this.block).toString());
|
||||
json.add("state", this.properties.serializeToJson());
|
||||
json.add("state", encodeStatePredicate(this.properties));
|
||||
return json;
|
||||
}
|
||||
|
||||
|
|
@ -131,7 +154,7 @@ public sealed interface BlockPredicate extends Predicate<BlockState> {
|
|||
public void toNetwork(FriendlyByteBuf buffer) {
|
||||
buffer.writeByte(BLOCK_STATE);
|
||||
buffer.writeId(BuiltInRegistries.BLOCK, this.block);
|
||||
buffer.writeUtf(this.properties.serializeToJson().toString());
|
||||
buffer.writeUtf(encodeStatePredicate(this.properties).toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -150,7 +173,7 @@ public sealed interface BlockPredicate extends Predicate<BlockState> {
|
|||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
import com.mojang.datafixers.Products;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
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.NumberProviders;
|
||||
|
||||
public abstract class ProbabilityRecipe extends SingleIngredientRecipe {
|
||||
public final Item result;
|
||||
public final NumberProvider resultAmount;
|
||||
|
||||
public ProbabilityRecipe(ResourceLocation id, Ingredient ingredient, Item result, NumberProvider resultAmount) {
|
||||
super(id, ingredient);
|
||||
public ProbabilityRecipe(Ingredient ingredient, Item result, NumberProvider resultAmount) {
|
||||
super(ingredient);
|
||||
this.result = result;
|
||||
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
|
||||
public ItemStack getResultItem(RegistryAccess access) {
|
||||
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;
|
||||
|
||||
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 it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectSet;
|
||||
import net.minecraft.commands.arguments.blocks.BlockStateParser;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
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.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
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.RecipeType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
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.providers.number.*;
|
||||
import net.minecraftforge.common.crafting.CraftingHelper;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.neoforged.neoforge.fluids.FluidStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import thedarkcolour.exdeorum.ExDeorum;
|
||||
import thedarkcolour.exdeorum.compat.PreferredOres;
|
||||
import thedarkcolour.exdeorum.item.HammerItem;
|
||||
import thedarkcolour.exdeorum.loot.SummationGenerator;
|
||||
import thedarkcolour.exdeorum.recipe.barrel.BarrelCompostRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.barrel.BarrelFluidMixingRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.barrel.FluidTransformationRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.barrel.BarrelMixingRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.barrel.FluidTransformationRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.cache.*;
|
||||
import thedarkcolour.exdeorum.recipe.crook.CrookRecipe;
|
||||
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.ERecipeTypes;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
|
||||
public final class RecipeUtil {
|
||||
private static final int CONSTANT_TYPE = 1;
|
||||
|
|
@ -96,7 +81,7 @@ public final class RecipeUtil {
|
|||
barrelCompostRecipeCache = new SingleIngredientRecipeCache<>(recipes, ERecipeTypes.BARREL_COMPOST);
|
||||
lavaCrucibleRecipeCache = new SingleIngredientRecipeCache<>(recipes, ERecipeTypes.LAVA_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);
|
||||
barrelFluidMixingRecipeCache = new BarrelFluidMixingRecipeCache(recipes);
|
||||
fluidTransformationRecipeCache = new FluidTransformationRecipeCache(recipes);
|
||||
|
|
@ -141,66 +126,28 @@ public final class RecipeUtil {
|
|||
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) {
|
||||
if (provider.getType() == NumberProviders.CONSTANT) {
|
||||
buffer.writeByte(CONSTANT_TYPE);
|
||||
buffer.writeFloat(((ConstantValue) provider).value);
|
||||
buffer.writeFloat(((ConstantValue) provider).value());
|
||||
} else if (provider.getType() == NumberProviders.UNIFORM) {
|
||||
var uniform = (UniformGenerator) provider;
|
||||
buffer.writeByte(UNIFORM_TYPE);
|
||||
toNetworkNumberProvider(buffer, uniform.min);
|
||||
toNetworkNumberProvider(buffer, uniform.max);
|
||||
toNetworkNumberProvider(buffer, uniform.min());
|
||||
toNetworkNumberProvider(buffer, uniform.max());
|
||||
} else if (provider.getType() == NumberProviders.BINOMIAL) {
|
||||
var binomial = (BinomialDistributionGenerator) provider;
|
||||
buffer.writeByte(BINOMIAL_TYPE);
|
||||
toNetworkNumberProvider(buffer, binomial.n);
|
||||
toNetworkNumberProvider(buffer, binomial.p);
|
||||
toNetworkNumberProvider(buffer, binomial.n());
|
||||
toNetworkNumberProvider(buffer, binomial.p());
|
||||
} else if (provider.getType() == ENumberProviders.SUMMATION.get()) {
|
||||
var summation = (SummationGenerator) provider;
|
||||
var providers = summation.providers();
|
||||
int length = providers.length;
|
||||
int length = providers.size();
|
||||
buffer.writeByte(SUMMATION_TYPE);
|
||||
buffer.writeByte(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
toNetworkNumberProvider(buffer, providers[i]);
|
||||
toNetworkNumberProvider(buffer, providers.get(i));
|
||||
}
|
||||
} else {
|
||||
buffer.writeByte(UNKNOWN_TYPE);
|
||||
|
|
@ -220,7 +167,7 @@ public final class RecipeUtil {
|
|||
for (int i = 0; i < length; i++) {
|
||||
providers[i] = fromNetworkNumberProvider(buffer);
|
||||
}
|
||||
yield new SummationGenerator(providers);
|
||||
yield new SummationGenerator(List.of(providers));
|
||||
}
|
||||
default -> ConstantValue.exactly(1f);
|
||||
};
|
||||
|
|
@ -231,7 +178,7 @@ public final class RecipeUtil {
|
|||
// although unlikely, we should check this anyway
|
||||
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 secondValues = new ObjectArrayList<>(second.values);
|
||||
|
||||
|
|
@ -270,11 +217,11 @@ public final class RecipeUtil {
|
|||
if (firstKlass == secondKlass) {
|
||||
if (firstKlass == Ingredient.ItemValue.class) {
|
||||
// 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) {
|
||||
// if tags are different, return false
|
||||
// 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 {
|
||||
var firstItems = firstValue.getItems();
|
||||
var secondItems = secondValue.getItems();
|
||||
|
|
@ -311,9 +258,9 @@ public final class RecipeUtil {
|
|||
// todo stop using the RecipeManager
|
||||
@Nullable
|
||||
public static BarrelMixingRecipe getBarrelMixingRecipe(RecipeManager recipes, ItemStack stack, FluidStack fluid) {
|
||||
for (var recipe : byType(recipes, ERecipeTypes.BARREL_MIXING.get())) {
|
||||
if (recipe.matches(stack, fluid)) {
|
||||
return recipe;
|
||||
for (var recipe : recipes.byType(ERecipeTypes.BARREL_MIXING.get()).values()) {
|
||||
if (recipe.value().matches(stack, fluid)) {
|
||||
return recipe.value();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -323,7 +270,7 @@ public final class RecipeUtil {
|
|||
@Nullable
|
||||
public static BarrelFluidMixingRecipe getFluidMixingRecipe(FluidStack base, Fluid additive) {
|
||||
var recipe = barrelFluidMixingRecipeCache.getRecipe(base.getFluid(), additive);
|
||||
if (recipe != null && base.getAmount() >= recipe.baseFluidAmount) {
|
||||
if (recipe != null && base.getAmount() >= recipe.baseFluidAmount()) {
|
||||
return recipe;
|
||||
} else {
|
||||
return null;
|
||||
|
|
@ -341,11 +288,11 @@ public final class RecipeUtil {
|
|||
|
||||
public static double getExpectedValue(NumberProvider provider) {
|
||||
if (provider instanceof ConstantValue constant) {
|
||||
return constant.value;
|
||||
return constant.value();
|
||||
} 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) {
|
||||
return getExpectedValue(binomial.n) * getExpectedValue(binomial.p);
|
||||
return getExpectedValue(binomial.n()) * getExpectedValue(binomial.p());
|
||||
} else if (provider instanceof SummationGenerator summation) {
|
||||
double avgSum = 0.0;
|
||||
|
||||
|
|
@ -366,33 +313,21 @@ public final class RecipeUtil {
|
|||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
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) {
|
||||
public static BlockPredicate readBlockPredicateNetwork(FriendlyByteBuf buffer) {
|
||||
BlockPredicate blockPredicate = BlockPredicate.fromNetwork(buffer);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static boolean isTagEmpty(TagKey<Item> tag) {
|
||||
return BuiltInRegistries.ITEM.getTag(tag).map(set -> !set.iterator().hasNext()).orElse(PreferredOres.getPreferredOre(tag) == Items.AIR);
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
@ -407,46 +342,14 @@ public final class RecipeUtil {
|
|||
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"})
|
||||
public static JsonPrimitive writeBlockState(BlockState state) {
|
||||
public static String writeBlockState(BlockState state) {
|
||||
var registryKey = BuiltInRegistries.BLOCK.getKey(state.getBlock());
|
||||
|
||||
Collection<Property> properties = (Collection<Property>) ((Collection)state.getProperties());
|
||||
|
||||
if (properties.isEmpty()) {
|
||||
return new JsonPrimitive(registryKey.toString());
|
||||
return registryKey.toString();
|
||||
} else {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(registryKey);
|
||||
|
|
@ -461,7 +364,7 @@ public final class RecipeUtil {
|
|||
}
|
||||
}
|
||||
builder.append(']');
|
||||
return new JsonPrimitive(builder.toString());
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -473,11 +376,11 @@ public final class RecipeUtil {
|
|||
}
|
||||
}
|
||||
|
||||
public static String getFluidId(Fluid baseFluid) {
|
||||
return BuiltInRegistries.FLUID.getKey(baseFluid).toString();
|
||||
public static void writeTag(FriendlyByteBuf buffer, TagKey<?> ore) {
|
||||
buffer.writeResourceLocation(ore.location());
|
||||
}
|
||||
|
||||
public static String writeItemJson(Item result) {
|
||||
return BuiltInRegistries.ITEM.getKey(result).toString();
|
||||
public static <T> TagKey<T> readTag(FriendlyByteBuf buffer, ResourceKey<Registry<T>> registry) {
|
||||
return TagKey.create(registry, buffer.readResourceLocation());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ package thedarkcolour.exdeorum.recipe;
|
|||
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
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.
|
||||
*/
|
||||
public abstract class SingleIngredientRecipe implements Recipe<Container> {
|
||||
private final ResourceLocation id;
|
||||
public final Ingredient ingredient;
|
||||
public final boolean dependsOnNbt;
|
||||
|
||||
public SingleIngredientRecipe(ResourceLocation id, Ingredient ingredient) {
|
||||
this.id = id;
|
||||
public SingleIngredientRecipe(Ingredient ingredient) {
|
||||
this.ingredient = ingredient;
|
||||
this.dependsOnNbt = !ingredient.isSimple();
|
||||
}
|
||||
|
|
@ -63,11 +60,6 @@ public abstract class SingleIngredientRecipe implements Recipe<Container> {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getResultItem(RegistryAccess access) {
|
||||
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.JsonObject;
|
||||
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.objects.ObjectImmutableList;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.util.RandomSource;
|
||||
|
|
@ -92,10 +95,6 @@ public class WeightedList<T> {
|
|||
return result;
|
||||
}
|
||||
|
||||
public static <T> Builder<T> builder() {
|
||||
return new Builder<>();
|
||||
}
|
||||
|
||||
public static <T> WeightedList<T> fromNetwork(FriendlyByteBuf buffer, Function<FriendlyByteBuf, T> valueReader) {
|
||||
int size = buffer.readVarInt();
|
||||
Object[] values = new Object[size];
|
||||
|
|
@ -142,6 +141,39 @@ public class WeightedList<T> {
|
|||
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> {
|
||||
private final ArrayList<T> values = new ArrayList<>();
|
||||
private final IntArrayList weights = new IntArrayList();
|
||||
|
|
|
|||
|
|
@ -18,23 +18,27 @@
|
|||
|
||||
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.resources.ResourceLocation;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.item.crafting.Ingredient;
|
||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||
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.registry.ERecipeSerializers;
|
||||
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
||||
|
||||
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;
|
||||
|
||||
public BarrelCompostRecipe(ResourceLocation id, Ingredient ingredient, int volume) {
|
||||
super(id, ingredient);
|
||||
public BarrelCompostRecipe(Ingredient ingredient, int volume) {
|
||||
super(ingredient);
|
||||
|
||||
this.volume = volume;
|
||||
}
|
||||
|
|
@ -54,12 +58,9 @@ public class BarrelCompostRecipe extends SingleIngredientRecipe {
|
|||
}
|
||||
|
||||
public static class Serializer implements RecipeSerializer<BarrelCompostRecipe> {
|
||||
@Override // Creates the recipe object from a JSON file
|
||||
public BarrelCompostRecipe fromJson(ResourceLocation name, JsonObject json) {
|
||||
Ingredient ingredient = RecipeUtil.readIngredient(json, "ingredient");
|
||||
int volume = GsonHelper.getAsInt(json, "volume");
|
||||
|
||||
return new BarrelCompostRecipe(name, ingredient, volume);
|
||||
@Override
|
||||
public Codec<BarrelCompostRecipe> codec() {
|
||||
return CODEC;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -69,11 +70,11 @@ public class BarrelCompostRecipe extends SingleIngredientRecipe {
|
|||
}
|
||||
|
||||
@Override
|
||||
public BarrelCompostRecipe fromNetwork(ResourceLocation name, FriendlyByteBuf buffer) {
|
||||
public BarrelCompostRecipe fromNetwork(FriendlyByteBuf buffer) {
|
||||
Ingredient ingredient = Ingredient.fromNetwork(buffer);
|
||||
int volume = buffer.readVarInt();
|
||||
|
||||
return new BarrelCompostRecipe(name, ingredient, volume);
|
||||
return new BarrelCompostRecipe(ingredient, volume);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,11 +18,11 @@
|
|||
|
||||
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.registries.BuiltInRegistries;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.item.Item;
|
||||
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.level.Level;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
||||
import thedarkcolour.exdeorum.recipe.CodecUtil;
|
||||
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
||||
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
// 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 is not consumed, however. Additives placed in the world are not consumed,
|
||||
// so it would be unfair to consume the handheld additive.
|
||||
public class BarrelFluidMixingRecipe implements Recipe<Container> {
|
||||
private final ResourceLocation id;
|
||||
|
||||
public final Fluid baseFluid;
|
||||
public final int baseFluidAmount;
|
||||
public final Fluid additiveFluid;
|
||||
public final Item result;
|
||||
public final boolean consumesAdditive;
|
||||
|
||||
public BarrelFluidMixingRecipe(ResourceLocation id, Fluid baseFluid, int baseFluidAmount, Fluid additiveFluid, Item result, boolean consumesAdditive) {
|
||||
this.id = id;
|
||||
this.baseFluid = baseFluid;
|
||||
this.baseFluidAmount = baseFluidAmount;
|
||||
this.additiveFluid = additiveFluid;
|
||||
this.result = result;
|
||||
this.consumesAdditive = consumesAdditive;
|
||||
}
|
||||
public record BarrelFluidMixingRecipe(
|
||||
Fluid baseFluid,
|
||||
int baseFluidAmount,
|
||||
Fluid additiveFluid,
|
||||
Item result,
|
||||
boolean consumesAdditive
|
||||
) implements Recipe<Container> {
|
||||
public static final Codec<BarrelFluidMixingRecipe> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||
CodecUtil.fluidField("base_fluid", BarrelFluidMixingRecipe::baseFluid),
|
||||
Codec.INT.fieldOf("base_fluid_amount").forGetter(BarrelFluidMixingRecipe::baseFluidAmount),
|
||||
CodecUtil.fluidField("additive_fluid", BarrelFluidMixingRecipe::baseFluid),
|
||||
CodecUtil.itemField("result", BarrelFluidMixingRecipe::result),
|
||||
Codec.BOOL.optionalFieldOf("base_fluid", false).forGetter(BarrelFluidMixingRecipe::consumesAdditive)
|
||||
).apply(instance, BarrelFluidMixingRecipe::new));
|
||||
|
||||
@Override
|
||||
public boolean matches(Container pContainer, Level pLevel) {
|
||||
|
|
@ -79,11 +76,6 @@ public class BarrelFluidMixingRecipe implements Recipe<Container> {
|
|||
return new ItemStack(this.result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeSerializer<?> getSerializer() {
|
||||
return ERecipeSerializers.BARREL_FLUID_MIXING.get();
|
||||
|
|
@ -96,34 +88,28 @@ public class BarrelFluidMixingRecipe implements Recipe<Container> {
|
|||
|
||||
public static class Serializer implements RecipeSerializer<BarrelFluidMixingRecipe> {
|
||||
@Override
|
||||
public BarrelFluidMixingRecipe fromJson(ResourceLocation id, JsonObject json) {
|
||||
Fluid baseFluid = RecipeUtil.readFluid(json, "base_fluid");
|
||||
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);
|
||||
public Codec<BarrelFluidMixingRecipe> codec() {
|
||||
return CODEC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toNetwork(FriendlyByteBuf buffer, BarrelFluidMixingRecipe recipe) {
|
||||
buffer.writeRegistryId(ForgeRegistries.FLUIDS, recipe.baseFluid);
|
||||
buffer.writeId(BuiltInRegistries.FLUID, recipe.baseFluid);
|
||||
buffer.writeVarInt(recipe.baseFluidAmount);
|
||||
buffer.writeRegistryId(ForgeRegistries.FLUIDS, recipe.additiveFluid);
|
||||
buffer.writeRegistryId(ForgeRegistries.ITEMS, recipe.result);
|
||||
buffer.writeId(BuiltInRegistries.FLUID, recipe.additiveFluid);
|
||||
buffer.writeId(BuiltInRegistries.ITEM, recipe.result);
|
||||
buffer.writeBoolean(recipe.consumesAdditive);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BarrelFluidMixingRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf buffer) {
|
||||
Fluid baseFluid = buffer.readRegistryId();
|
||||
public BarrelFluidMixingRecipe fromNetwork(FriendlyByteBuf buffer) {
|
||||
Fluid baseFluid = Objects.requireNonNull(buffer.readById(BuiltInRegistries.FLUID));
|
||||
int baseFluidAmount = buffer.readVarInt();
|
||||
Fluid additiveFluid = buffer.readRegistryId();
|
||||
Item result = buffer.readRegistryId();
|
||||
Fluid additiveFluid = Objects.requireNonNull(buffer.readById(BuiltInRegistries.FLUID));
|
||||
Item result = Objects.requireNonNull(buffer.readById(BuiltInRegistries.ITEM));
|
||||
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;
|
||||
|
||||
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.registries.BuiltInRegistries;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.item.Item;
|
||||
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.level.Level;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
||||
import net.neoforged.neoforge.fluids.FluidStack;
|
||||
import thedarkcolour.exdeorum.recipe.CodecUtil;
|
||||
import thedarkcolour.exdeorum.recipe.SingleIngredientRecipe;
|
||||
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
||||
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
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 int fluidAmount;
|
||||
public final Item result;
|
||||
|
||||
public BarrelMixingRecipe(ResourceLocation id, Ingredient ingredient, Fluid fluid, int fluidAmount, Item result) {
|
||||
super(id, ingredient);
|
||||
public BarrelMixingRecipe(Ingredient ingredient, Fluid fluid, int fluidAmount, Item result) {
|
||||
super(ingredient);
|
||||
this.fluid = fluid;
|
||||
this.fluidAmount = fluidAmount;
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public Fluid getFluid() {
|
||||
return this.fluid;
|
||||
}
|
||||
|
||||
public int getFluidAmount() {
|
||||
return this.fluidAmount;
|
||||
}
|
||||
|
||||
public Item getResult() {
|
||||
return this.result;
|
||||
}
|
||||
|
||||
// Do not use
|
||||
@Override
|
||||
@Deprecated
|
||||
|
|
@ -79,31 +98,26 @@ public class BarrelMixingRecipe extends SingleIngredientRecipe {
|
|||
|
||||
public static class Serializer implements RecipeSerializer<BarrelMixingRecipe> {
|
||||
@Override
|
||||
public BarrelMixingRecipe fromJson(ResourceLocation id, JsonObject json) {
|
||||
Ingredient ingredient = RecipeUtil.readIngredient(json, "ingredient");
|
||||
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);
|
||||
public Codec<BarrelMixingRecipe> codec() {
|
||||
return CODEC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toNetwork(FriendlyByteBuf buffer, BarrelMixingRecipe recipe) {
|
||||
recipe.ingredient.toNetwork(buffer);
|
||||
buffer.writeRegistryId(ForgeRegistries.FLUIDS, recipe.fluid);
|
||||
buffer.writeId(BuiltInRegistries.FLUID, recipe.fluid);
|
||||
buffer.writeVarInt(recipe.fluidAmount);
|
||||
buffer.writeRegistryId(ForgeRegistries.ITEMS, recipe.result);
|
||||
buffer.writeId(BuiltInRegistries.ITEM, recipe.result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable BarrelMixingRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf buffer) {
|
||||
public BarrelMixingRecipe fromNetwork(FriendlyByteBuf buffer) {
|
||||
Ingredient ingredient = Ingredient.fromNetwork(buffer);
|
||||
Fluid fluid = buffer.readRegistryId();
|
||||
Fluid fluid = Objects.requireNonNull(buffer.readById(BuiltInRegistries.FLUID));
|
||||
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;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
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.state.BlockState;
|
||||
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.CodecUtil;
|
||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
||||
import thedarkcolour.exdeorum.recipe.WeightedList;
|
||||
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
||||
|
|
@ -46,25 +42,22 @@ import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
|||
import java.util.Objects;
|
||||
|
||||
// todo consider NBT tag of input fluid?
|
||||
public class FluidTransformationRecipe implements Recipe<Container> {
|
||||
private final ResourceLocation id;
|
||||
|
||||
public final Fluid baseFluid;
|
||||
public final Fluid resultFluid;
|
||||
public final int resultColor;
|
||||
public final BlockPredicate catalyst;
|
||||
public final WeightedList<BlockState> byproducts;
|
||||
public final int duration;
|
||||
|
||||
public FluidTransformationRecipe(ResourceLocation id, Fluid baseFluid, Fluid resultFluid, int resultColor, BlockPredicate catalyst, WeightedList<BlockState> byproducts, int duration) {
|
||||
this.id = id;
|
||||
this.baseFluid = baseFluid;
|
||||
this.resultFluid = resultFluid;
|
||||
this.resultColor = resultColor;
|
||||
this.catalyst = catalyst;
|
||||
this.byproducts = byproducts;
|
||||
this.duration = duration;
|
||||
}
|
||||
public record FluidTransformationRecipe(
|
||||
Fluid baseFluid,
|
||||
Fluid resultFluid,
|
||||
int resultColor,
|
||||
BlockPredicate catalyst,
|
||||
WeightedList<BlockState> byproducts,
|
||||
int duration
|
||||
) implements Recipe<Container> {
|
||||
public static final Codec<FluidTransformationRecipe> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||
CodecUtil.fluidField("base_fluid", FluidTransformationRecipe::baseFluid),
|
||||
CodecUtil.fluidField("result_fluid", FluidTransformationRecipe::resultFluid),
|
||||
Codec.INT.fieldOf("result_color").forGetter(FluidTransformationRecipe::resultColor),
|
||||
BlockPredicate.CODEC.fieldOf("catalyst").forGetter(FluidTransformationRecipe::catalyst),
|
||||
WeightedList.codec(Codec.STRING.xmap(RecipeUtil::parseBlockState, RecipeUtil::writeBlockState)).fieldOf("byproducts").forGetter(FluidTransformationRecipe::byproducts),
|
||||
Codec.INT.fieldOf("duration").forGetter(FluidTransformationRecipe::duration)
|
||||
).apply(instance, FluidTransformationRecipe::new));
|
||||
|
||||
@Override
|
||||
public boolean matches(Container pContainer, Level pLevel) {
|
||||
|
|
@ -86,11 +79,6 @@ public class FluidTransformationRecipe implements Recipe<Container> {
|
|||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeSerializer<?> getSerializer() {
|
||||
return ERecipeSerializers.BARREL_FLUID_TRANSFORMATION.get();
|
||||
|
|
@ -103,32 +91,14 @@ public class FluidTransformationRecipe implements Recipe<Container> {
|
|||
|
||||
public static class Serializer implements RecipeSerializer<FluidTransformationRecipe> {
|
||||
@Override
|
||||
public FluidTransformationRecipe fromJson(ResourceLocation id, JsonObject json) {
|
||||
Fluid baseFluid = RecipeUtil.readFluid(json, "base_fluid");
|
||||
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);
|
||||
public Codec<FluidTransformationRecipe> codec() {
|
||||
return CODEC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toNetwork(FriendlyByteBuf buffer, FluidTransformationRecipe recipe) {
|
||||
buffer.writeRegistryId(ForgeRegistries.FLUIDS, recipe.baseFluid);
|
||||
buffer.writeRegistryId(ForgeRegistries.FLUIDS, recipe.resultFluid);
|
||||
buffer.writeId(BuiltInRegistries.FLUID, recipe.baseFluid);
|
||||
buffer.writeId(BuiltInRegistries.FLUID, recipe.resultFluid);
|
||||
buffer.writeInt(recipe.resultColor);
|
||||
recipe.catalyst.toNetwork(buffer);
|
||||
recipe.byproducts.toNetwork(buffer, (buf, state) -> buf.writeId(Block.BLOCK_STATE_REGISTRY, state));
|
||||
|
|
@ -136,30 +106,15 @@ public class FluidTransformationRecipe implements Recipe<Container> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public @Nullable FluidTransformationRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf buffer) {
|
||||
Fluid baseFluid = buffer.readRegistryId();
|
||||
Fluid resultFluid = buffer.readRegistryId();
|
||||
public FluidTransformationRecipe fromNetwork(FriendlyByteBuf buffer) {
|
||||
Fluid baseFluid = Objects.requireNonNull(buffer.readById(BuiltInRegistries.FLUID));
|
||||
Fluid resultFluid = Objects.requireNonNull(buffer.readById(BuiltInRegistries.FLUID));
|
||||
int resultColor = buffer.readInt();
|
||||
BlockPredicate catalyst = RecipeUtil.readBlockPredicateNetwork(id, buffer);
|
||||
if (catalyst == null) {
|
||||
return null;
|
||||
}
|
||||
BlockPredicate catalyst = RecipeUtil.readBlockPredicateNetwork(buffer);
|
||||
WeightedList<BlockState> byproducts = WeightedList.fromNetwork(buffer, buf -> buf.readById(Block.BLOCK_STATE_REGISTRY));
|
||||
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() {
|
||||
this.recipes = new HashMap<>();
|
||||
|
||||
for (var recipe : this.recipeManager.byType(ERecipeTypes.BARREL_FLUID_MIXING.get()).values()) {
|
||||
this.recipes.computeIfAbsent(recipe.baseFluid, key -> new HashMap<>()).put(recipe.additiveFluid, recipe);
|
||||
for (var holder : this.recipeManager.byType(ERecipeTypes.BARREL_FLUID_MIXING.get()).values()) {
|
||||
var recipe = holder.value();
|
||||
this.recipes.computeIfAbsent(recipe.baseFluid(), key -> new HashMap<>()).put(recipe.additiveFluid(), recipe);
|
||||
}
|
||||
|
||||
this.recipeManager = null;
|
||||
|
|
|
|||
|
|
@ -49,8 +49,8 @@ public class CrookRecipeCache {
|
|||
var tempRecipes = new HashMap<BlockState, HashSet<CrookRecipe>>();
|
||||
|
||||
for (var recipe : this.recipeManager.byType(ERecipeTypes.CROOK.get()).values()) {
|
||||
recipe.blockPredicate().possibleStates().forEach(state -> {
|
||||
tempRecipes.computeIfAbsent(state, key -> new HashSet<>()).add(recipe);
|
||||
recipe.value().blockPredicate().possibleStates().forEach(state -> {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -45,8 +45,9 @@ public class CrucibleHeatRecipeCache {
|
|||
private void buildRecipes() {
|
||||
this.recipes = new Object2IntOpenHashMap<>();
|
||||
|
||||
for (var recipe : this.recipeManager.byType(ERecipeTypes.CRUCIBLE_HEAT_SOURCE.get()).values()) {
|
||||
recipe.blockPredicate().possibleStates().forEach(state -> recipes.put(state, recipe.heatValue()));
|
||||
for (var holder : this.recipeManager.byType(ERecipeTypes.CRUCIBLE_HEAT_SOURCE.get()).values()) {
|
||||
var recipe = holder.value();
|
||||
recipe.blockPredicate().possibleStates().forEach(state -> this.recipes.put(state, recipe.heatValue()));
|
||||
}
|
||||
|
||||
this.recipeManager = null;
|
||||
|
|
|
|||
|
|
@ -52,9 +52,10 @@ public class FluidTransformationRecipeCache {
|
|||
private void buildRecipes() {
|
||||
this.recipes = new HashMap<>();
|
||||
|
||||
for (var recipe : this.recipeManager.byType(ERecipeTypes.BARREL_FLUID_TRANSFORMATION.get()).values()) {
|
||||
recipe.catalyst.possibleStates().forEach(state -> {
|
||||
this.recipes.computeIfAbsent(state, key -> new HashMap<>()).put(recipe.baseFluid, recipe);
|
||||
for (var holder : this.recipeManager.byType(ERecipeTypes.BARREL_FLUID_TRANSFORMATION.get()).values()) {
|
||||
var recipe = holder.value();
|
||||
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() {
|
||||
// Group recipes based on their mesh
|
||||
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);
|
||||
}
|
||||
this.meshCaches = new HashMap<>();
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ package thedarkcolour.exdeorum.recipe.cache;
|
|||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraft.world.item.Item;
|
||||
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.RecipeType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
|
@ -39,20 +40,12 @@ public class SingleIngredientRecipeCache<T extends SingleIngredientRecipe> {
|
|||
private Map<Item, T> simpleRecipes;
|
||||
@Nullable
|
||||
private List<T> complexRecipes;
|
||||
@Nullable
|
||||
private Collection<T> allRecipes;
|
||||
private boolean trackAllRecipes;
|
||||
|
||||
public SingleIngredientRecipeCache(RecipeManager recipeManager, Supplier<RecipeType<T>> recipeType) {
|
||||
this.recipeType = recipeType;
|
||||
this.recipeManager = recipeManager;
|
||||
}
|
||||
|
||||
public SingleIngredientRecipeCache<T> trackAllRecipes() {
|
||||
this.trackAllRecipes = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public T getRecipe(Item 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"
|
||||
* 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"
|
||||
* 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}
|
||||
* 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
|
||||
* complexRecipes may be null after this method call if no complex recipes are found. Finally, after all recipes
|
||||
* have been scanned, the {@link #recipeManager} is set to null, since it is no longer needed.
|
||||
*/
|
||||
private void buildRecipes() {
|
||||
|
|
@ -104,7 +88,8 @@ public class SingleIngredientRecipeCache<T extends SingleIngredientRecipe> {
|
|||
|
||||
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();
|
||||
|
||||
if (ingredient.isSimple()) {
|
||||
|
|
@ -120,10 +105,6 @@ public class SingleIngredientRecipeCache<T extends SingleIngredientRecipe> {
|
|||
if (this.complexRecipes.isEmpty()) {
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,25 +18,33 @@
|
|||
|
||||
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.registries.BuiltInRegistries;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.item.Item;
|
||||
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.RecipeSerializer;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.minecraft.world.level.Level;
|
||||
import thedarkcolour.exdeorum.recipe.BlockPredicate;
|
||||
import thedarkcolour.exdeorum.recipe.CodecUtil;
|
||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
||||
import thedarkcolour.exdeorum.registry.ERecipeSerializers;
|
||||
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
|
||||
public boolean matches(Container pContainer, Level pLevel) {
|
||||
return false;
|
||||
|
|
@ -57,11 +65,6 @@ public record CrookRecipe(ResourceLocation id, BlockPredicate blockPredicate, It
|
|||
return new ItemStack(this.result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeSerializer<?> getSerializer() {
|
||||
return ERecipeSerializers.CROOK.get();
|
||||
|
|
@ -72,32 +75,19 @@ public record CrookRecipe(ResourceLocation id, BlockPredicate blockPredicate, It
|
|||
return ERecipeTypes.CROOK.get();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static class Serializer implements RecipeSerializer<CrookRecipe> {
|
||||
@Override
|
||||
public CrookRecipe fromJson(ResourceLocation id, JsonObject json) {
|
||||
BlockPredicate blockPredicate = RecipeUtil.readBlockPredicate(id, json, "block_predicate");
|
||||
if (blockPredicate == null) return null;
|
||||
|
||||
Item result = RecipeUtil.readItem(json, "result");
|
||||
float chance = json.get("chance").getAsFloat();
|
||||
|
||||
|
||||
return new CrookRecipe(id, blockPredicate, result, chance);
|
||||
public Codec<CrookRecipe> codec() {
|
||||
return CODEC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CrookRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf buffer) {
|
||||
BlockPredicate blockPredicate = RecipeUtil.readBlockPredicateNetwork(id, buffer);
|
||||
if (blockPredicate == null) return null;
|
||||
|
||||
Item result = buffer.readById(BuiltInRegistries.ITEM);
|
||||
if (result == null || result == Items.AIR) {
|
||||
return null;
|
||||
}
|
||||
public CrookRecipe fromNetwork(FriendlyByteBuf buffer) {
|
||||
BlockPredicate blockPredicate = RecipeUtil.readBlockPredicateNetwork(buffer);
|
||||
Item result = Objects.requireNonNull(buffer.readById(BuiltInRegistries.ITEM));
|
||||
float chance = buffer.readFloat();
|
||||
|
||||
return new CrookRecipe(id, blockPredicate, result, chance);
|
||||
return new CrookRecipe(blockPredicate, result, chance);
|
||||
}
|
||||
|
||||
@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;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
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.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
|
||||
public boolean matches(Container pContainer, Level pLevel) {
|
||||
return false;
|
||||
|
|
@ -54,11 +59,6 @@ public record CrucibleHeatRecipe(ResourceLocation id, BlockPredicate blockPredic
|
|||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeSerializer<?> getSerializer() {
|
||||
return ERecipeSerializers.CRUCIBLE_HEAT_SOURCE.get();
|
||||
|
|
@ -71,19 +71,15 @@ public record CrucibleHeatRecipe(ResourceLocation id, BlockPredicate blockPredic
|
|||
|
||||
public static class Serializer implements RecipeSerializer<CrucibleHeatRecipe> {
|
||||
@Override
|
||||
public CrucibleHeatRecipe fromJson(ResourceLocation id, JsonObject json) {
|
||||
BlockPredicate blockPredicate = RecipeUtil.readBlockPredicate(id, json, "block_predicate");
|
||||
if (blockPredicate == null) return null;
|
||||
int heatValue = json.get("heat_value").getAsInt();
|
||||
return new CrucibleHeatRecipe(id, blockPredicate, heatValue);
|
||||
public Codec<CrucibleHeatRecipe> codec() {
|
||||
return CODEC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CrucibleHeatRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf buffer) {
|
||||
BlockPredicate blockPredicate = RecipeUtil.readBlockPredicateNetwork(id, buffer);
|
||||
if (blockPredicate == null) return null;
|
||||
public CrucibleHeatRecipe fromNetwork(FriendlyByteBuf buffer) {
|
||||
BlockPredicate blockPredicate = RecipeUtil.readBlockPredicateNetwork(buffer);
|
||||
int heatValue = buffer.readVarInt();
|
||||
return new CrucibleHeatRecipe(id, blockPredicate, heatValue);
|
||||
return new CrucibleHeatRecipe(blockPredicate, heatValue);
|
||||
}
|
||||
|
||||
@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