Move processing type determining logic to its own registry

This commit is contained in:
Lgmrszd 2023-07-19 10:00:15 +03:00
parent a411666dc8
commit 50e7140900
No known key found for this signature in database
GPG key ID: D8E0CC2BFF5D4D9B
3 changed files with 95 additions and 43 deletions

View file

@ -1,29 +1,19 @@
package com.simibubi.create.content.kinetics.fan;
import com.google.common.collect.Maps;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
import com.simibubi.create.content.processing.burner.LitBlazeBurnerBlock;
import net.minecraft.core.BlockPos;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.CampfireBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.phys.Vec3;
import java.util.List;
import java.util.Map;
import static com.simibubi.create.content.processing.burner.BlazeBurnerBlock.getHeatLevelOf;
/**
* Make Class extending this if you want to add your own Fan processing type.
* After that, register it's condition using {@link ProcessingTypeTransformerRegistry#registerProcessingTypeTransformer(int, ProcessingTypeTransformerRegistry.ProcessingTypeTransformer)}
*/
public abstract class AbstractFanProcessingType {
public static final Map<String, AbstractFanProcessingType> REGISTRY = Maps.newConcurrentMap();
@ -74,34 +64,6 @@ public abstract class AbstractFanProcessingType {
public abstract List<ItemStack> process(ItemStack stack, AbstractFanProcessingType type, Level world);
public static AbstractFanProcessingType byBlock(BlockGetter reader, BlockPos pos) {
FluidState fluidState = reader.getFluidState(pos);
if (fluidState.getType() == Fluids.WATER || fluidState.getType() == Fluids.FLOWING_WATER)
return FanProcessing.SPLASHING;
BlockState blockState = reader.getBlockState(pos);
Block block = blockState.getBlock();
if (block == Blocks.SOUL_FIRE
|| block == Blocks.SOUL_CAMPFIRE && blockState.getOptionalValue(CampfireBlock.LIT)
.orElse(false)
|| AllBlocks.LIT_BLAZE_BURNER.has(blockState)
&& blockState.getOptionalValue(LitBlazeBurnerBlock.FLAME_TYPE)
.map(flame -> flame == LitBlazeBurnerBlock.FlameType.SOUL)
.orElse(false))
return FanProcessing.HAUNTING;
if (block == Blocks.FIRE
|| blockState.is(BlockTags.CAMPFIRES) && blockState.getOptionalValue(CampfireBlock.LIT)
.orElse(false)
|| AllBlocks.LIT_BLAZE_BURNER.has(blockState)
&& blockState.getOptionalValue(LitBlazeBurnerBlock.FLAME_TYPE)
.map(flame -> flame == LitBlazeBurnerBlock.FlameType.REGULAR)
.orElse(false)
|| getHeatLevelOf(blockState) == BlazeBurnerBlock.HeatLevel.SMOULDERING)
return FanProcessing.SMOKING;
if (block == Blocks.LAVA || getHeatLevelOf(blockState).isAtLeast(BlazeBurnerBlock.HeatLevel.FADING))
return FanProcessing.BLASTING;
return AbstractFanProcessingType.NONE;
}
public static AbstractFanProcessingType valueOf(String name) {
return REGISTRY.getOrDefault(name, NONE);
}

View file

@ -163,7 +163,7 @@ public class AirCurrent {
for (int i = searchStart; i * searchStep <= searchEnd * searchStep; i += searchStep) {
BlockPos currentPos = start.relative(direction, i);
AbstractFanProcessingType newType = AbstractFanProcessingType.byBlock(world, currentPos);
AbstractFanProcessingType newType = ProcessingTypeTransformerRegistry.byBlock(world, currentPos);
if (newType != AbstractFanProcessingType.NONE)
type = newType;
if (currentSegment.type != type || currentSegment.startOffset == 0) {
@ -216,6 +216,9 @@ public class AirCurrent {
BlockState copycatState = CopycatBlock.getMaterial(world, currentPos);
if (shouldAlwaysPass(copycatState.isAir() ? state : copycatState))
continue;
// If there's defined Processing Type for the block, it's probably passable for the Air Current
if (ProcessingTypeTransformerRegistry.byBlock(world, currentPos) != AbstractFanProcessingType.NONE)
continue;
VoxelShape voxelshape = state.getCollisionShape(world, currentPos, CollisionContext.empty());
if (voxelshape.isEmpty())
continue;

View file

@ -0,0 +1,87 @@
package com.simibubi.create.content.kinetics.fan;
import com.google.common.collect.Lists;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
import com.simibubi.create.content.processing.burner.LitBlazeBurnerBlock;
import com.simibubi.create.foundation.utility.Pair;
import net.minecraft.core.BlockPos;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.CampfireBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.function.BiFunction;
import static com.simibubi.create.content.processing.burner.BlazeBurnerBlock.getHeatLevelOf;
public class ProcessingTypeTransformerRegistry {
private static final List<Pair<Integer, ProcessingTypeTransformer>> REG = Lists.newArrayList();
private static List<ProcessingTypeTransformer> REG_SORTED = Collections.emptyList();
static {
registerProcessingTypeTransformer(0, (BlockGetter reader, BlockPos pos) -> {
FluidState fluidState = reader.getFluidState(pos);
if (fluidState.getType() == Fluids.WATER || fluidState.getType() == Fluids.FLOWING_WATER)
return FanProcessing.SPLASHING;
BlockState blockState = reader.getBlockState(pos);
Block block = blockState.getBlock();
if (block == Blocks.SOUL_FIRE
|| block == Blocks.SOUL_CAMPFIRE && blockState.getOptionalValue(CampfireBlock.LIT)
.orElse(false)
|| AllBlocks.LIT_BLAZE_BURNER.has(blockState)
&& blockState.getOptionalValue(LitBlazeBurnerBlock.FLAME_TYPE)
.map(flame -> flame == LitBlazeBurnerBlock.FlameType.SOUL)
.orElse(false))
return FanProcessing.HAUNTING;
if (block == Blocks.FIRE
|| blockState.is(BlockTags.CAMPFIRES) && blockState.getOptionalValue(CampfireBlock.LIT)
.orElse(false)
|| AllBlocks.LIT_BLAZE_BURNER.has(blockState)
&& blockState.getOptionalValue(LitBlazeBurnerBlock.FLAME_TYPE)
.map(flame -> flame == LitBlazeBurnerBlock.FlameType.REGULAR)
.orElse(false)
|| getHeatLevelOf(blockState) == BlazeBurnerBlock.HeatLevel.SMOULDERING)
return FanProcessing.SMOKING;
if (block == Blocks.LAVA || getHeatLevelOf(blockState).isAtLeast(BlazeBurnerBlock.HeatLevel.FADING))
return FanProcessing.BLASTING;
return AbstractFanProcessingType.NONE;
});
}
/**
* Add Air Current Transformation.
* @param priority Priority of this transform (smallest comes first)
* @param transformer Function that provides a Processing Type or {@link AbstractFanProcessingType#NONE}
* if no processing type is available
*/
public static void registerProcessingTypeTransformer(int priority, ProcessingTypeTransformer transformer) {
REG.add(Pair.of(priority, transformer));
REG_SORTED = rebuild();
}
public static AbstractFanProcessingType byBlock(BlockGetter reader, BlockPos pos) {
for (ProcessingTypeTransformer ptt : REG_SORTED) {
AbstractFanProcessingType processingType = ptt.apply(reader, pos);
if (processingType != AbstractFanProcessingType.NONE) return processingType;
}
return AbstractFanProcessingType.NONE;
}
private static List<ProcessingTypeTransformer> rebuild() {
return REG.stream().sorted(Comparator.comparing(Pair::getFirst)).map(Pair::getSecond).toList();
}
public interface ProcessingTypeTransformer extends BiFunction<BlockGetter, BlockPos, AbstractFanProcessingType> {}
}