mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-03-04 06:44:40 +01:00
Merge branch 'mc1.20.1/feature-dev' into mc1.21.1/dev
This commit is contained in:
commit
13148135b5
180 changed files with 5385 additions and 4794 deletions
|
@ -140,6 +140,7 @@ _Now using Flywheel 1.0_
|
|||
- Added `#create:sugar_cane_variants` to allow the mechanical saw to work with custom sugarcane variants (#7263)
|
||||
- New API for custom storage block behaviour on contraptions.
|
||||
For simple cases, create provides the `#create:simple_mounted_storage` and `#create:chest_mounted_storage` block tags.
|
||||
- Added `#create:non_breakable` to mark blocks that cannot be broken by block-breaking kinetics
|
||||
- Removed LangMerger and related classes
|
||||
- Implemented an api to allow mods to register schematic requirements, partial safe nbt and contraption transforms
|
||||
without implementing interfaces (#4702)
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
// 1.20.1 2025-02-20T18:50:30.47100651 Create's Contraption Type Tags
|
||||
700982b6682ea583e7f08e44198af1b3219531d5 data/create/tags/create/contraption_type/opens_controls.json
|
||||
08384ffb27c43caadbd36c2d390ed9af1c357084 data/create/tags/create/contraption_type/requires_vehicle_for_render.json
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"values": []
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"values": [
|
||||
"create:carriage"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"values": [
|
||||
"create:mounted"
|
||||
]
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package com.simibubi.create;
|
||||
|
||||
import static com.simibubi.create.Create.REGISTRATE;
|
||||
import static com.simibubi.create.content.redstone.displayLink.AllDisplayBehaviours.assignDataBehaviourBE;
|
||||
|
||||
import com.simibubi.create.content.contraptions.actors.contraptionControls.ContraptionControlsBlockEntity;
|
||||
import com.simibubi.create.content.contraptions.actors.contraptionControls.ContraptionControlsRenderer;
|
||||
|
@ -203,8 +202,6 @@ import com.simibubi.create.content.redstone.diodes.PulseRepeaterBlockEntity;
|
|||
import com.simibubi.create.content.redstone.diodes.PulseTimerBlockEntity;
|
||||
import com.simibubi.create.content.redstone.displayLink.DisplayLinkBlockEntity;
|
||||
import com.simibubi.create.content.redstone.displayLink.LinkBulbRenderer;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.NixieTubeDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.target.NixieTubeDisplayTarget;
|
||||
import com.simibubi.create.content.redstone.link.RedstoneLinkBlockEntity;
|
||||
import com.simibubi.create.content.redstone.link.controller.LecternControllerBlockEntity;
|
||||
import com.simibubi.create.content.redstone.link.controller.LecternControllerRenderer;
|
||||
|
@ -821,11 +818,11 @@ public class AllBlockEntityTypes {
|
|||
|
||||
public static final BlockEntityEntry<NixieTubeBlockEntity> NIXIE_TUBE = REGISTRATE
|
||||
.blockEntity("nixie_tube", NixieTubeBlockEntity::new)
|
||||
.displaySource(AllDisplaySources.NIXIE_TUBE)
|
||||
.displayTarget(AllDisplayTargets.NIXIE_TUBE)
|
||||
.validBlocks(AllBlocks.ORANGE_NIXIE_TUBE)
|
||||
.validBlocks(AllBlocks.NIXIE_TUBES.toArray())
|
||||
.renderer(() -> NixieTubeRenderer::new)
|
||||
.onRegister(assignDataBehaviourBE(new NixieTubeDisplayTarget()))
|
||||
.onRegister(assignDataBehaviourBE(new NixieTubeDisplaySource()))
|
||||
.register();
|
||||
|
||||
public static final BlockEntityEntry<DisplayLinkBlockEntity> DISPLAY_LINK = REGISTRATE
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
package com.simibubi.create;
|
||||
|
||||
import static com.simibubi.create.AllInteractionBehaviours.interactionBehaviour;
|
||||
import static com.simibubi.create.AllMovementBehaviours.movementBehaviour;
|
||||
import static com.simibubi.create.Create.REGISTRATE;
|
||||
import static com.simibubi.create.api.contraption.storage.MountedStorageTypeRegistry.mountedFluidStorage;
|
||||
import static com.simibubi.create.api.contraption.storage.MountedStorageTypeRegistry.mountedItemStorage;
|
||||
import static com.simibubi.create.content.redstone.displayLink.AllDisplayBehaviours.assignDataBehaviour;
|
||||
import static com.simibubi.create.api.behaviour.display.DisplaySource.displaySource;
|
||||
import static com.simibubi.create.api.behaviour.display.DisplayTarget.displayTarget;
|
||||
import static com.simibubi.create.api.behaviour.interaction.MovingInteractionBehaviour.interactionBehaviour;
|
||||
import static com.simibubi.create.api.behaviour.movement.MovementBehaviour.movementBehaviour;
|
||||
import static com.simibubi.create.api.contraption.storage.fluid.MountedFluidStorageType.mountedFluidStorage;
|
||||
import static com.simibubi.create.api.contraption.storage.item.MountedItemStorageType.mountedItemStorage;
|
||||
import static com.simibubi.create.foundation.data.BlockStateGen.axisBlock;
|
||||
import static com.simibubi.create.foundation.data.BlockStateGen.simpleCubeAll;
|
||||
import static com.simibubi.create.foundation.data.CreateRegistrate.connectedTextures;
|
||||
|
@ -17,6 +18,7 @@ import static com.simibubi.create.foundation.data.TagGen.tagBlockAndItem;
|
|||
|
||||
import com.simibubi.create.AllTags.AllBlockTags;
|
||||
import com.simibubi.create.AllTags.AllItemTags;
|
||||
import com.simibubi.create.api.behaviour.interaction.ConductorBlockInteractionBehavior;
|
||||
import com.simibubi.create.content.contraptions.actors.contraptionControls.ContraptionControlsBlock;
|
||||
import com.simibubi.create.content.contraptions.actors.contraptionControls.ContraptionControlsMovement;
|
||||
import com.simibubi.create.content.contraptions.actors.contraptionControls.ContraptionControlsMovingInteraction;
|
||||
|
@ -226,26 +228,6 @@ import com.simibubi.create.content.redstone.diodes.ToggleLatchBlock;
|
|||
import com.simibubi.create.content.redstone.diodes.ToggleLatchGenerator;
|
||||
import com.simibubi.create.content.redstone.displayLink.DisplayLinkBlock;
|
||||
import com.simibubi.create.content.redstone.displayLink.DisplayLinkBlockItem;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.AccumulatedItemCountDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.BoilerDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.CurrentFloorDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.EntityNameDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.FactoryGaugeDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.FillLevelDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.FluidAmountDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.FluidListDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.ItemCountDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.ItemListDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.ItemNameDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.ItemThroughputDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.KineticSpeedDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.KineticStressDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.ObservedTrainNameSource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.StationSummaryDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.StopWatchDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.TimeOfDayDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.TrainStatusDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.target.DisplayBoardTarget;
|
||||
import com.simibubi.create.content.redstone.link.RedstoneLinkBlock;
|
||||
import com.simibubi.create.content.redstone.link.RedstoneLinkGenerator;
|
||||
import com.simibubi.create.content.redstone.link.controller.LecternControllerBlock;
|
||||
|
@ -290,7 +272,6 @@ import com.simibubi.create.foundation.item.UncontainableBlockItem;
|
|||
import com.simibubi.create.foundation.mixin.accessor.BlockLootSubProviderAccessor;
|
||||
import com.simibubi.create.foundation.utility.ColorHandlers;
|
||||
import com.simibubi.create.foundation.utility.DyeHelper;
|
||||
import com.simibubi.create.impl.contraption.train.TrainConductorHandlerImpl;
|
||||
import com.tterrag.registrate.providers.RegistrateRecipeProvider;
|
||||
import com.tterrag.registrate.util.DataIngredient;
|
||||
import com.tterrag.registrate.util.entry.BlockEntry;
|
||||
|
@ -552,7 +533,7 @@ public class AllBlocks {
|
|||
.transform(axeOrPickaxe())
|
||||
.blockstate(new BeltGenerator()::generate)
|
||||
.transform(BlockStressDefaults.setImpact(0))
|
||||
.onRegister(assignDataBehaviour(new ItemNameDisplaySource(), "combine_item_names"))
|
||||
.transform(displaySource(AllDisplaySources.ITEM_NAMES))
|
||||
.onRegister(CreateRegistrate.blockModel(() -> BeltModel::new))
|
||||
.clientExtension(() -> () -> new BeltBlock.RenderProperties())
|
||||
.register();
|
||||
|
@ -674,8 +655,8 @@ public class AllBlocks {
|
|||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_YELLOW))
|
||||
.transform(axeOrPickaxe())
|
||||
.transform(BuilderTransformers.cuckooClock())
|
||||
.onRegister(assignDataBehaviour(new TimeOfDayDisplaySource(), "time_of_day"))
|
||||
.onRegister(assignDataBehaviour(new StopWatchDisplaySource(), "stop_watch"))
|
||||
.transform(displaySource(AllDisplaySources.TIME_OF_DAY))
|
||||
.transform(displaySource(AllDisplaySources.STOPWATCH))
|
||||
.register();
|
||||
|
||||
public static final BlockEntry<CuckooClockBlock> MYSTERIOUS_CUCKOO_CLOCK =
|
||||
|
@ -771,7 +752,7 @@ public class AllBlocks {
|
|||
.loot((lt, block) -> lt.add(block, BlazeBurnerBlock.buildLootTable()))
|
||||
.blockstate((c, p) -> p.simpleBlock(c.getEntry(), AssetLookup.partialBaseModel(c, p)))
|
||||
.onRegister(movementBehaviour(new BlazeBurnerMovementBehaviour()))
|
||||
.onRegister(block -> TrainConductorHandlerImpl.registerBlazeBurner())
|
||||
.onRegister(interactionBehaviour(new ConductorBlockInteractionBehavior.BlazeBurner()))
|
||||
.item(BlazeBurnerBlockItem::withBlaze)
|
||||
.model(AssetLookup.customBlockItemModel("blaze_burner", "block_with_blaze"))
|
||||
.build()
|
||||
|
@ -802,7 +783,7 @@ public class AllBlocks {
|
|||
.properties(p -> p.mapColor(MapColor.COLOR_GRAY))
|
||||
.transform(axeOrPickaxe())
|
||||
.blockstate((c, p) -> p.simpleBlock(c.getEntry(), AssetLookup.partialBaseModel(c, p)))
|
||||
.onRegister(assignDataBehaviour(new ItemNameDisplaySource(), "combine_item_names"))
|
||||
.transform(displaySource(AllDisplaySources.ITEM_NAMES))
|
||||
.onRegister(interactionBehaviour(new MountedDepotInteractionBehaviour()))
|
||||
.transform(mountedItemStorage(AllMountedStorageTypes.DEPOT))
|
||||
.item()
|
||||
|
@ -817,7 +798,7 @@ public class AllBlocks {
|
|||
.transform(axeOrPickaxe())
|
||||
.blockstate((c, p) -> p.horizontalBlock(c.getEntry(), AssetLookup.partialBaseModel(c, p), 180))
|
||||
.transform(BlockStressDefaults.setImpact(2.0))
|
||||
.onRegister(assignDataBehaviour(new ItemNameDisplaySource(), "combine_item_names"))
|
||||
.transform(displaySource(AllDisplaySources.ITEM_NAMES))
|
||||
.item(EjectorItem::new)
|
||||
.transform(customItemModel())
|
||||
.register();
|
||||
|
@ -858,7 +839,7 @@ public class AllBlocks {
|
|||
.transform(axeOrPickaxe())
|
||||
.transform(BlockStressDefaults.setNoImpact())
|
||||
.blockstate(new GaugeGenerator()::generate)
|
||||
.onRegister(assignDataBehaviour(new KineticSpeedDisplaySource(), "kinetic_speed"))
|
||||
.transform(displaySource(AllDisplaySources.KINETIC_SPEED))
|
||||
.item()
|
||||
.transform(ModelGen.customItemModel("gauge", "_", "item"))
|
||||
.register();
|
||||
|
@ -869,7 +850,7 @@ public class AllBlocks {
|
|||
.transform(axeOrPickaxe())
|
||||
.transform(BlockStressDefaults.setNoImpact())
|
||||
.blockstate(new GaugeGenerator()::generate)
|
||||
.onRegister(assignDataBehaviour(new KineticStressDisplaySource(), "kinetic_stress"))
|
||||
.transform(displaySource(AllDisplaySources.KINETIC_STRESS))
|
||||
.item()
|
||||
.transform(ModelGen.customItemModel("gauge", "_", "item"))
|
||||
.register();
|
||||
|
@ -1004,7 +985,7 @@ public class AllBlocks {
|
|||
.transform(pickaxeOnly())
|
||||
.blockstate(new FluidTankGenerator()::generate)
|
||||
.onRegister(CreateRegistrate.blockModel(() -> FluidTankModel::standard))
|
||||
.onRegister(assignDataBehaviour(new BoilerDisplaySource(), "boiler_status"))
|
||||
.transform(displaySource(AllDisplaySources.BOILER))
|
||||
.transform(mountedFluidStorage(AllMountedStorageTypes.FLUID_TANK))
|
||||
.onRegister(movementBehaviour(new FluidTankMovementBehavior()))
|
||||
.addLayer(() -> RenderType::cutoutMipped)
|
||||
|
@ -1433,7 +1414,7 @@ public class AllBlocks {
|
|||
: calling ? AssetLookup.partialBaseModel(c, p, "dim") : AssetLookup.partialBaseModel(c, p);
|
||||
}))
|
||||
.loot((p, b) -> p.dropOther(b, REDSTONE_CONTACT.get()))
|
||||
.onRegister(assignDataBehaviour(new CurrentFloorDisplaySource(), "current_floor"))
|
||||
.transform(displaySource(AllDisplaySources.CURRENT_FLOOR))
|
||||
.item()
|
||||
.transform(customItemModel("_", "block"))
|
||||
.register();
|
||||
|
@ -1668,8 +1649,8 @@ public class AllBlocks {
|
|||
.sound(SoundType.NETHERITE_BLOCK))
|
||||
.transform(pickaxeOnly())
|
||||
.blockstate((c, p) -> p.simpleBlock(c.get(), AssetLookup.partialBaseModel(c, p)))
|
||||
.onRegister(assignDataBehaviour(new StationSummaryDisplaySource(), "station_summary"))
|
||||
.onRegister(assignDataBehaviour(new TrainStatusDisplaySource(), "train_status"))
|
||||
.transform(displaySource(AllDisplaySources.STATION_SUMMARY))
|
||||
.transform(displaySource(AllDisplaySources.TRAIN_STATUS))
|
||||
.lang("Train Station")
|
||||
.item(TrackTargetingBlockItem.ofType(EdgePointType.STATION))
|
||||
.transform(customItemModel())
|
||||
|
@ -1699,7 +1680,7 @@ public class AllBlocks {
|
|||
.sound(SoundType.NETHERITE_BLOCK))
|
||||
.blockstate((c, p) -> BlockStateGen.simpleBlock(c, p, AssetLookup.forPowered(c, p)))
|
||||
.transform(pickaxeOnly())
|
||||
.onRegister(assignDataBehaviour(new ObservedTrainNameSource(), "observed_train_name"))
|
||||
.transform(displaySource(AllDisplaySources.OBSERVED_TRAIN_NAME))
|
||||
.lang("Train Observer")
|
||||
.item(TrackTargetingBlockItem.ofType(EdgePointType.OBSERVER))
|
||||
.transform(customItemModel("_", "block"))
|
||||
|
@ -1793,16 +1774,16 @@ public class AllBlocks {
|
|||
REGISTRATE.block("andesite_tunnel", BeltTunnelBlock::new)
|
||||
.properties(p -> p.mapColor(MapColor.STONE))
|
||||
.transform(BuilderTransformers.beltTunnel("andesite", ResourceLocation.withDefaultNamespace("block/polished_andesite")))
|
||||
.onRegister(assignDataBehaviour(new AccumulatedItemCountDisplaySource(), "accumulate_items"))
|
||||
.onRegister(assignDataBehaviour(new ItemThroughputDisplaySource(), "item_throughput"))
|
||||
.transform(displaySource(AllDisplaySources.ACCUMULATE_ITEMS))
|
||||
.transform(displaySource(AllDisplaySources.ITEM_THROUGHPUT))
|
||||
.register();
|
||||
|
||||
public static final BlockEntry<BrassTunnelBlock> BRASS_TUNNEL =
|
||||
REGISTRATE.block("brass_tunnel", BrassTunnelBlock::new)
|
||||
.properties(p -> p.mapColor(MapColor.TERRACOTTA_YELLOW))
|
||||
.transform(BuilderTransformers.beltTunnel("brass", Create.asResource("block/brass_block")))
|
||||
.onRegister(assignDataBehaviour(new AccumulatedItemCountDisplaySource(), "accumulate_items"))
|
||||
.onRegister(assignDataBehaviour(new ItemThroughputDisplaySource(), "item_throughput"))
|
||||
.transform(displaySource(AllDisplaySources.ACCUMULATE_ITEMS))
|
||||
.transform(displaySource(AllDisplaySources.ITEM_THROUGHPUT))
|
||||
.onRegister(connectedTextures(BrassTunnelCTBehaviour::new))
|
||||
.register();
|
||||
|
||||
|
@ -1814,10 +1795,10 @@ public class AllBlocks {
|
|||
.properties(p -> p.isRedstoneConductor(($1, $2, $3) -> false))
|
||||
.transform(axeOrPickaxe())
|
||||
.blockstate(new SmartObserverGenerator()::generate)
|
||||
.onRegister(assignDataBehaviour(new ItemCountDisplaySource(), "count_items"))
|
||||
.onRegister(assignDataBehaviour(new ItemListDisplaySource(), "list_items"))
|
||||
.onRegister(assignDataBehaviour(new FluidAmountDisplaySource(), "count_fluids"))
|
||||
.onRegister(assignDataBehaviour(new FluidListDisplaySource(), "list_fluids"))
|
||||
.transform(displaySource(AllDisplaySources.COUNT_ITEMS))
|
||||
.transform(displaySource(AllDisplaySources.LIST_ITEMS))
|
||||
.transform(displaySource(AllDisplaySources.COUNT_FLUIDS))
|
||||
.transform(displaySource(AllDisplaySources.LIST_FLUIDS))
|
||||
.lang("Smart Observer")
|
||||
.item()
|
||||
.transform(customItemModel("_", "block"))
|
||||
|
@ -1831,7 +1812,7 @@ public class AllBlocks {
|
|||
.properties(p -> p.isRedstoneConductor(($1, $2, $3) -> false))
|
||||
.transform(axeOrPickaxe())
|
||||
.blockstate(new ThresholdSwitchGenerator()::generate)
|
||||
.onRegister(assignDataBehaviour(new FillLevelDisplaySource(), "fill_level"))
|
||||
.transform(displaySource(AllDisplaySources.FILL_LEVEL))
|
||||
.lang("Threshold Switch")
|
||||
.item()
|
||||
.transform(customItemModel("threshold_switch", "block_wall"))
|
||||
|
@ -1981,7 +1962,7 @@ public class AllBlocks {
|
|||
.transform(pickaxeOnly())
|
||||
.blockstate((c, p) -> p.horizontalFaceBlock(c.get(), AssetLookup.partialBaseModel(c, p)))
|
||||
.onRegister(CreateRegistrate.blockModel(() -> FactoryPanelModel::new))
|
||||
.onRegister(assignDataBehaviour(new FactoryGaugeDisplaySource(), "gauge_status"))
|
||||
.transform(displaySource(AllDisplaySources.GAUGE_STATUS))
|
||||
.item(FactoryPanelBlockItem::new)
|
||||
.model(AssetLookup::customItemModel)
|
||||
.build()
|
||||
|
@ -2058,7 +2039,7 @@ public class AllBlocks {
|
|||
.transform(pickaxeOnly())
|
||||
.transform(BlockStressDefaults.setImpact(0))
|
||||
.blockstate((c, p) -> p.horizontalBlock(c.get(), AssetLookup.partialBaseModel(c, p)))
|
||||
.onRegister(assignDataBehaviour(new DisplayBoardTarget()))
|
||||
.transform(displayTarget(AllDisplayTargets.DISPLAY_BOARD))
|
||||
.lang("Display Board")
|
||||
.item()
|
||||
.transform(customItemModel())
|
||||
|
@ -2410,7 +2391,7 @@ public class AllBlocks {
|
|||
.transform(axeOnly())
|
||||
.onRegister(movementBehaviour(movementBehaviour))
|
||||
.onRegister(interactionBehaviour(interactionBehaviour))
|
||||
.onRegister(assignDataBehaviour(new EntityNameDisplaySource(), "entity_name"))
|
||||
.transform(displaySource(AllDisplaySources.ENTITY_NAME))
|
||||
.blockstate((c, p) -> {
|
||||
p.simpleBlock(c.get(), p.models()
|
||||
.withExistingParent(colourName + "_seat", p.modLoc("block/seat"))
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package com.simibubi.create;
|
||||
|
||||
import com.simibubi.create.api.contraption.ContraptionMovementSetting;
|
||||
import com.simibubi.create.infrastructure.config.AllConfigs;
|
||||
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
|
||||
public class AllContraptionMovementSettings {
|
||||
public static void registerDefaults() {
|
||||
ContraptionMovementSetting.REGISTRY.register(Blocks.SPAWNER, () -> AllConfigs.server().kinetics.spawnerMovement.get());
|
||||
ContraptionMovementSetting.REGISTRY.register(Blocks.BUDDING_AMETHYST, () -> AllConfigs.server().kinetics.amethystMovement.get());
|
||||
ContraptionMovementSetting.REGISTRY.register(Blocks.OBSIDIAN, () -> AllConfigs.server().kinetics.obsidianMovement.get());
|
||||
ContraptionMovementSetting.REGISTRY.register(Blocks.CRYING_OBSIDIAN, () -> AllConfigs.server().kinetics.obsidianMovement.get());
|
||||
ContraptionMovementSetting.REGISTRY.register(Blocks.RESPAWN_ANCHOR, () -> AllConfigs.server().kinetics.obsidianMovement.get());
|
||||
ContraptionMovementSetting.REGISTRY.register(Blocks.REINFORCED_DEEPSLATE, () -> AllConfigs.server().kinetics.reinforcedDeepslateMovement.get());
|
||||
}
|
||||
}
|
51
src/main/java/com/simibubi/create/AllContraptionTypes.java
Normal file
51
src/main/java/com/simibubi/create/AllContraptionTypes.java
Normal file
|
@ -0,0 +1,51 @@
|
|||
package com.simibubi.create;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.api.contraption.ContraptionType;
|
||||
import com.simibubi.create.api.registry.CreateRegistries;
|
||||
import com.simibubi.create.content.contraptions.Contraption;
|
||||
import com.simibubi.create.content.contraptions.bearing.BearingContraption;
|
||||
import com.simibubi.create.content.contraptions.bearing.ClockworkContraption;
|
||||
import com.simibubi.create.content.contraptions.bearing.StabilizedContraption;
|
||||
import com.simibubi.create.content.contraptions.elevator.ElevatorContraption;
|
||||
import com.simibubi.create.content.contraptions.gantry.GantryContraption;
|
||||
import com.simibubi.create.content.contraptions.mounted.MountedContraption;
|
||||
import com.simibubi.create.content.contraptions.piston.PistonContraption;
|
||||
import com.simibubi.create.content.contraptions.pulley.PulleyContraption;
|
||||
import com.simibubi.create.content.trains.entity.CarriageContraption;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
|
||||
import net.neoforged.bus.api.IEventBus;
|
||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||
|
||||
public class AllContraptionTypes {
|
||||
private static final DeferredRegister<ContraptionType> REGISTER = DeferredRegister.create(CreateRegistries.CONTRAPTION_TYPE, Create.ID);
|
||||
|
||||
public static final Map<String, ContraptionType> BY_LEGACY_NAME = new HashMap<>();
|
||||
|
||||
public static final Holder<ContraptionType> PISTON = register("piston", PistonContraption::new);
|
||||
public static final Holder<ContraptionType> BEARING = register("bearing", BearingContraption::new);
|
||||
public static final Holder<ContraptionType> PULLEY = register("pulley", PulleyContraption::new);
|
||||
public static final Holder<ContraptionType> CLOCKWORK = register("clockwork", ClockworkContraption::new);
|
||||
public static final Holder<ContraptionType> MOUNTED = register("mounted", MountedContraption::new);
|
||||
public static final Holder<ContraptionType> STABILIZED = register("stabilized", StabilizedContraption::new);
|
||||
public static final Holder<ContraptionType> GANTRY = register("gantry", GantryContraption::new);
|
||||
public static final Holder<ContraptionType> CARRIAGE = register("carriage", CarriageContraption::new);
|
||||
public static final Holder<ContraptionType> ELEVATOR = register("elevator", ElevatorContraption::new);
|
||||
|
||||
private static Holder<ContraptionType> register(String name, Supplier<? extends Contraption> factory) {
|
||||
return REGISTER.register(name, () -> {
|
||||
ContraptionType type = new ContraptionType(factory);
|
||||
BY_LEGACY_NAME.put(name, type);
|
||||
return type;
|
||||
});
|
||||
}
|
||||
|
||||
public static void register(IEventBus modEventBus) {
|
||||
REGISTER.register(modEventBus);
|
||||
}
|
||||
}
|
154
src/main/java/com/simibubi/create/AllDisplaySources.java
Normal file
154
src/main/java/com/simibubi/create/AllDisplaySources.java
Normal file
|
@ -0,0 +1,154 @@
|
|||
package com.simibubi.create;
|
||||
|
||||
import static com.simibubi.create.Create.REGISTRATE;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.api.behaviour.display.DisplaySource;
|
||||
import com.simibubi.create.compat.Mods;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.AccumulatedItemCountDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.BoilerDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.ComputerDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.CurrentFloorDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.DeathCounterDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.EnchantPowerDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.EntityNameDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.FactoryGaugeDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.FillLevelDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.FluidAmountDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.FluidListDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.ItemCountDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.ItemListDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.ItemNameDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.ItemThroughputDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.KineticSpeedDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.KineticStressDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.NixieTubeDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.ObservedTrainNameSource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.RedstonePowerDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.ScoreboardDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.StationSummaryDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.StopWatchDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.TimeOfDayDisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.TrainStatusDisplaySource;
|
||||
import com.tterrag.registrate.util.entry.RegistryEntry;
|
||||
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.DyeColor;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
|
||||
public class AllDisplaySources {
|
||||
public static final RegistryEntry<DisplaySource, DeathCounterDisplaySource> DEATH_COUNT = REGISTRATE.displaySource("death_count", DeathCounterDisplaySource::new)
|
||||
.associate(Blocks.RESPAWN_ANCHOR)
|
||||
.register();
|
||||
public static final RegistryEntry<DisplaySource, ScoreboardDisplaySource> SCOREBOARD = REGISTRATE.displaySource("scoreboard", ScoreboardDisplaySource::new)
|
||||
.associate(BlockEntityType.COMMAND_BLOCK)
|
||||
.register();
|
||||
public static final RegistryEntry<DisplaySource, EnchantPowerDisplaySource> ENCHANT_POWER = REGISTRATE.displaySource("enchant_power", EnchantPowerDisplaySource::new)
|
||||
.associate(BlockEntityType.ENCHANTING_TABLE)
|
||||
.register();
|
||||
public static final RegistryEntry<DisplaySource, RedstonePowerDisplaySource> REDSTONE_POWER = REGISTRATE.displaySource("redstone_power", RedstonePowerDisplaySource::new)
|
||||
.associate(Blocks.TARGET)
|
||||
.register();
|
||||
|
||||
public static final RegistryEntry<DisplaySource, NixieTubeDisplaySource> NIXIE_TUBE = simple("nixie_tube", NixieTubeDisplaySource::new);
|
||||
public static final RegistryEntry<DisplaySource, ItemNameDisplaySource> ITEM_NAMES = simple("item_names", ItemNameDisplaySource::new);
|
||||
public static final RegistryEntry<DisplaySource, BoilerDisplaySource> BOILER = simple("boiler", BoilerDisplaySource::new);
|
||||
public static final RegistryEntry<DisplaySource, CurrentFloorDisplaySource> CURRENT_FLOOR = simple("current_floor", CurrentFloorDisplaySource::new);
|
||||
public static final RegistryEntry<DisplaySource, FillLevelDisplaySource> FILL_LEVEL = simple("fill_level", FillLevelDisplaySource::new);
|
||||
public static final RegistryEntry<DisplaySource, FactoryGaugeDisplaySource> GAUGE_STATUS = simple("gauge_status", FactoryGaugeDisplaySource::new);
|
||||
public static final RegistryEntry<DisplaySource, EntityNameDisplaySource> ENTITY_NAME = simple("entity_name", EntityNameDisplaySource::new);
|
||||
|
||||
public static final RegistryEntry<DisplaySource, TimeOfDayDisplaySource> TIME_OF_DAY = simple("time_of_day", TimeOfDayDisplaySource::new);
|
||||
public static final RegistryEntry<DisplaySource, StopWatchDisplaySource> STOPWATCH = simple("stopwatch", StopWatchDisplaySource::new);
|
||||
|
||||
public static final RegistryEntry<DisplaySource, KineticSpeedDisplaySource> KINETIC_SPEED = simple("kinetic_speed", KineticSpeedDisplaySource::new);
|
||||
public static final RegistryEntry<DisplaySource, KineticStressDisplaySource> KINETIC_STRESS = simple("kinetic_stress", KineticStressDisplaySource::new);
|
||||
|
||||
public static final RegistryEntry<DisplaySource, StationSummaryDisplaySource> STATION_SUMMARY = simple("station_summary", StationSummaryDisplaySource::new);
|
||||
public static final RegistryEntry<DisplaySource, TrainStatusDisplaySource> TRAIN_STATUS = simple("train_status", TrainStatusDisplaySource::new);
|
||||
public static final RegistryEntry<DisplaySource, ObservedTrainNameSource> OBSERVED_TRAIN_NAME = simple("observed_train_name", ObservedTrainNameSource::new);
|
||||
|
||||
public static final RegistryEntry<DisplaySource, AccumulatedItemCountDisplaySource> ACCUMULATE_ITEMS = simple("accumulate_items", AccumulatedItemCountDisplaySource::new);
|
||||
public static final RegistryEntry<DisplaySource, ItemThroughputDisplaySource> ITEM_THROUGHPUT = simple("item_throughput", ItemThroughputDisplaySource::new);
|
||||
|
||||
public static final RegistryEntry<DisplaySource, ItemCountDisplaySource> COUNT_ITEMS = simple("count_items", ItemCountDisplaySource::new);
|
||||
public static final RegistryEntry<DisplaySource, ItemListDisplaySource> LIST_ITEMS = simple("list_items", ItemListDisplaySource::new);
|
||||
public static final RegistryEntry<DisplaySource, FluidAmountDisplaySource> COUNT_FLUIDS = simple("count_fluids", FluidAmountDisplaySource::new);
|
||||
public static final RegistryEntry<DisplaySource, FluidListDisplaySource> LIST_FLUIDS = simple("list_fluids", FluidListDisplaySource::new);
|
||||
|
||||
public static final RegistryEntry<DisplaySource, ComputerDisplaySource> COMPUTER = REGISTRATE.displaySource("computer", ComputerDisplaySource::new)
|
||||
.onRegisterAfter(Registries.BLOCK_ENTITY_TYPE, source -> {
|
||||
List<String> types = List.of("wired_modem_full", "computer_normal", "computer_advanced", "computer_command");
|
||||
for (String name : types) {
|
||||
ResourceLocation id = Mods.COMPUTERCRAFT.rl(name);
|
||||
if (BuiltInRegistries.BLOCK_ENTITY_TYPE.containsKey(id)) {
|
||||
BlockEntityType<?> type = BuiltInRegistries.BLOCK_ENTITY_TYPE.get(id);
|
||||
DisplaySource.BY_BLOCK_ENTITY.add(type, source);
|
||||
} else {
|
||||
Create.LOGGER.warn("Could not find block entity type {}. Outdated compat?", id);
|
||||
}
|
||||
}
|
||||
})
|
||||
.register();
|
||||
|
||||
public static final Map<String, RegistryEntry<DisplaySource, ? extends DisplaySource>> LEGACY_NAMES = Util.make(() -> {
|
||||
Map<String, RegistryEntry<DisplaySource, ? extends DisplaySource>> map = new HashMap<>();
|
||||
map.put("death_count_display_source", DEATH_COUNT);
|
||||
map.put("scoreboard_display_source", SCOREBOARD);
|
||||
map.put("enchant_power_display_source", ENCHANT_POWER);
|
||||
map.put("redstone_power_display_source", REDSTONE_POWER);
|
||||
|
||||
map.put("nixie_tube_source", NIXIE_TUBE);
|
||||
map.put("belt_source_combine_item_names", ITEM_NAMES);
|
||||
map.put("cuckoo_clock_source_time_of_day", TIME_OF_DAY);
|
||||
map.put("cuckoo_clock_source_stop_watch", STOPWATCH);
|
||||
map.put("speedometer_source_kinetic_speed", KINETIC_SPEED);
|
||||
map.put("stressometer_source_kinetic_stress", KINETIC_STRESS);
|
||||
map.put("fluid_tank_source_boiler_status", BOILER);
|
||||
map.put("elevator_contact_source_current_floor", CURRENT_FLOOR);
|
||||
map.put("track_station_source_station_summary", STATION_SUMMARY);
|
||||
map.put("track_station_source_train_status", TRAIN_STATUS);
|
||||
map.put("track_observer_source_observed_train_name", OBSERVED_TRAIN_NAME);
|
||||
|
||||
map.put("andesite_tunnel_source_accumulate_items", ACCUMULATE_ITEMS);
|
||||
map.put("andesite_tunnel_source_item_throughput", ITEM_THROUGHPUT);
|
||||
map.put("brass_tunnel_source_accumulate_items", ACCUMULATE_ITEMS);
|
||||
map.put("brass_tunnel_source_item_throughput", ITEM_THROUGHPUT);
|
||||
|
||||
map.put("content_observer_source_count_items", COUNT_ITEMS);
|
||||
map.put("content_observer_source_list_items", LIST_ITEMS);
|
||||
map.put("content_observer_source_count_fluids", COUNT_FLUIDS);
|
||||
map.put("content_observer_source_list_fluids", LIST_FLUIDS);
|
||||
|
||||
map.put("stockpile_switch_source_fill_level", FILL_LEVEL);
|
||||
|
||||
map.put("factory_gauge_source_gauge_status", GAUGE_STATUS);
|
||||
|
||||
for (DyeColor color : DyeColor.values()) {
|
||||
String name = color.getSerializedName() + "_seat_source_entity_name";
|
||||
map.put(name, ENTITY_NAME);
|
||||
}
|
||||
|
||||
map.put("depot_source_combine_item_names", ITEM_NAMES);
|
||||
map.put("weighted_ejector_source_combine_item_names", ITEM_NAMES);
|
||||
|
||||
map.put("computer_display_source", COMPUTER);
|
||||
|
||||
return map;
|
||||
});
|
||||
|
||||
private static <T extends DisplaySource> RegistryEntry<DisplaySource, T> simple(String name, Supplier<T> supplier) {
|
||||
return REGISTRATE.displaySource(name, supplier).register();
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
}
|
||||
}
|
41
src/main/java/com/simibubi/create/AllDisplayTargets.java
Normal file
41
src/main/java/com/simibubi/create/AllDisplayTargets.java
Normal file
|
@ -0,0 +1,41 @@
|
|||
package com.simibubi.create;
|
||||
|
||||
import static com.simibubi.create.Create.REGISTRATE;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.api.behaviour.display.DisplayTarget;
|
||||
import com.simibubi.create.content.redstone.displayLink.target.DisplayBoardTarget;
|
||||
import com.simibubi.create.content.redstone.displayLink.target.LecternDisplayTarget;
|
||||
import com.simibubi.create.content.redstone.displayLink.target.NixieTubeDisplayTarget;
|
||||
import com.simibubi.create.content.redstone.displayLink.target.SignDisplayTarget;
|
||||
import com.tterrag.registrate.util.entry.RegistryEntry;
|
||||
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
|
||||
public class AllDisplayTargets {
|
||||
public static final RegistryEntry<DisplayTarget, SignDisplayTarget> SIGN = REGISTRATE.displayTarget("sign", SignDisplayTarget::new)
|
||||
.associate(BlockEntityType.SIGN)
|
||||
.register();
|
||||
public static final RegistryEntry<DisplayTarget, LecternDisplayTarget> LECTERN = REGISTRATE.displayTarget("lectern", LecternDisplayTarget::new)
|
||||
.associate(BlockEntityType.LECTERN)
|
||||
.register();
|
||||
|
||||
public static final RegistryEntry<DisplayTarget, DisplayBoardTarget> DISPLAY_BOARD = simple("display_board", DisplayBoardTarget::new);
|
||||
public static final RegistryEntry<DisplayTarget, NixieTubeDisplayTarget> NIXIE_TUBE = simple("nixie_tube", NixieTubeDisplayTarget::new);
|
||||
|
||||
public static final Map<String, RegistryEntry<DisplayTarget, ? extends DisplayTarget>> LEGACY_NAMES = Map.of(
|
||||
"sign_display_target", SIGN,
|
||||
"lectern_display_target", LECTERN,
|
||||
"display_board_target", DISPLAY_BOARD,
|
||||
"nixie_tube_target", NIXIE_TUBE
|
||||
);
|
||||
|
||||
private static <T extends DisplayTarget> RegistryEntry<DisplayTarget, T> simple(String name, Supplier<T> supplier) {
|
||||
return REGISTRATE.displayTarget(name, supplier).register();
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
}
|
||||
}
|
|
@ -1,94 +1,20 @@
|
|||
package com.simibubi.create;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.api.behaviour.interaction.MovingInteractionBehaviour;
|
||||
import com.simibubi.create.api.registry.SimpleRegistry;
|
||||
import com.simibubi.create.content.contraptions.behaviour.DoorMovingInteraction;
|
||||
import com.simibubi.create.content.contraptions.behaviour.FenceGateMovingInteraction;
|
||||
import com.simibubi.create.content.contraptions.behaviour.LeverMovingInteraction;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovingInteractionBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.TrapdoorMovingInteraction;
|
||||
import com.simibubi.create.foundation.utility.AttachedRegistry;
|
||||
import com.tterrag.registrate.util.nullness.NonNullConsumer;
|
||||
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class AllInteractionBehaviours {
|
||||
private static final AttachedRegistry<Block, MovingInteractionBehaviour> BLOCK_BEHAVIOURS = new AttachedRegistry<>(BuiltInRegistries.BLOCK);
|
||||
private static final List<BehaviourProvider> GLOBAL_BEHAVIOURS = new ArrayList<>();
|
||||
|
||||
public static void registerBehaviour(ResourceLocation block, MovingInteractionBehaviour provider) {
|
||||
BLOCK_BEHAVIOURS.register(block, provider);
|
||||
}
|
||||
|
||||
public static void registerBehaviour(Block block, MovingInteractionBehaviour provider) {
|
||||
BLOCK_BEHAVIOURS.register(block, provider);
|
||||
}
|
||||
|
||||
public static void registerBehaviourProvider(BehaviourProvider provider) {
|
||||
GLOBAL_BEHAVIOURS.add(provider);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static MovingInteractionBehaviour getBehaviour(BlockState state) {
|
||||
MovingInteractionBehaviour behaviour = BLOCK_BEHAVIOURS.get(state.getBlock());
|
||||
if (behaviour != null) {
|
||||
return behaviour;
|
||||
}
|
||||
|
||||
for (BehaviourProvider provider : GLOBAL_BEHAVIOURS) {
|
||||
behaviour = provider.getBehaviour(state);
|
||||
if (behaviour != null) {
|
||||
return behaviour;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <B extends Block> NonNullConsumer<? super B> interactionBehaviour(
|
||||
MovingInteractionBehaviour behaviour) {
|
||||
return b -> registerBehaviour(b, behaviour);
|
||||
}
|
||||
|
||||
static void registerDefaults() {
|
||||
registerBehaviour(Blocks.LEVER, new LeverMovingInteraction());
|
||||
MovingInteractionBehaviour.REGISTRY.register(Blocks.LEVER, new LeverMovingInteraction());
|
||||
|
||||
DoorMovingInteraction doorBehaviour = new DoorMovingInteraction();
|
||||
registerBehaviourProvider(state -> {
|
||||
if (state.is(BlockTags.MOB_INTERACTABLE_DOORS)) {
|
||||
return doorBehaviour;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
TrapdoorMovingInteraction trapdoorBehaviour = new TrapdoorMovingInteraction();
|
||||
registerBehaviourProvider(state -> {
|
||||
if (state.is(BlockTags.TRAPDOORS) && !state.is(Blocks.IRON_TRAPDOOR)) {
|
||||
return trapdoorBehaviour;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
FenceGateMovingInteraction fenceGateBehavior = new FenceGateMovingInteraction();
|
||||
registerBehaviourProvider(state -> {
|
||||
if (state.is(BlockTags.FENCE_GATES)) {
|
||||
return fenceGateBehavior;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public interface BehaviourProvider {
|
||||
@Nullable
|
||||
MovingInteractionBehaviour getBehaviour(BlockState state);
|
||||
MovingInteractionBehaviour.REGISTRY.registerProvider(SimpleRegistry.Provider.forBlockTag(BlockTags.WOODEN_DOORS, new DoorMovingInteraction()));
|
||||
MovingInteractionBehaviour.REGISTRY.registerProvider(SimpleRegistry.Provider.forBlockTag(BlockTags.WOODEN_TRAPDOORS, new TrapdoorMovingInteraction()));
|
||||
MovingInteractionBehaviour.REGISTRY.registerProvider(SimpleRegistry.Provider.forBlockTag(BlockTags.FENCE_GATES, new TrapdoorMovingInteraction()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,14 +34,14 @@ public class AllMountedStorageTypes {
|
|||
|
||||
// these are for external blocks, register associations here
|
||||
public static final RegistryEntry<MountedItemStorageType<?>, SimpleMountedStorageType.Impl> SIMPLE = REGISTRATE.mountedItemStorage("simple", SimpleMountedStorageType.Impl::new)
|
||||
.registerTo(AllTags.AllBlockTags.SIMPLE_MOUNTED_STORAGE.tag)
|
||||
.associateBlockTag(AllTags.AllBlockTags.SIMPLE_MOUNTED_STORAGE.tag)
|
||||
.register();
|
||||
public static final RegistryEntry<MountedItemStorageType<?>, ChestMountedStorageType> CHEST = REGISTRATE.mountedItemStorage("chest", ChestMountedStorageType::new)
|
||||
.registerTo(AllTags.AllBlockTags.CHEST_MOUNTED_STORAGE.tag)
|
||||
.associateBlockTag(AllTags.AllBlockTags.CHEST_MOUNTED_STORAGE.tag)
|
||||
.register();
|
||||
public static final RegistryEntry<MountedItemStorageType<?>, DispenserMountedStorageType> DISPENSER = REGISTRATE.mountedItemStorage("dispenser", DispenserMountedStorageType::new)
|
||||
.registerTo(Blocks.DISPENSER)
|
||||
.registerTo(Blocks.DROPPER)
|
||||
.associate(Blocks.DISPENSER)
|
||||
.associate(Blocks.DROPPER)
|
||||
.register();
|
||||
|
||||
private static <T extends MountedItemStorageType<?>> RegistryEntry<MountedItemStorageType<?>, T> simpleItem(String name, Supplier<T> supplier) {
|
||||
|
|
|
@ -1,75 +1,21 @@
|
|||
package com.simibubi.create;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.simibubi.create.api.behaviour.movement.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.BellMovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.CampfireMovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.dispenser.DispenserMovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.dispenser.DropperMovementBehaviour;
|
||||
import com.simibubi.create.foundation.utility.AttachedRegistry;
|
||||
import com.tterrag.registrate.util.nullness.NonNullConsumer;
|
||||
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class AllMovementBehaviours {
|
||||
private static final AttachedRegistry<Block, MovementBehaviour> BLOCK_BEHAVIOURS = new AttachedRegistry<>(BuiltInRegistries.BLOCK);
|
||||
private static final List<BehaviourProvider> GLOBAL_BEHAVIOURS = new ArrayList<>();
|
||||
|
||||
public static void registerBehaviour(ResourceLocation block, MovementBehaviour behaviour) {
|
||||
BLOCK_BEHAVIOURS.register(block, behaviour);
|
||||
}
|
||||
|
||||
public static void registerBehaviour(Block block, MovementBehaviour behaviour) {
|
||||
BLOCK_BEHAVIOURS.register(block, behaviour);
|
||||
}
|
||||
|
||||
public static void registerBehaviourProvider(BehaviourProvider provider) {
|
||||
GLOBAL_BEHAVIOURS.add(provider);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static MovementBehaviour getBehaviour(BlockState state) {
|
||||
MovementBehaviour behaviour = BLOCK_BEHAVIOURS.get(state.getBlock());
|
||||
if (behaviour != null) {
|
||||
return behaviour;
|
||||
}
|
||||
|
||||
for (BehaviourProvider provider : GLOBAL_BEHAVIOURS) {
|
||||
behaviour = provider.getBehaviour(state);
|
||||
if (behaviour != null) {
|
||||
return behaviour;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <B extends Block> NonNullConsumer<? super B> movementBehaviour(
|
||||
MovementBehaviour behaviour) {
|
||||
return b -> registerBehaviour(b, behaviour);
|
||||
}
|
||||
|
||||
static void registerDefaults() {
|
||||
registerBehaviour(Blocks.BELL, new BellMovementBehaviour());
|
||||
registerBehaviour(Blocks.CAMPFIRE, new CampfireMovementBehaviour());
|
||||
registerBehaviour(Blocks.SOUL_CAMPFIRE, new CampfireMovementBehaviour());
|
||||
MovementBehaviour.REGISTRY.register(Blocks.BELL, new BellMovementBehaviour());
|
||||
MovementBehaviour.REGISTRY.register(Blocks.CAMPFIRE, new CampfireMovementBehaviour());
|
||||
MovementBehaviour.REGISTRY.register(Blocks.SOUL_CAMPFIRE, new CampfireMovementBehaviour());
|
||||
|
||||
DispenserMovementBehaviour.gatherMovedDispenseItemBehaviours();
|
||||
registerBehaviour(Blocks.DISPENSER, new DispenserMovementBehaviour());
|
||||
registerBehaviour(Blocks.DROPPER, new DropperMovementBehaviour());
|
||||
}
|
||||
|
||||
public interface BehaviourProvider {
|
||||
@Nullable
|
||||
MovementBehaviour getBehaviour(BlockState state);
|
||||
MovementBehaviour.REGISTRY.register(Blocks.DISPENSER, new DispenserMovementBehaviour());
|
||||
MovementBehaviour.REGISTRY.register(Blocks.DROPPER, new DropperMovementBehaviour());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package com.simibubi.create;
|
||||
|
||||
import com.simibubi.create.api.effect.OpenPipeEffectHandler;
|
||||
import com.simibubi.create.api.registry.SimpleRegistry;
|
||||
import com.simibubi.create.impl.effect.LavaEffectHandler;
|
||||
import com.simibubi.create.impl.effect.MilkEffectHandler;
|
||||
import com.simibubi.create.impl.effect.PotionEffectHandler;
|
||||
import com.simibubi.create.impl.effect.TeaEffectHandler;
|
||||
import com.simibubi.create.impl.effect.WaterEffectHandler;
|
||||
|
||||
import net.minecraft.tags.FluidTags;
|
||||
|
||||
import net.neoforged.neoforge.common.Tags;
|
||||
|
||||
public class AllOpenPipeEffectHandlers {
|
||||
public static void registerDefaults() {
|
||||
OpenPipeEffectHandler.REGISTRY.registerProvider(SimpleRegistry.Provider.forFluidTag(FluidTags.WATER, new WaterEffectHandler()));
|
||||
OpenPipeEffectHandler.REGISTRY.registerProvider(SimpleRegistry.Provider.forFluidTag(FluidTags.LAVA, new LavaEffectHandler()));
|
||||
OpenPipeEffectHandler.REGISTRY.registerProvider(SimpleRegistry.Provider.forFluidTag(Tags.Fluids.MILK, new MilkEffectHandler()));
|
||||
OpenPipeEffectHandler.REGISTRY.register(AllFluids.POTION.getSource(), new PotionEffectHandler());
|
||||
OpenPipeEffectHandler.REGISTRY.register(AllFluids.TEA.getSource(), new TeaEffectHandler());
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
package com.simibubi.create;
|
||||
|
||||
import com.simibubi.create.api.contraption.storage.fluid.MountedFluidStorageType;
|
||||
import com.simibubi.create.api.contraption.storage.item.MountedItemStorageType;
|
||||
import com.simibubi.create.content.kinetics.fan.processing.FanProcessingType;
|
||||
import com.simibubi.create.content.kinetics.mechanicalArm.ArmInteractionPointType;
|
||||
import com.simibubi.create.content.logistics.item.filter.attribute.ItemAttributeType;
|
||||
import com.simibubi.create.content.logistics.packagePort.PackagePortTargetType;
|
||||
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.neoforge.registries.NewRegistryEvent;
|
||||
import net.neoforged.neoforge.registries.RegistryBuilder;
|
||||
|
||||
@EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD)
|
||||
public class AllRegistries {
|
||||
public static final Registry<ArmInteractionPointType> ARM_INTERACTION_POINT_TYPE = create(Keys.ARM_INTERACTION_POINT_TYPE);
|
||||
public static final Registry<FanProcessingType> FAN_PROCESSING_TYPE = create(Keys.FAN_PROCESSING_TYPE);
|
||||
public static final Registry<ItemAttributeType> ITEM_ATTRIBUTE_TYPE = create(AllRegistries.Keys.ITEM_ATTRIBUTE_TYPE);
|
||||
public static final Registry<PackagePortTargetType> PACKAGE_PORT_TARGET = create(Keys.PACKAGE_PORT_TARGET);
|
||||
public static final Registry<MountedItemStorageType<?>> MOUNTED_ITEM_STORAGE_TYPE = create(Keys.MOUNTED_ITEM_STORAGE_TYPE);
|
||||
public static final Registry<MountedFluidStorageType<?>> MOUNTED_FLUID_STORAGE_TYPE = create(Keys.MOUNTED_FLUID_STORAGE_TYPE);
|
||||
|
||||
private static <T> Registry<T> create(ResourceKey<Registry<T>> key) {
|
||||
return new RegistryBuilder<>(key).sync(true).create();
|
||||
}
|
||||
|
||||
// Make these non-plural
|
||||
public static final class Keys {
|
||||
public static final ResourceKey<Registry<ArmInteractionPointType>> ARM_INTERACTION_POINT_TYPE = key("arm_interaction_point_type");
|
||||
public static final ResourceKey<Registry<FanProcessingType>> FAN_PROCESSING_TYPE = key("fan_processing_type");
|
||||
public static final ResourceKey<Registry<ItemAttributeType>> ITEM_ATTRIBUTE_TYPE = key("item_attribute_type");
|
||||
public static final ResourceKey<Registry<PackagePortTargetType>> PACKAGE_PORT_TARGET = key("package_port_target");
|
||||
public static final ResourceKey<Registry<MountedItemStorageType<?>>> MOUNTED_ITEM_STORAGE_TYPE = key("mounted_item_storage_type");
|
||||
public static final ResourceKey<Registry<MountedFluidStorageType<?>>> MOUNTED_FLUID_STORAGE_TYPE = key("mounted_fluid_storage_type");
|
||||
|
||||
private static <T> ResourceKey<Registry<T>> key(String name) {
|
||||
return ResourceKey.createRegistryKey(Create.asResource(name));
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void registerRegistries(NewRegistryEvent event) {
|
||||
event.register(AllRegistries.ARM_INTERACTION_POINT_TYPE);
|
||||
event.register(AllRegistries.FAN_PROCESSING_TYPE);
|
||||
event.register(AllRegistries.ITEM_ATTRIBUTE_TYPE);
|
||||
event.register(AllRegistries.PACKAGE_PORT_TARGET);
|
||||
event.register(AllRegistries.MOUNTED_ITEM_STORAGE_TYPE);
|
||||
event.register(AllRegistries.MOUNTED_FLUID_STORAGE_TYPE);
|
||||
}
|
||||
}
|
|
@ -6,6 +6,9 @@ import static com.simibubi.create.AllTags.NameSpace.MOD;
|
|||
import static com.simibubi.create.AllTags.NameSpace.QUARK;
|
||||
import static com.simibubi.create.AllTags.NameSpace.TIC;
|
||||
|
||||
import com.simibubi.create.api.contraption.ContraptionType;
|
||||
import com.simibubi.create.api.registry.CreateRegistries;
|
||||
|
||||
import net.createmod.catnip.lang.Lang;
|
||||
|
||||
import net.minecraft.core.Registry;
|
||||
|
@ -56,9 +59,7 @@ public class AllTags {
|
|||
TIC("tconstruct"),
|
||||
QUARK("quark"),
|
||||
GS("galosphere"),
|
||||
CURIOS("curios")
|
||||
|
||||
;
|
||||
CURIOS("curios");
|
||||
|
||||
public final String id;
|
||||
public final boolean optionalDefault;
|
||||
|
@ -89,6 +90,7 @@ public class AllTags {
|
|||
GIRDABLE_TRACKS,
|
||||
MOVABLE_EMPTY_COLLIDER,
|
||||
NON_MOVABLE,
|
||||
NON_BREAKABLE,
|
||||
ORE_OVERRIDE_STONE,
|
||||
PASSIVE_BOILER_HEATERS,
|
||||
SAFE_NBT,
|
||||
|
@ -159,7 +161,8 @@ public class AllTags {
|
|||
return state.is(tag);
|
||||
}
|
||||
|
||||
private static void init() {}
|
||||
private static void init() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -190,17 +193,15 @@ public class AllTags {
|
|||
VALVE_HANDLES,
|
||||
|
||||
PLATES(COMMON),
|
||||
OBSIDIAN_DUST(COMMON,"dusts/obsidian"),
|
||||
OBSIDIAN_DUST(COMMON, "dusts/obsidian"),
|
||||
WRENCH(COMMON, "tools/wrench"),
|
||||
|
||||
ALLURITE(MOD,"stone_types/galosphere/allurite"),
|
||||
AMETHYST(MOD,"stone_types/galosphere/amethyst"),
|
||||
ALLURITE(MOD, "stone_types/galosphere/allurite"),
|
||||
AMETHYST(MOD, "stone_types/galosphere/amethyst"),
|
||||
LUMIERE(MOD, "stone_types/galosphere/lumiere"),
|
||||
|
||||
UA_CORAL(MOD, "upgrade_aquatic/coral"),
|
||||
CURIOS_HEAD(CURIOS, "head")
|
||||
|
||||
;
|
||||
CURIOS_HEAD(CURIOS, "head");
|
||||
|
||||
public final TagKey<Item> tag;
|
||||
public final boolean alwaysDatagen;
|
||||
|
@ -241,7 +242,8 @@ public class AllTags {
|
|||
return stack.is(tag);
|
||||
}
|
||||
|
||||
private static void init() {}
|
||||
private static void init() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -294,7 +296,8 @@ public class AllTags {
|
|||
return state.is(tag);
|
||||
}
|
||||
|
||||
private static void init() {}
|
||||
private static void init() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -342,7 +345,8 @@ public class AllTags {
|
|||
return matches(entity.getType());
|
||||
}
|
||||
|
||||
private static void init() {}
|
||||
private static void init() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -386,7 +390,29 @@ public class AllTags {
|
|||
return BuiltInRegistries.RECIPE_SERIALIZER.getHolder(key).orElseThrow().is(tag);
|
||||
}
|
||||
|
||||
private static void init() {}
|
||||
private static void init() {
|
||||
}
|
||||
}
|
||||
|
||||
public enum AllContraptionTypeTags {
|
||||
OPENS_CONTROLS,
|
||||
REQUIRES_VEHICLE_FOR_RENDER;
|
||||
|
||||
public final TagKey<ContraptionType> tag;
|
||||
public final boolean alwaysDatagen;
|
||||
|
||||
AllContraptionTypeTags() {
|
||||
ResourceLocation tagId = Create.asResource(Lang.asId(this.name()));
|
||||
this.tag = TagKey.create(CreateRegistries.CONTRAPTION_TYPE, tagId);
|
||||
this.alwaysDatagen = true;
|
||||
}
|
||||
|
||||
public boolean matches(ContraptionType type) {
|
||||
return type.is(this.tag);
|
||||
}
|
||||
|
||||
private static void init() {
|
||||
}
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
|
@ -395,5 +421,6 @@ public class AllTags {
|
|||
AllFluidTags.init();
|
||||
AllEntityTags.init();
|
||||
AllRecipeSerializerTags.init();
|
||||
AllContraptionTypeTags.init();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,27 +2,31 @@ package com.simibubi.create;
|
|||
|
||||
import java.util.Random;
|
||||
|
||||
import com.simibubi.create.content.equipment.armor.AllArmorMaterials;
|
||||
import com.simibubi.create.content.logistics.packagePort.AllPackagePortTargetTypes;
|
||||
import com.simibubi.create.foundation.recipe.AllIngredients;
|
||||
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
|
||||
import net.neoforged.neoforge.registries.RegisterEvent;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.simibubi.create.api.behaviour.BlockSpoutingBehaviour;
|
||||
import com.simibubi.create.api.behaviour.spouting.BlockSpoutingBehaviour;
|
||||
import com.simibubi.create.compat.Mods;
|
||||
import com.simibubi.create.compat.computercraft.ComputerCraftProxy;
|
||||
import com.simibubi.create.compat.curios.Curios;
|
||||
import com.simibubi.create.content.contraptions.ContraptionMovementSetting;
|
||||
import com.simibubi.create.content.decoration.palettes.AllPaletteBlocks;
|
||||
import com.simibubi.create.content.equipment.armor.AllArmorMaterials;
|
||||
import com.simibubi.create.content.equipment.potatoCannon.BuiltinPotatoProjectileTypes;
|
||||
import com.simibubi.create.content.fluids.tank.BoilerHeaters;
|
||||
import com.simibubi.create.content.kinetics.TorquePropagator;
|
||||
import com.simibubi.create.content.kinetics.fan.processing.AllFanProcessingTypes;
|
||||
import com.simibubi.create.content.kinetics.mechanicalArm.AllArmInteractionPointTypes;
|
||||
import com.simibubi.create.content.logistics.item.filter.attribute.AllItemAttributeTypes;
|
||||
import com.simibubi.create.content.logistics.packagePort.AllPackagePortTargetTypes;
|
||||
import com.simibubi.create.content.logistics.packagerLink.GlobalLogisticsManager;
|
||||
import com.simibubi.create.content.redstone.displayLink.AllDisplayBehaviours;
|
||||
import com.simibubi.create.content.redstone.link.RedstoneLinkNetworkHandler;
|
||||
import com.simibubi.create.content.schematics.ServerSchematicLoader;
|
||||
import com.simibubi.create.content.trains.GlobalRailwayManager;
|
||||
|
@ -34,8 +38,6 @@ import com.simibubi.create.foundation.data.CreateRegistrate;
|
|||
import com.simibubi.create.foundation.item.ItemDescription;
|
||||
import com.simibubi.create.foundation.item.KineticStats;
|
||||
import com.simibubi.create.foundation.item.TooltipModifier;
|
||||
import com.simibubi.create.foundation.recipe.AllIngredients;
|
||||
import com.simibubi.create.foundation.utility.AttachedRegistry;
|
||||
import com.simibubi.create.foundation.utility.CreateNBTProcessors;
|
||||
import com.simibubi.create.infrastructure.command.ServerLagger;
|
||||
import com.simibubi.create.infrastructure.config.AllConfigs;
|
||||
|
@ -45,13 +47,13 @@ import com.simibubi.create.infrastructure.worldgen.AllPlacementModifiers;
|
|||
|
||||
import net.createmod.catnip.lang.FontHelper;
|
||||
import net.createmod.catnip.lang.LangBuilder;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.item.CreativeModeTab;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
|
||||
import net.neoforged.bus.api.EventPriority;
|
||||
import net.neoforged.bus.api.IEventBus;
|
||||
import net.neoforged.fml.ModContainer;
|
||||
|
@ -59,7 +61,6 @@ import net.neoforged.fml.ModLoadingContext;
|
|||
import net.neoforged.fml.common.Mod;
|
||||
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.neoforged.neoforge.common.NeoForgeMod;
|
||||
import net.neoforged.neoforge.registries.RegisterEvent;
|
||||
|
||||
@Mod(Create.ID)
|
||||
public class Create {
|
||||
|
@ -111,6 +112,8 @@ public class Create {
|
|||
AllTags.init();
|
||||
AllCreativeModeTabs.register(modEventBus);
|
||||
AllArmorMaterials.register(modEventBus);
|
||||
AllDisplaySources.register();
|
||||
AllDisplayTargets.register();
|
||||
AllBlocks.register();
|
||||
AllItems.register();
|
||||
AllFluids.register();
|
||||
|
@ -136,15 +139,10 @@ public class Create {
|
|||
AllArmInteractionPointTypes.register(modEventBus);
|
||||
AllFanProcessingTypes.register(modEventBus);
|
||||
AllItemAttributeTypes.register(modEventBus);
|
||||
AllContraptionTypes.register(modEventBus);
|
||||
AllPackagePortTargetTypes.register(modEventBus);
|
||||
BlockSpoutingBehaviour.registerDefaults();
|
||||
|
||||
// FIXME: some of these registrations are not thread-safe
|
||||
AllMovementBehaviours.registerDefaults();
|
||||
AllInteractionBehaviours.registerDefaults();
|
||||
AllPortalTracks.registerDefaults();
|
||||
AllDisplayBehaviours.registerDefaults();
|
||||
ContraptionMovementSetting.registerDefaults();
|
||||
BogeySizes.init();
|
||||
AllBogeyStyles.init();
|
||||
// ----
|
||||
|
@ -173,9 +171,13 @@ public class Create {
|
|||
// These registrations use Create's registered objects directly so they must run after registration has finished.
|
||||
BuiltinPotatoProjectileTypes.register();
|
||||
BoilerHeaters.registerDefaults();
|
||||
AllPortalTracks.registerDefaults();
|
||||
BlockSpoutingBehaviour.registerDefaults();
|
||||
AllMovementBehaviours.registerDefaults();
|
||||
AllInteractionBehaviours.registerDefaults();
|
||||
AllContraptionMovementSettings.registerDefaults();
|
||||
AllOpenPipeEffectHandlers.registerDefaults();
|
||||
// --
|
||||
|
||||
AttachedRegistry.unwrapAll();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
package com.simibubi.create.api.behaviour;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.compat.tconstruct.SpoutCasting;
|
||||
import com.simibubi.create.content.fluids.spout.SpoutBlockEntity;
|
||||
import com.simibubi.create.impl.behaviour.BlockSpoutingBehaviourImpl;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.neoforged.neoforge.fluids.FluidStack;
|
||||
|
||||
public abstract class BlockSpoutingBehaviour {
|
||||
/**
|
||||
* Register a new custom spout interaction
|
||||
*
|
||||
* @param resourceLocation The interaction id
|
||||
* @param spoutingBehaviour An instance of your behaviour class
|
||||
*/
|
||||
public static void addCustomSpoutInteraction(ResourceLocation resourceLocation, BlockSpoutingBehaviour spoutingBehaviour) {
|
||||
BlockSpoutingBehaviourImpl.addCustomSpoutInteraction(resourceLocation, spoutingBehaviour);
|
||||
}
|
||||
|
||||
public static void registerDefaults() {
|
||||
addCustomSpoutInteraction(Create.asResource("ticon_casting"), new SpoutCasting());
|
||||
}
|
||||
|
||||
/**
|
||||
* While idle, Spouts will call this every tick with simulate == true <br>
|
||||
* When fillBlock returns > 0, the Spout will start its animation cycle <br>
|
||||
* <br>
|
||||
* During this animation cycle, fillBlock is called once again with simulate == false but only on the relevant SpoutingBehaviour <br>
|
||||
* When fillBlock returns > 0 once again, the Spout will drain its content by the returned amount of units <br>
|
||||
* Perform any other side effects in this method <br>
|
||||
* This method is called server-side only (except in ponder) <br>
|
||||
*
|
||||
* @param level The current level
|
||||
* @param pos The position of the affected block
|
||||
* @param spout The spout block entity that is calling this
|
||||
* @param availableFluid A copy of the fluidStack that is available, modifying this will do nothing, return the amount to be subtracted instead
|
||||
* @param simulate Whether the spout is testing or actually performing this behaviour
|
||||
* @return The amount filled into the block, 0 to idle/cancel
|
||||
*/
|
||||
public abstract int fillBlock(Level level, BlockPos pos, SpoutBlockEntity spout, FluidStack availableFluid, boolean simulate);
|
||||
|
||||
}
|
|
@ -0,0 +1,172 @@
|
|||
package com.simibubi.create.api.behaviour.display;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.simibubi.create.AllDisplaySources;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.api.registry.CreateBuiltInRegistries;
|
||||
import com.simibubi.create.api.registry.CreateRegistries;
|
||||
import com.simibubi.create.api.registry.SimpleRegistry;
|
||||
import com.simibubi.create.content.redstone.displayLink.DisplayLinkContext;
|
||||
import com.simibubi.create.content.redstone.displayLink.target.DisplayBoardTarget;
|
||||
import com.simibubi.create.content.redstone.displayLink.target.DisplayTargetStats;
|
||||
import com.simibubi.create.content.trains.display.FlapDisplayBlockEntity;
|
||||
import com.simibubi.create.content.trains.display.FlapDisplayLayout;
|
||||
import com.simibubi.create.foundation.gui.ModularGuiLineBuilder;
|
||||
import com.tterrag.registrate.builders.BlockBuilder;
|
||||
import com.tterrag.registrate.util.entry.RegistryEntry;
|
||||
import com.tterrag.registrate.util.nullness.NonNullUnaryOperator;
|
||||
|
||||
import net.createmod.catnip.nbt.NBTProcessors;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
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.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
|
||||
public abstract class DisplaySource {
|
||||
public static final SimpleRegistry.Multi<Block, DisplaySource> BY_BLOCK = SimpleRegistry.Multi.create();
|
||||
public static final SimpleRegistry.Multi<BlockEntityType<?>, DisplaySource> BY_BLOCK_ENTITY = SimpleRegistry.Multi.create();
|
||||
|
||||
public static final List<MutableComponent> EMPTY = ImmutableList.of(Component.empty());
|
||||
public static final MutableComponent EMPTY_LINE = Component.empty();
|
||||
public static final MutableComponent WHITESPACE = CommonComponents.space();
|
||||
|
||||
public abstract List<MutableComponent> provideText(DisplayLinkContext context, DisplayTargetStats stats);
|
||||
|
||||
public void transferData(DisplayLinkContext context, DisplayTarget activeTarget, int line) {
|
||||
DisplayTargetStats stats = activeTarget.provideStats(context);
|
||||
|
||||
if (activeTarget instanceof DisplayBoardTarget fddt) {
|
||||
List<List<MutableComponent>> flapDisplayText = provideFlapDisplayText(context, stats);
|
||||
fddt.acceptFlapText(line, flapDisplayText, context);
|
||||
}
|
||||
|
||||
List<MutableComponent> text = provideText(context, stats);
|
||||
if (text.isEmpty())
|
||||
text = EMPTY;
|
||||
|
||||
if (activeTarget.requiresComponentSanitization())
|
||||
for (MutableComponent component : text)
|
||||
if (NBTProcessors.textComponentHasClickEvent(component))
|
||||
return; // Naughty
|
||||
|
||||
activeTarget.acceptText(line, text, context);
|
||||
}
|
||||
|
||||
public void onSignalReset(DisplayLinkContext context) {
|
||||
}
|
||||
|
||||
public void populateData(DisplayLinkContext context) {
|
||||
}
|
||||
|
||||
public int getPassiveRefreshTicks() {
|
||||
return 100;
|
||||
}
|
||||
|
||||
public boolean shouldPassiveReset() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected final ResourceLocation getId() {
|
||||
return CreateBuiltInRegistries.DISPLAY_SOURCE.getKey(this);
|
||||
}
|
||||
|
||||
protected String getTranslationKey() {
|
||||
return this.getId().getPath();
|
||||
}
|
||||
|
||||
public Component getName() {
|
||||
return Component.translatable(this.getId().getNamespace() + ".display_source." + getTranslationKey());
|
||||
}
|
||||
|
||||
public void loadFlapDisplayLayout(DisplayLinkContext context, FlapDisplayBlockEntity flapDisplay, FlapDisplayLayout layout, int lineIndex) {
|
||||
loadFlapDisplayLayout(context, flapDisplay, layout);
|
||||
}
|
||||
|
||||
public void loadFlapDisplayLayout(DisplayLinkContext context, FlapDisplayBlockEntity flapDisplay,
|
||||
FlapDisplayLayout layout) {
|
||||
if (!layout.isLayout("Default"))
|
||||
layout.loadDefault(flapDisplay.getMaxCharCount());
|
||||
}
|
||||
|
||||
public List<List<MutableComponent>> provideFlapDisplayText(DisplayLinkContext context, DisplayTargetStats stats) {
|
||||
return provideText(context, stats).stream()
|
||||
.map(Arrays::asList)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void initConfigurationWidgets(DisplayLinkContext context, ModularGuiLineBuilder builder,
|
||||
boolean isFirstLine) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility for use with Registrate builders. Creates a builder transformer
|
||||
* that will register the given DisplaySource to a block when ready.
|
||||
*/
|
||||
public static <B extends Block, P> NonNullUnaryOperator<BlockBuilder<B, P>> displaySource(RegistryEntry<DisplaySource, ? extends DisplaySource> source) {
|
||||
return builder -> builder.onRegisterAfter(CreateRegistries.DISPLAY_SOURCE, block -> BY_BLOCK.add(block, source.get()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DisplaySource with the given ID, accounting for legacy names.
|
||||
*/
|
||||
@Nullable
|
||||
public static DisplaySource get(@Nullable ResourceLocation id) {
|
||||
if (id == null)
|
||||
return null;
|
||||
|
||||
if (id.getNamespace().equals(Create.ID) && AllDisplaySources.LEGACY_NAMES.containsKey(id.getPath())) {
|
||||
return AllDisplaySources.LEGACY_NAMES.get(id.getPath()).get();
|
||||
}
|
||||
|
||||
return CreateBuiltInRegistries.DISPLAY_SOURCE.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all DisplaySources applicable to the block at the given location, checking both the Block and BlockEntity.
|
||||
* Returns an empty list if none are present, not null.
|
||||
*/
|
||||
public static List<DisplaySource> getAll(LevelAccessor level, BlockPos pos) {
|
||||
BlockState state = level.getBlockState(pos);
|
||||
List<DisplaySource> byBlock = BY_BLOCK.get(state);
|
||||
|
||||
BlockEntity be = level.getBlockEntity(pos);
|
||||
if (be == null)
|
||||
return byBlock;
|
||||
|
||||
List<DisplaySource> byBe = BY_BLOCK_ENTITY.get(be.getType());
|
||||
|
||||
if (byBlock.isEmpty()) {
|
||||
if (byBe.isEmpty()) {
|
||||
// none
|
||||
return List.of();
|
||||
} else {
|
||||
// only BlockEntity
|
||||
return byBe;
|
||||
}
|
||||
} else if (byBe.isEmpty()) {
|
||||
// only Block
|
||||
return byBlock;
|
||||
} else {
|
||||
// both present, combine
|
||||
List<DisplaySource> combined = new ArrayList<>(byBlock);
|
||||
combined.addAll(byBe);
|
||||
return combined;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
package com.simibubi.create.api.behaviour.display;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllDisplayTargets;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.api.registry.CreateBuiltInRegistries;
|
||||
import com.simibubi.create.api.registry.CreateRegistries;
|
||||
import com.simibubi.create.api.registry.SimpleRegistry;
|
||||
import com.simibubi.create.content.redstone.displayLink.DisplayLinkContext;
|
||||
import com.simibubi.create.content.redstone.displayLink.target.DisplayTargetStats;
|
||||
import com.simibubi.create.foundation.utility.CreateLang;
|
||||
import com.tterrag.registrate.builders.BlockBuilder;
|
||||
import com.tterrag.registrate.util.entry.RegistryEntry;
|
||||
import com.tterrag.registrate.util.nullness.NonNullUnaryOperator;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
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.minecraft.world.level.block.entity.SignBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
|
||||
public abstract class DisplayTarget {
|
||||
public static final SimpleRegistry<Block, DisplayTarget> BY_BLOCK = SimpleRegistry.create();
|
||||
public static final SimpleRegistry<BlockEntityType<?>, DisplayTarget> BY_BLOCK_ENTITY = SimpleRegistry.create();
|
||||
|
||||
public abstract void acceptText(int line, List<MutableComponent> text, DisplayLinkContext context);
|
||||
|
||||
public abstract DisplayTargetStats provideStats(DisplayLinkContext context);
|
||||
|
||||
public AABB getMultiblockBounds(LevelAccessor level, BlockPos pos) {
|
||||
VoxelShape shape = level.getBlockState(pos)
|
||||
.getShape(level, pos);
|
||||
if (shape.isEmpty())
|
||||
return new AABB(pos);
|
||||
return shape.bounds()
|
||||
.move(pos);
|
||||
}
|
||||
|
||||
public Component getLineOptionText(int line) {
|
||||
return CreateLang.translateDirect("display_target.line", line + 1);
|
||||
}
|
||||
|
||||
public static void reserve(int line, BlockEntity target, DisplayLinkContext context) {
|
||||
if (line == 0)
|
||||
return;
|
||||
|
||||
CompoundTag tag = target.getPersistentData();
|
||||
CompoundTag compound = tag.getCompound("DisplayLink");
|
||||
compound.putLong("Line" + line, context.blockEntity()
|
||||
.getBlockPos()
|
||||
.asLong());
|
||||
tag.put("DisplayLink", compound);
|
||||
}
|
||||
|
||||
public boolean isReserved(int line, BlockEntity target, DisplayLinkContext context) {
|
||||
CompoundTag tag = target.getPersistentData();
|
||||
CompoundTag compound = tag.getCompound("DisplayLink");
|
||||
|
||||
if (!compound.contains("Line" + line))
|
||||
return false;
|
||||
|
||||
long l = compound.getLong("Line" + line);
|
||||
BlockPos reserved = BlockPos.of(l);
|
||||
|
||||
if (!reserved.equals(context.blockEntity()
|
||||
.getBlockPos()) && AllBlocks.DISPLAY_LINK.has(target.getLevel()
|
||||
.getBlockState(reserved)))
|
||||
return true;
|
||||
|
||||
compound.remove("Line" + line);
|
||||
if (compound.isEmpty())
|
||||
tag.remove("DisplayLink");
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean requiresComponentSanitization() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility for use with Registrate builders. Creates a builder transformer
|
||||
* that will register the given DisplayTarget to a block when ready.
|
||||
*/
|
||||
public static <B extends Block, P> NonNullUnaryOperator<BlockBuilder<B, P>> displayTarget(RegistryEntry<DisplayTarget, ? extends DisplayTarget> target) {
|
||||
return builder -> builder.onRegisterAfter(CreateRegistries.DISPLAY_TARGET, block -> BY_BLOCK.register(block, target.get()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DisplayTarget with the given ID, accounting for legacy names.
|
||||
*/
|
||||
@Nullable
|
||||
public static DisplayTarget get(@Nullable ResourceLocation id) {
|
||||
if (id == null)
|
||||
return null;
|
||||
|
||||
if (id.getNamespace().equals(Create.ID) && AllDisplayTargets.LEGACY_NAMES.containsKey(id.getPath())) {
|
||||
return AllDisplayTargets.LEGACY_NAMES.get(id.getPath()).get();
|
||||
}
|
||||
|
||||
return CreateBuiltInRegistries.DISPLAY_TARGET.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DisplayTarget applicable to the given location, or null if there isn't one.
|
||||
*/
|
||||
@Nullable
|
||||
public static DisplayTarget get(LevelAccessor level, BlockPos pos) {
|
||||
BlockState state = level.getBlockState(pos);
|
||||
DisplayTarget byBlock = BY_BLOCK.get(state);
|
||||
// block takes priority if present, it's more granular
|
||||
if (byBlock != null)
|
||||
return byBlock;
|
||||
|
||||
BlockEntity be = level.getBlockEntity(pos);
|
||||
if (be == null)
|
||||
return null;
|
||||
|
||||
DisplayTarget byBe = BY_BLOCK_ENTITY.get(be.getType());
|
||||
if (byBe != null)
|
||||
return byBe;
|
||||
|
||||
// special case: modded signs are common
|
||||
return be instanceof SignBlockEntity ? AllDisplayTargets.SIGN.get() : null;
|
||||
}
|
||||
}
|
|
@ -1,11 +1,12 @@
|
|||
package com.simibubi.create.content.processing.burner;
|
||||
package com.simibubi.create.api.behaviour.interaction;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.AllSoundEvents;
|
||||
import com.simibubi.create.api.contraption.train.TrainConductorHandler;
|
||||
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.Contraption;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovingInteractionBehaviour;
|
||||
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
|
||||
import com.simibubi.create.content.trains.entity.CarriageContraption;
|
||||
import com.simibubi.create.content.trains.entity.CarriageContraptionEntity;
|
||||
import com.simibubi.create.content.trains.entity.Train;
|
||||
|
@ -25,20 +26,25 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
/**
|
||||
* Partial interaction behavior implementation that allows blocks to act as conductors on trains, like Blaze Burners.
|
||||
*/
|
||||
public abstract class ConductorBlockInteractionBehavior extends MovingInteractionBehaviour {
|
||||
/**
|
||||
* Check if the given state is capable of being a conductor.
|
||||
*/
|
||||
public abstract boolean isValidConductor(BlockState state);
|
||||
|
||||
public class BlockBasedTrainConductorInteractionBehaviour extends MovingInteractionBehaviour {
|
||||
|
||||
private final Predicate<BlockState> isValidConductor;
|
||||
private final TrainConductorHandler.UpdateScheduleCallback callback;
|
||||
|
||||
public BlockBasedTrainConductorInteractionBehaviour(Predicate<BlockState> isValidConductor, TrainConductorHandler.UpdateScheduleCallback callback) {
|
||||
this.isValidConductor = isValidConductor;
|
||||
this.callback = callback;
|
||||
/**
|
||||
* Called when the conductor's schedule has changed.
|
||||
* @param hasSchedule true if the schedule was set, false if it was removed
|
||||
* @param blockStateSetter a consumer that will change the BlockState of this conductor on the contraption
|
||||
*/
|
||||
protected void onScheduleUpdate(boolean hasSchedule, BlockState currentBlockState, Consumer<BlockState> blockStateSetter) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handlePlayerInteraction(Player player, InteractionHand activeHand, BlockPos localPos,
|
||||
public final boolean handlePlayerInteraction(Player player, InteractionHand activeHand, BlockPos localPos,
|
||||
AbstractContraptionEntity contraptionEntity) {
|
||||
ItemStack itemInHand = player.getItemInHand(activeHand);
|
||||
|
||||
|
@ -52,7 +58,7 @@ public class BlockBasedTrainConductorInteractionBehaviour extends MovingInteract
|
|||
|
||||
StructureBlockInfo info = carriageContraption.getBlocks()
|
||||
.get(localPos);
|
||||
if (info == null || !isValidConductor.test(info.state()))
|
||||
if (info == null || !this.isValidConductor(info.state()))
|
||||
return false;
|
||||
|
||||
Direction assemblyDirection = carriageContraption.getAssemblyDirection();
|
||||
|
@ -85,7 +91,7 @@ public class BlockBasedTrainConductorInteractionBehaviour extends MovingInteract
|
|||
train.runtime.isAutoSchedule ? "schedule.auto_removed_from_train" : "schedule.removed_from_train"),
|
||||
true);
|
||||
player.setItemInHand(activeHand, train.runtime.returnSchedule(player.registryAccess()));
|
||||
callback.update(false, info.state(), newBlockState -> setBlockState(localPos, contraptionEntity, newBlockState));
|
||||
this.onScheduleUpdate(false, info.state(), newBlockState -> setBlockState(localPos, contraptionEntity, newBlockState));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -101,7 +107,7 @@ public class BlockBasedTrainConductorInteractionBehaviour extends MovingInteract
|
|||
player.displayClientMessage(CreateLang.translateDirect("schedule.no_stops"), true);
|
||||
return true;
|
||||
}
|
||||
callback.update(true, info.state(), newBlockState -> setBlockState(localPos, contraptionEntity, newBlockState));
|
||||
this.onScheduleUpdate(true, info.state(), newBlockState -> setBlockState(localPos, contraptionEntity, newBlockState));
|
||||
train.runtime.setSchedule(schedule, false);
|
||||
AllAdvancements.CONDUCTOR.awardTo(player);
|
||||
AllSoundEvents.CONFIRM.playOnServer(player.level(), player.blockPosition(), 1, 1);
|
||||
|
@ -123,4 +129,14 @@ public class BlockBasedTrainConductorInteractionBehaviour extends MovingInteract
|
|||
setContraptionBlockData(contraption, localPos, new StructureTemplate.StructureBlockInfo(info.pos(), newState, info.nbt()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation used for Blaze Burners. May be reused by addons if applicable.
|
||||
*/
|
||||
public static class BlazeBurner extends ConductorBlockInteractionBehavior {
|
||||
@Override
|
||||
public boolean isValidConductor(BlockState state) {
|
||||
return state.getValue(BlazeBurnerBlock.HEAT_LEVEL) != BlazeBurnerBlock.HeatLevel.NONE;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,16 +1,32 @@
|
|||
package com.simibubi.create.content.contraptions.behaviour;
|
||||
package com.simibubi.create.api.behaviour.interaction;
|
||||
|
||||
import org.apache.commons.lang3.tuple.MutablePair;
|
||||
|
||||
import com.simibubi.create.api.registry.SimpleRegistry;
|
||||
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||
import com.tterrag.registrate.util.nullness.NonNullConsumer;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo;
|
||||
|
||||
/**
|
||||
* MovingInteractionBehaviors define behavior of blocks on contraptions
|
||||
* when interacted with by players or collided with by entities.
|
||||
*/
|
||||
public abstract class MovingInteractionBehaviour {
|
||||
public static final SimpleRegistry<Block, MovingInteractionBehaviour> REGISTRY = SimpleRegistry.create();
|
||||
|
||||
/**
|
||||
* Creates a consumer that will register a behavior to a block. Useful for Registrate.
|
||||
*/
|
||||
public static <B extends Block> NonNullConsumer<? super B> interactionBehaviour(MovingInteractionBehaviour behaviour) {
|
||||
return b -> REGISTRY.register(b, behaviour);
|
||||
}
|
||||
|
||||
protected void setContraptionActorData(AbstractContraptionEntity contraptionEntity, int index,
|
||||
StructureBlockInfo info, MovementContext ctx) {
|
|
@ -1,11 +1,14 @@
|
|||
package com.simibubi.create.content.contraptions.behaviour;
|
||||
package com.simibubi.create.api.behaviour.movement;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.simibubi.create.api.registry.SimpleRegistry;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||
import com.simibubi.create.content.contraptions.render.ActorVisual;
|
||||
import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
|
||||
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
|
||||
import com.simibubi.create.infrastructure.config.AllConfigs;
|
||||
import com.tterrag.registrate.util.nullness.NonNullConsumer;
|
||||
|
||||
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
|
@ -14,11 +17,24 @@ import net.minecraft.world.entity.item.ItemEntity;
|
|||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import net.neoforged.neoforge.items.ItemHandlerHelper;
|
||||
|
||||
/**
|
||||
* MovementBehaviors, also known as Actors, provide behavior to blocks mounted on contraptions.
|
||||
* Blocks may be associated with a behavior through {@link #REGISTRY}.
|
||||
*/
|
||||
public interface MovementBehaviour {
|
||||
SimpleRegistry<Block, MovementBehaviour> REGISTRY = SimpleRegistry.create();
|
||||
|
||||
/**
|
||||
* Creates a consumer that will register a behavior to a block. Useful for Registrate.
|
||||
*/
|
||||
static <B extends Block> NonNullConsumer<? super B> movementBehaviour(MovementBehaviour behaviour) {
|
||||
return b -> REGISTRY.register(b, behaviour);
|
||||
}
|
||||
|
||||
default boolean isActive(MovementContext context) {
|
||||
return !context.disabled;
|
|
@ -0,0 +1,103 @@
|
|||
package com.simibubi.create.api.behaviour.spouting;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.api.registry.SimpleRegistry;
|
||||
import com.simibubi.create.compat.Mods;
|
||||
import com.simibubi.create.compat.tconstruct.SpoutCasting;
|
||||
import com.simibubi.create.content.fluids.spout.SpoutBlockEntity;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
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.FarmBlock;
|
||||
import net.minecraft.world.level.block.LayeredCauldronBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
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.neoforged.neoforge.fluids.FluidStack;
|
||||
|
||||
/**
|
||||
* Interface for custom block-filling behavior for spouts.
|
||||
* <p>
|
||||
* Behaviors are queried by block first, through {@link #BY_BLOCK}. If no behavior was provided,
|
||||
* they are then queried by block entity type, through {@link #BY_BLOCK_ENTITY}.
|
||||
* @see StateChangingBehavior
|
||||
* @see CauldronSpoutingBehavior
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface BlockSpoutingBehaviour {
|
||||
SimpleRegistry<Block, BlockSpoutingBehaviour> BY_BLOCK = SimpleRegistry.create();
|
||||
SimpleRegistry<BlockEntityType<?>, BlockSpoutingBehaviour> BY_BLOCK_ENTITY = SimpleRegistry.create();
|
||||
|
||||
/**
|
||||
* Get the behavior that should be used for the block at the given location.
|
||||
* Queries both the block and the block entity if needed.
|
||||
*/
|
||||
@Nullable
|
||||
static BlockSpoutingBehaviour get(Level level, BlockPos pos) {
|
||||
BlockState state = level.getBlockState(pos);
|
||||
BlockSpoutingBehaviour byBlock = BY_BLOCK.get(state.getBlock());
|
||||
if (byBlock != null)
|
||||
return byBlock;
|
||||
|
||||
BlockEntity be = level.getBlockEntity(pos);
|
||||
if (be == null)
|
||||
return null;
|
||||
|
||||
return BY_BLOCK_ENTITY.get(be.getType());
|
||||
}
|
||||
|
||||
static void registerDefaults() {
|
||||
Predicate<Fluid> isWater = fluid -> fluid.isSame(Fluids.WATER);
|
||||
BlockSpoutingBehaviour toMud = StateChangingBehavior.setTo(250, isWater, Blocks.MUD);
|
||||
|
||||
for (Block dirt : List.of(Blocks.DIRT, Blocks.COARSE_DIRT, Blocks.ROOTED_DIRT)) {
|
||||
BY_BLOCK.register(dirt, toMud);
|
||||
}
|
||||
|
||||
BY_BLOCK.register(Blocks.FARMLAND, StateChangingBehavior.incrementingState(100, isWater, FarmBlock.MOISTURE));
|
||||
BY_BLOCK.register(Blocks.WATER_CAULDRON, StateChangingBehavior.incrementingState(250, isWater, LayeredCauldronBlock.LEVEL));
|
||||
BY_BLOCK.register(Blocks.CAULDRON, CauldronSpoutingBehavior.INSTANCE);
|
||||
|
||||
if (!Mods.TCONSTRUCT.isLoaded())
|
||||
return;
|
||||
|
||||
for (String name : List.of("table", "basin")) {
|
||||
ResourceLocation id = Mods.TCONSTRUCT.rl(name);
|
||||
if (BuiltInRegistries.BLOCK_ENTITY_TYPE.containsKey(id)) {
|
||||
BlockEntityType<?> table = BuiltInRegistries.BLOCK_ENTITY_TYPE.get(id);
|
||||
BY_BLOCK_ENTITY.register(table, SpoutCasting.INSTANCE);
|
||||
} else {
|
||||
Create.LOGGER.warn("Block entity {} wasn't found. Outdated compat?", id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* While idle, spouts will query the behavior provided by the block below it.
|
||||
* If one is present, this method will be called every tick with simulate == true.
|
||||
* <p>
|
||||
* When a value greater than 0 is returned, the spout will begin processing. It will call this method again
|
||||
* with simulate == false, which is when any filling behavior should actually occur.
|
||||
* <p>
|
||||
* This method is only called on the server side, except for in Ponder.
|
||||
* @param level The current level
|
||||
* @param pos The position of the affected block
|
||||
* @param spout The spout block entity that is calling this
|
||||
* @param availableFluid A copy of the fluidStack that is available, modifying this will do nothing, return the amount to be subtracted instead
|
||||
* @param simulate Whether the spout is testing or actually performing this behaviour
|
||||
* @return The amount filled into the block, 0 to idle/cancel
|
||||
*/
|
||||
int fillBlock(Level level, BlockPos pos, SpoutBlockEntity spout, FluidStack availableFluid, boolean simulate);
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package com.simibubi.create.api.behaviour.spouting;
|
||||
|
||||
import com.simibubi.create.api.registry.SimpleRegistry;
|
||||
import com.simibubi.create.content.fluids.spout.SpoutBlockEntity;
|
||||
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
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.state.BlockState;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
|
||||
import net.neoforged.neoforge.fluids.FluidStack;
|
||||
|
||||
/**
|
||||
* {@link BlockSpoutingBehaviour} for empty cauldrons. Mods can register their fluids
|
||||
* to {@link #CAULDRON_INFO} to allow spouts to fill empty cauldrons with their fluids.
|
||||
*/
|
||||
public enum CauldronSpoutingBehavior implements BlockSpoutingBehaviour {
|
||||
INSTANCE;
|
||||
|
||||
public static final SimpleRegistry<Fluid, CauldronInfo> CAULDRON_INFO = Util.make(() -> {
|
||||
SimpleRegistry<Fluid, CauldronInfo> registry = SimpleRegistry.create();
|
||||
registry.register(Fluids.WATER, new CauldronInfo(250, Blocks.WATER_CAULDRON));
|
||||
registry.register(Fluids.LAVA, new CauldronInfo(1000, Blocks.LAVA_CAULDRON));
|
||||
return registry;
|
||||
});
|
||||
|
||||
@Override
|
||||
public int fillBlock(Level level, BlockPos pos, SpoutBlockEntity spout, FluidStack availableFluid, boolean simulate) {
|
||||
CauldronInfo info = CAULDRON_INFO.get(availableFluid.getFluid());
|
||||
if (info == null)
|
||||
return 0;
|
||||
|
||||
if (availableFluid.getAmount() < info.amount)
|
||||
return 0;
|
||||
|
||||
if (!simulate) {
|
||||
level.setBlockAndUpdate(pos, info.cauldron);
|
||||
}
|
||||
|
||||
return info.amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param amount the amount of fluid that must be inserted into an empty cauldron
|
||||
* @param cauldron the BlockState to set after filling an empty cauldron with the given amount of fluid
|
||||
*/
|
||||
public record CauldronInfo(int amount, BlockState cauldron) {
|
||||
public CauldronInfo(int amount, Block block) {
|
||||
this(amount, block.defaultBlockState());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package com.simibubi.create.api.behaviour.spouting;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
import com.simibubi.create.content.fluids.spout.SpoutBlockEntity;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
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.block.state.properties.IntegerProperty;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
|
||||
import net.neoforged.neoforge.fluids.FluidStack;
|
||||
|
||||
/**
|
||||
* An implementation of {@link BlockSpoutingBehaviour} that allows for easily modifying a BlockState through spouting.
|
||||
* @param amount the amount of fluid consumed when filling
|
||||
* @param fluidTest a predicate for fluids that can be used to fill the target block
|
||||
* @param canFill a predicate that must match the target BlockState to fill it
|
||||
* @param fillFunction a function that converts the current state into the filled one
|
||||
*/
|
||||
public record StateChangingBehavior(int amount, Predicate<Fluid> fluidTest, Predicate<BlockState> canFill,
|
||||
UnaryOperator<BlockState> fillFunction) implements BlockSpoutingBehaviour {
|
||||
@Override
|
||||
public int fillBlock(Level level, BlockPos pos, SpoutBlockEntity spout, FluidStack availableFluid, boolean simulate) {
|
||||
if (availableFluid.getAmount() < this.amount || !this.fluidTest.test(availableFluid.getFluid()))
|
||||
return 0;
|
||||
|
||||
BlockState state = level.getBlockState(pos);
|
||||
if (!this.canFill.test(state))
|
||||
return 0;
|
||||
|
||||
if (!simulate) {
|
||||
BlockState newState = this.fillFunction.apply(state);
|
||||
level.setBlockAndUpdate(pos, newState);
|
||||
}
|
||||
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for {@link #setTo(int, Predicate, BlockState)} that uses the Block's default state.
|
||||
*/
|
||||
public static BlockSpoutingBehaviour setTo(int amount, Predicate<Fluid> fluidTest, Block block) {
|
||||
return setTo(amount, fluidTest, block.defaultBlockState());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link BlockSpoutingBehaviour} that will simply convert the target block to the given state.
|
||||
* @param newState the state that will be set after filling
|
||||
*/
|
||||
public static BlockSpoutingBehaviour setTo(int amount, Predicate<Fluid> fluidTest, BlockState newState) {
|
||||
return new StateChangingBehavior(amount, fluidTest, state -> true, state -> newState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link BlockSpoutingBehaviour} that will increment the given {@link IntegerProperty} until it reaches
|
||||
* its maximum value, consuming {@code amount} each time fluid is filled.
|
||||
* @param property the property that will be incremented by one on each fill
|
||||
*/
|
||||
public static BlockSpoutingBehaviour incrementingState(int amount, Predicate<Fluid> fluidTest, IntegerProperty property) {
|
||||
int max = property.getPossibleValues().stream().max(Integer::compareTo).orElseThrow();
|
||||
|
||||
Predicate<BlockState> canFill = state -> state.getValue(property) < max;
|
||||
UnaryOperator<BlockState> fillFunction = state -> state.setValue(property, state.getValue(property) + 1);
|
||||
|
||||
return new StateChangingBehavior(amount, fluidTest, canFill, fillFunction);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package com.simibubi.create.api.boiler;
|
||||
|
||||
import com.simibubi.create.api.registry.SimpleRegistry;
|
||||
import com.simibubi.create.content.fluids.tank.BoilerHeaters;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
/**
|
||||
* A BoilerHeater provides heat to boilers.
|
||||
* Boilers will query blocks for heaters through the registry, usually with {@link #findHeat(Level, BlockPos, BlockState) findHeat}.
|
||||
* Heaters can provide a heat level by returning any positive integer from their {@link #getHeat(Level, BlockPos, BlockState) getHeat} method.
|
||||
* Returning any negative number counts as no heat - {@link #NO_HEAT} is provided for convenience.
|
||||
* <p>
|
||||
* Returning {@link #PASSIVE_HEAT} is special - passive heat can be used to provide a small amount of heat, highly limiting
|
||||
* in its abilities. This is usually used for free sources of heat, such as fire or magma blocks.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface BoilerHeater {
|
||||
int PASSIVE_HEAT = 0;
|
||||
int NO_HEAT = -1;
|
||||
|
||||
/**
|
||||
* The heater used by common passively-heating blocks. Automatically provides
|
||||
* heat for any block in the {@code create:passive_boiler_heaters} block tag.
|
||||
*/
|
||||
BoilerHeater PASSIVE = BoilerHeaters::passive;
|
||||
/**
|
||||
* The heater used by Blaze Burners. Addons can register this to their own blocks if they use the same functionality.
|
||||
*/
|
||||
BoilerHeater BLAZE_BURNER = BoilerHeaters::blazeBurner;
|
||||
|
||||
SimpleRegistry<Block, BoilerHeater> REGISTRY = SimpleRegistry.create();
|
||||
|
||||
/**
|
||||
* Gets the heat at the given location. If a heater is present, queries it for heat. If not, returns {@link #NO_HEAT}.
|
||||
*/
|
||||
static float findHeat(Level level, BlockPos pos, BlockState state) {
|
||||
BoilerHeater heater = REGISTRY.get(state);
|
||||
return heater != null ? heater.getHeat(level, pos, state) : NO_HEAT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the amount of heat to provide.
|
||||
* @see #NO_HEAT
|
||||
* @see #PASSIVE_HEAT
|
||||
*/
|
||||
float getHeat(Level level, BlockPos pos, BlockState state);
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
package com.simibubi.create.api.contraption;
|
||||
|
||||
import com.simibubi.create.impl.contraption.BlockMovementChecksImpl;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
/**
|
||||
* Provides several interfaces that can define the behavior of blocks when mounting onto contraptions:
|
||||
* <ul>
|
||||
* <li>{@link MovementNecessaryCheck}</li>
|
||||
* <li>{@link MovementAllowedCheck}</li>
|
||||
* <li>{@link BrittleCheck}</li>
|
||||
* <li>{@link AttachedCheck}</li>
|
||||
* <li>{@link NotSupportiveCheck}</li>
|
||||
* </ul>
|
||||
* See each one for details.
|
||||
* <p>
|
||||
* For each interface, checks can be registered and queried.
|
||||
* Registration is thread-safe and can be done in parallel mod init.
|
||||
* Each query will iterate all registered checks of that type in reverse-registration order. If a check returns
|
||||
* a non-{@link CheckResult#PASS PASS} result, that is the result of the query. If no check catches a query, then
|
||||
* a best-effort fallback is used.
|
||||
*/
|
||||
public class BlockMovementChecks {
|
||||
public static void registerMovementNecessaryCheck(MovementNecessaryCheck check) {
|
||||
BlockMovementChecksImpl.registerMovementNecessaryCheck(check);
|
||||
}
|
||||
|
||||
public static void registerMovementAllowedCheck(MovementAllowedCheck check) {
|
||||
BlockMovementChecksImpl.registerMovementAllowedCheck(check);
|
||||
}
|
||||
|
||||
public static void registerBrittleCheck(BrittleCheck check) {
|
||||
BlockMovementChecksImpl.registerBrittleCheck(check);
|
||||
}
|
||||
|
||||
public static void registerAttachedCheck(AttachedCheck check) {
|
||||
BlockMovementChecksImpl.registerAttachedCheck(check);
|
||||
}
|
||||
|
||||
public static void registerNotSupportiveCheck(NotSupportiveCheck check) {
|
||||
BlockMovementChecksImpl.registerNotSupportiveCheck(check);
|
||||
}
|
||||
|
||||
// queries
|
||||
|
||||
public static boolean isMovementNecessary(BlockState state, Level world, BlockPos pos) {
|
||||
return BlockMovementChecksImpl.isMovementNecessary(state, world, pos);
|
||||
}
|
||||
|
||||
public static boolean isMovementAllowed(BlockState state, Level world, BlockPos pos) {
|
||||
return BlockMovementChecksImpl.isMovementAllowed(state, world, pos);
|
||||
}
|
||||
|
||||
public static boolean isBrittle(BlockState state) {
|
||||
return BlockMovementChecksImpl.isBrittle(state);
|
||||
}
|
||||
|
||||
public static boolean isBlockAttachedTowards(BlockState state, Level world, BlockPos pos, Direction direction) {
|
||||
return BlockMovementChecksImpl.isBlockAttachedTowards(state, world, pos, direction);
|
||||
}
|
||||
|
||||
public static boolean isNotSupportive(BlockState state, Direction facing) {
|
||||
return BlockMovementChecksImpl.isNotSupportive(state, facing);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface MovementNecessaryCheck {
|
||||
/**
|
||||
* Determine if it's necessary to move the given block. Contraptions
|
||||
* will generally ignore blocks that are unnecessary to move.
|
||||
*/
|
||||
CheckResult isMovementNecessary(BlockState state, Level world, BlockPos pos);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface MovementAllowedCheck {
|
||||
/**
|
||||
* Determine if the given block is movable. Immobile blocks will generally prevent a contraption from assembling.
|
||||
* @see ContraptionMovementSetting
|
||||
*/
|
||||
CheckResult isMovementAllowed(BlockState state, Level world, BlockPos pos);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface BrittleCheck {
|
||||
/**
|
||||
* Brittle blocks are blocks that require another block for support, like torches or ladders.
|
||||
* They're collected first to avoid them breaking when their support block is removed.
|
||||
*/
|
||||
CheckResult isBrittle(BlockState state);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface AttachedCheck {
|
||||
/**
|
||||
* Determine if the given block is attached to the block in the given direction.
|
||||
* Attached blocks will be moved together. Examples:
|
||||
* <ul>
|
||||
* <li>Ladders are attached to their support block</li>
|
||||
* <li>Pressure plates are attached to the floor</li>
|
||||
* <li>Fluid tanks are attached to others in their multiblock</li>
|
||||
* <li>Bed halves are attached to each other</li>
|
||||
* </ul>
|
||||
*/
|
||||
CheckResult isBlockAttachedTowards(BlockState state, Level world, BlockPos pos, Direction direction);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface NotSupportiveCheck {
|
||||
/**
|
||||
* Check if the given block is non-supportive in the given direction.
|
||||
* Non-supportive blocks stop block collection propagation.
|
||||
* Examples:
|
||||
* <ul>
|
||||
* <li>Drills are not supportive for the block in front of them</li>
|
||||
* <li>Carpets are not supportive for the block above them</li>
|
||||
* <li>Non-extended stickers are not supportive of the block in front of them</li>
|
||||
* </ul>
|
||||
*/
|
||||
CheckResult isNotSupportive(BlockState state, Direction direction);
|
||||
}
|
||||
|
||||
public enum CheckResult {
|
||||
SUCCESS, FAIL, PASS;
|
||||
|
||||
public boolean toBoolean() {
|
||||
if (this == PASS) {
|
||||
throw new IllegalStateException("PASS does not have a boolean value");
|
||||
}
|
||||
|
||||
return this == SUCCESS;
|
||||
}
|
||||
|
||||
public static CheckResult of(boolean b) {
|
||||
return b ? SUCCESS : FAIL;
|
||||
}
|
||||
|
||||
public static CheckResult of(Boolean b) {
|
||||
return b == null ? PASS : (b ? SUCCESS : FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package com.simibubi.create.api.contraption;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.simibubi.create.api.registry.SimpleRegistry;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
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.levelgen.structure.templatesystem.StructureTemplate;
|
||||
|
||||
import net.neoforged.neoforge.common.extensions.IBlockExtension;
|
||||
|
||||
/**
|
||||
* Defines whether a block is movable by contraptions.
|
||||
* This is used as a fallback check for {@link BlockMovementChecks#isMovementAllowed(BlockState, Level, BlockPos)}.
|
||||
* The registry uses suppliers, so the setting of a block can change. This is useful for config options.
|
||||
*/
|
||||
public enum ContraptionMovementSetting {
|
||||
/**
|
||||
* Block is fully movable with no restrictions.
|
||||
*/
|
||||
MOVABLE,
|
||||
/**
|
||||
* Block can be mounted and moved, but if it's on a minecart contraption, the contraption cannot be picked up.
|
||||
*/
|
||||
NO_PICKUP,
|
||||
/**
|
||||
* Block cannot ever be moved by a contraption.
|
||||
*/
|
||||
UNMOVABLE;
|
||||
|
||||
public static final SimpleRegistry<Block, Supplier<ContraptionMovementSetting>> REGISTRY = SimpleRegistry.create();
|
||||
|
||||
/**
|
||||
* Shortcut that gets the block of the given state.
|
||||
*/
|
||||
@Nullable
|
||||
public static ContraptionMovementSetting get(BlockState state) {
|
||||
return get(state.getBlock());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current movement setting of the given block.
|
||||
*/
|
||||
@Nullable
|
||||
public static ContraptionMovementSetting get(Block block) {
|
||||
if (block instanceof MovementSettingProvider provider)
|
||||
return provider.getContraptionMovementSetting();
|
||||
Supplier<ContraptionMovementSetting> supplier = REGISTRY.get(block);
|
||||
return supplier == null ? null : supplier.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if any of the blocks in the collection match the given setting.
|
||||
*/
|
||||
public static boolean anyAre(Collection<StructureTemplate.StructureBlockInfo> blocks, ContraptionMovementSetting setting) {
|
||||
return blocks.stream().anyMatch(b -> get(b.state().getBlock()) == setting);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if any of the blocks in the collection forbid pickup.
|
||||
*/
|
||||
public static boolean isNoPickup(Collection<StructureTemplate.StructureBlockInfo> blocks) {
|
||||
return anyAre(blocks, ContraptionMovementSetting.NO_PICKUP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface that may optionally be implemented on a Block implementation which will be queried instead of the registry.
|
||||
*/
|
||||
public interface MovementSettingProvider extends IBlockExtension {
|
||||
ContraptionMovementSetting getContraptionMovementSetting();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package com.simibubi.create.api.contraption;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.simibubi.create.AllContraptionTypes;
|
||||
import com.simibubi.create.api.registry.CreateBuiltInRegistries;
|
||||
import com.simibubi.create.content.contraptions.Contraption;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.TagKey;
|
||||
|
||||
public final class ContraptionType {
|
||||
public final Supplier<? extends Contraption> factory;
|
||||
public final Holder.Reference<ContraptionType> holder;
|
||||
|
||||
public ContraptionType(Supplier<? extends Contraption> factory) {
|
||||
this.factory = factory;
|
||||
this.holder = CreateBuiltInRegistries.CONTRAPTION_TYPE.createIntrusiveHolder(this);
|
||||
}
|
||||
|
||||
public boolean is(TagKey<ContraptionType> tag) {
|
||||
return this.holder.is(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup the ContraptionType with the given ID, and create a new Contraption from it if present.
|
||||
* If it doesn't exist, returns null.
|
||||
*/
|
||||
@Nullable
|
||||
public static Contraption fromType(String typeId) {
|
||||
ContraptionType legacy = AllContraptionTypes.BY_LEGACY_NAME.get(typeId);
|
||||
if (legacy != null) {
|
||||
return legacy.factory.get();
|
||||
}
|
||||
|
||||
ResourceLocation id = ResourceLocation.tryParse(typeId);
|
||||
ContraptionType type = CreateBuiltInRegistries.CONTRAPTION_TYPE.get(id);
|
||||
return type == null ? null : type.factory.get();
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
package com.simibubi.create.api.contraption.storage;
|
||||
|
||||
import com.simibubi.create.AllRegistries.Keys;
|
||||
import com.simibubi.create.api.contraption.storage.fluid.MountedFluidStorageType;
|
||||
import com.simibubi.create.api.contraption.storage.item.MountedItemStorageType;
|
||||
import com.simibubi.create.api.lookup.BlockLookup;
|
||||
import com.simibubi.create.impl.contraption.storage.MountedStorageTypeRegistryImpl;
|
||||
import com.tterrag.registrate.builders.BlockBuilder;
|
||||
import com.tterrag.registrate.util.entry.RegistryEntry;
|
||||
import com.tterrag.registrate.util.nullness.NonNullUnaryOperator;
|
||||
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
public class MountedStorageTypeRegistry {
|
||||
/**
|
||||
* Lookup used for finding the item storage type associated with a block.
|
||||
* @see BlockLookup
|
||||
*/
|
||||
public static final BlockLookup<MountedItemStorageType<?>> ITEM_LOOKUP = MountedStorageTypeRegistryImpl.ITEM_LOOKUP;
|
||||
/**
|
||||
* Lookup used for finding the fluid storage type associated with a block.
|
||||
* @see BlockLookup
|
||||
*/
|
||||
public static final BlockLookup<MountedFluidStorageType<?>> FLUID_LOOKUP = MountedStorageTypeRegistryImpl.FLUID_LOOKUP;
|
||||
|
||||
/**
|
||||
* Utility for use with Registrate builders. Creates a builder transformer
|
||||
* that will register the given MountedItemStorageType to a block when ready.
|
||||
*/
|
||||
public static <B extends Block, P> NonNullUnaryOperator<BlockBuilder<B, P>> mountedItemStorage(RegistryEntry<? extends MountedItemStorageType<?>, ?> type) {
|
||||
return builder -> builder.onRegisterAfter(Keys.MOUNTED_ITEM_STORAGE_TYPE, block -> ITEM_LOOKUP.register(block, type.get()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility for use with Registrate builders. Creates a builder transformer
|
||||
* that will register the given MountedFluidStorageType to a block when ready.
|
||||
*/
|
||||
public static <B extends Block, P> NonNullUnaryOperator<BlockBuilder<B, P>> mountedFluidStorage(RegistryEntry<? extends MountedFluidStorageType<?>, ?> type) {
|
||||
return builder -> builder.onRegisterAfter(Keys.MOUNTED_FLUID_STORAGE_TYPE, block -> FLUID_LOOKUP.register(block, type.get()));
|
||||
}
|
||||
}
|
|
@ -4,17 +4,22 @@ import org.jetbrains.annotations.Nullable;
|
|||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import com.simibubi.create.AllRegistries;
|
||||
import com.simibubi.create.api.registry.CreateBuiltInRegistries;
|
||||
import com.simibubi.create.api.registry.CreateRegistries;
|
||||
import com.simibubi.create.api.registry.SimpleRegistry;
|
||||
import com.tterrag.registrate.builders.BlockBuilder;
|
||||
import com.tterrag.registrate.util.entry.RegistryEntry;
|
||||
import com.tterrag.registrate.util.nullness.NonNullUnaryOperator;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public abstract class MountedFluidStorageType<T extends MountedFluidStorage> {
|
||||
public static final Codec<MountedFluidStorageType<?>> CODEC = Codec.lazyInitialized(
|
||||
AllRegistries.MOUNTED_FLUID_STORAGE_TYPE::byNameCodec
|
||||
);
|
||||
public static final Codec<MountedFluidStorageType<?>> CODEC = CreateBuiltInRegistries.MOUNTED_FLUID_STORAGE_TYPE.byNameCodec();
|
||||
public static final SimpleRegistry<Block, MountedFluidStorageType<?>> REGISTRY = SimpleRegistry.create();
|
||||
|
||||
public final MapCodec<? extends T> codec;
|
||||
|
||||
|
@ -24,4 +29,12 @@ public abstract class MountedFluidStorageType<T extends MountedFluidStorage> {
|
|||
|
||||
@Nullable
|
||||
public abstract T mount(Level level, BlockState state, BlockPos pos, @Nullable BlockEntity be);
|
||||
|
||||
/**
|
||||
* Utility for use with Registrate builders. Creates a builder transformer
|
||||
* that will register the given MountedFluidStorageType to a block when ready.
|
||||
*/
|
||||
public static <B extends Block, P> NonNullUnaryOperator<BlockBuilder<B, P>> mountedFluidStorage(RegistryEntry<MountedFluidStorageType<?>, ? extends MountedFluidStorageType<?>> type) {
|
||||
return builder -> builder.onRegisterAfter(CreateRegistries.MOUNTED_FLUID_STORAGE_TYPE, block -> REGISTRY.register(block, type.get()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
package com.simibubi.create.api.contraption.storage.fluid.registrate;
|
||||
|
||||
import com.simibubi.create.AllRegistries;
|
||||
import com.simibubi.create.api.contraption.storage.MountedStorageTypeRegistry;
|
||||
import com.simibubi.create.api.contraption.storage.fluid.MountedFluidStorageType;
|
||||
import com.tterrag.registrate.AbstractRegistrate;
|
||||
import com.tterrag.registrate.builders.AbstractBuilder;
|
||||
import com.tterrag.registrate.builders.BuilderCallback;
|
||||
import com.tterrag.registrate.util.nullness.NonnullType;
|
||||
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
public class MountedFluidStorageTypeBuilder<T extends MountedFluidStorageType<?>, P> extends AbstractBuilder<MountedFluidStorageType<?>, T, P, MountedFluidStorageTypeBuilder<T, P>> {
|
||||
private final T type;
|
||||
|
||||
public MountedFluidStorageTypeBuilder(AbstractRegistrate<?> owner, P parent, String name, BuilderCallback callback, T type) {
|
||||
super(owner, parent, name, callback, AllRegistries.Keys.MOUNTED_FLUID_STORAGE_TYPE);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public MountedFluidStorageTypeBuilder<T, P> registerTo(Block block) {
|
||||
MountedStorageTypeRegistry.FLUID_LOOKUP.register(block, this.type);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MountedFluidStorageTypeBuilder<T, P> registerTo(TagKey<Block> tag) {
|
||||
MountedStorageTypeRegistry.FLUID_LOOKUP.registerTag(tag, this.type);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonnullType
|
||||
protected T createEntry() {
|
||||
return this.type;
|
||||
}
|
||||
}
|
|
@ -8,10 +8,10 @@ import java.util.function.Predicate;
|
|||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.simibubi.create.api.behaviour.movement.MovementBehaviour;
|
||||
import com.simibubi.create.api.contraption.storage.item.menu.MountedStorageMenus;
|
||||
import com.simibubi.create.content.contraptions.Contraption;
|
||||
import com.simibubi.create.content.contraptions.MountedStorageManager;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||
import com.simibubi.create.foundation.utility.CreateLang;
|
||||
|
||||
|
|
|
@ -4,17 +4,28 @@ import org.jetbrains.annotations.Nullable;
|
|||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import com.simibubi.create.AllRegistries;
|
||||
import com.simibubi.create.api.registry.CreateBuiltInRegistries;
|
||||
import com.simibubi.create.api.registry.CreateRegistries;
|
||||
import com.simibubi.create.api.registry.SimpleRegistry;
|
||||
import com.simibubi.create.impl.contraption.storage.MountedItemStorageFallbackProvider;
|
||||
import com.tterrag.registrate.builders.BlockBuilder;
|
||||
import com.tterrag.registrate.util.entry.RegistryEntry;
|
||||
import com.tterrag.registrate.util.nullness.NonNullUnaryOperator;
|
||||
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public abstract class MountedItemStorageType<T extends MountedItemStorage> {
|
||||
public static final Codec<MountedItemStorageType<?>> CODEC = Codec.lazyInitialized(
|
||||
AllRegistries.MOUNTED_ITEM_STORAGE_TYPE::byNameCodec
|
||||
);
|
||||
public static final Codec<MountedItemStorageType<?>> CODEC = CreateBuiltInRegistries.MOUNTED_ITEM_STORAGE_TYPE.byNameCodec();
|
||||
public static final SimpleRegistry<Block, MountedItemStorageType<?>> REGISTRY = Util.make(() -> {
|
||||
SimpleRegistry<Block, MountedItemStorageType<?>> registry = SimpleRegistry.create();
|
||||
registry.registerProvider(MountedItemStorageFallbackProvider.INSTANCE);
|
||||
return registry;
|
||||
});
|
||||
|
||||
public final MapCodec<? extends T> codec;
|
||||
|
||||
|
@ -24,4 +35,12 @@ public abstract class MountedItemStorageType<T extends MountedItemStorage> {
|
|||
|
||||
@Nullable
|
||||
public abstract T mount(Level level, BlockState state, BlockPos pos, @Nullable BlockEntity be);
|
||||
|
||||
/**
|
||||
* Utility for use with Registrate builders. Creates a builder transformer
|
||||
* that will register the given MountedItemStorageType to a block when ready.
|
||||
*/
|
||||
public static <B extends Block, P> NonNullUnaryOperator<BlockBuilder<B, P>> mountedItemStorage(RegistryEntry<MountedItemStorageType<?>, ? extends MountedItemStorageType<?>> type) {
|
||||
return builder -> builder.onRegisterAfter(CreateRegistries.MOUNTED_ITEM_STORAGE_TYPE, block -> REGISTRY.register(block, type.get()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
package com.simibubi.create.api.contraption.storage.item.registrate;
|
||||
|
||||
import com.simibubi.create.AllRegistries;
|
||||
import com.simibubi.create.api.contraption.storage.MountedStorageTypeRegistry;
|
||||
import com.simibubi.create.api.contraption.storage.item.MountedItemStorageType;
|
||||
import com.tterrag.registrate.AbstractRegistrate;
|
||||
import com.tterrag.registrate.builders.AbstractBuilder;
|
||||
import com.tterrag.registrate.builders.BuilderCallback;
|
||||
import com.tterrag.registrate.util.nullness.NonnullType;
|
||||
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
public class MountedItemStorageTypeBuilder<T extends MountedItemStorageType<?>, P> extends AbstractBuilder<MountedItemStorageType<?>, T, P, MountedItemStorageTypeBuilder<T, P>> {
|
||||
private final T type;
|
||||
|
||||
public MountedItemStorageTypeBuilder(AbstractRegistrate<?> owner, P parent, String name, BuilderCallback callback, T type) {
|
||||
super(owner, parent, name, callback, AllRegistries.Keys.MOUNTED_ITEM_STORAGE_TYPE);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public MountedItemStorageTypeBuilder<T, P> registerTo(Block block) {
|
||||
MountedStorageTypeRegistry.ITEM_LOOKUP.register(block, this.type);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MountedItemStorageTypeBuilder<T, P> registerTo(TagKey<Block> tag) {
|
||||
MountedStorageTypeRegistry.ITEM_LOOKUP.registerTag(tag, this.type);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonnullType
|
||||
protected T createEntry() {
|
||||
return this.type;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package com.simibubi.create.api.contraption.train;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.api.registry.SimpleRegistry;
|
||||
import com.simibubi.create.content.trains.track.AllPortalTracks;
|
||||
|
||||
import net.createmod.catnip.math.BlockFace;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Portal;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
/**
|
||||
* A provider for portal track connections.
|
||||
* Takes a track inbound through a portal and finds the exit location for the outbound track.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface PortalTrackProvider {
|
||||
SimpleRegistry<Block, PortalTrackProvider> REGISTRY = SimpleRegistry.create();
|
||||
|
||||
/**
|
||||
* Find the exit location for a track going through a portal.
|
||||
* @param level the level of the inbound track
|
||||
* @param face the face of the inbound track
|
||||
*/
|
||||
Exit findExit(ServerLevel level, BlockFace face);
|
||||
|
||||
/**
|
||||
* Checks if a given {@link BlockState} represents a supported portal block.
|
||||
* @param state The block state to check.
|
||||
* @return {@code true} if the block state represents a supported portal; {@code false} otherwise.
|
||||
*/
|
||||
static boolean isSupportedPortal(BlockState state) {
|
||||
return REGISTRY.get(state) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the corresponding outbound track on the other side of a portal.
|
||||
* @param level The current {@link ServerLevel}.
|
||||
* @param inboundTrack The inbound track {@link BlockFace}.
|
||||
* @return the found outbound track, or null if one wasn't found.
|
||||
*/
|
||||
@Nullable
|
||||
static Exit getOtherSide(ServerLevel level, BlockFace inboundTrack) {
|
||||
BlockPos portalPos = inboundTrack.getConnectedPos();
|
||||
BlockState portalState = level.getBlockState(portalPos);
|
||||
PortalTrackProvider provider = REGISTRY.get(portalState);
|
||||
return provider == null ? null : provider.findExit(level, inboundTrack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find an exit location by using an {@link Portal} instance.
|
||||
* @param level The level of the inbound track
|
||||
* @param face The face of the inbound track
|
||||
* @param firstDimension The first dimension (typically the Overworld)
|
||||
* @param secondDimension The second dimension (e.g., Nether, Aether)
|
||||
* @param portal The portal
|
||||
* @return A found exit, or null if one wasn't found
|
||||
*/
|
||||
static Exit fromPortal(ServerLevel level, BlockFace face, ResourceKey<Level> firstDimension,
|
||||
ResourceKey<Level> secondDimension, Portal portal) {
|
||||
return AllPortalTracks.fromPortal(level, face, firstDimension, secondDimension, portal);
|
||||
}
|
||||
|
||||
record Exit(ServerLevel level, BlockFace face) {
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
package com.simibubi.create.api.contraption.train;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.simibubi.create.AllInteractionBehaviours;
|
||||
import com.simibubi.create.content.processing.burner.BlockBasedTrainConductorInteractionBehaviour;
|
||||
import com.simibubi.create.impl.contraption.train.TrainConductorHandlerImpl;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
|
||||
/**
|
||||
* All required methods to make your block a train conductor similar to the blaze burner
|
||||
*/
|
||||
public interface TrainConductorHandler {
|
||||
boolean isValidConductor(BlockState state);
|
||||
|
||||
private static void registerHandler(TrainConductorHandler handler) {
|
||||
TrainConductorHandlerImpl.CONDUCTOR_HANDLERS.add(handler);
|
||||
}
|
||||
|
||||
static void registerConductor(ResourceLocation blockRl, Predicate<BlockState> isValidConductor, UpdateScheduleCallback updateScheduleCallback) {
|
||||
AllInteractionBehaviours.registerBehaviour(blockRl, new BlockBasedTrainConductorInteractionBehaviour(isValidConductor, updateScheduleCallback));
|
||||
registerHandler(isValidConductor::test);
|
||||
}
|
||||
|
||||
interface UpdateScheduleCallback {
|
||||
UpdateScheduleCallback EMPTY = (hasSchedule, blockState, blockStateSetter) -> {};
|
||||
|
||||
void update(boolean hasSchedule, BlockState currentBlockState, Consumer<BlockState> blockStateSetter);
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
package com.simibubi.create.api.contraption.transformable;
|
||||
|
||||
import com.simibubi.create.impl.contraption.transformable.ContraptionTransformableRegistryImpl;
|
||||
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
|
||||
/**
|
||||
* Registry for registering new contraption transformations
|
||||
* to properly place blocks when disassembled after being part of a contraption
|
||||
*/
|
||||
public class ContraptionTransformableRegistry {
|
||||
/**
|
||||
* Register a new transform for a provided block
|
||||
*
|
||||
* @param block The block you want to register a new {@link TransformableBlock} for
|
||||
* @param transformableBlock The transform that should be applied whenever this block is being placed from
|
||||
* contraption disassembly
|
||||
*/
|
||||
public static void registerForBlock(Block block, TransformableBlock transformableBlock) {
|
||||
ContraptionTransformableRegistryImpl.registerForBlock(block, transformableBlock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new transform for a provided block entity type
|
||||
*
|
||||
* @param blockEntityType The blockEntityType you want to register a new {@link TransformableBlockEntity} for
|
||||
* @param transformableBlockEntity The transform that should be applied whenever this block entity type is
|
||||
* being placed from contraption disassembly
|
||||
*/
|
||||
public static void registerForBlockEntity(BlockEntityType<?> blockEntityType, TransformableBlockEntity transformableBlockEntity) {
|
||||
ContraptionTransformableRegistryImpl.registerForBlockEntity(blockEntityType, transformableBlockEntity);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.simibubi.create.api.contraption.transformable;
|
||||
|
||||
import com.simibubi.create.api.registry.SimpleRegistry;
|
||||
import com.simibubi.create.content.contraptions.StructureTransform;
|
||||
|
||||
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.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
/**
|
||||
* Registry for custom transformations to apply to blocks after they've been moved by a contraption.
|
||||
* These interfaces are alternatives to the {@link TransformableBlock} and {@link TransformableBlockEntity} interfaces.
|
||||
*/
|
||||
public class MovedBlockTransformerRegistries {
|
||||
public static final SimpleRegistry<Block, BlockTransformer> BLOCK_TRANSFORMERS = SimpleRegistry.create();
|
||||
public static final SimpleRegistry<BlockEntityType<?>, BlockEntityTransformer> BLOCK_ENTITY_TRANSFORMERS = SimpleRegistry.create();
|
||||
|
||||
@FunctionalInterface
|
||||
public interface BlockTransformer {
|
||||
BlockState transform(BlockState state, StructureTransform transform);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface BlockEntityTransformer {
|
||||
void transform(BlockEntity be, StructureTransform transform);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.simibubi.create.api.effect;
|
||||
|
||||
import com.simibubi.create.api.registry.SimpleRegistry;
|
||||
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
|
||||
import net.neoforged.neoforge.fluids.FluidStack;
|
||||
|
||||
/**
|
||||
* Interface for custom behavior for fluids spilling out of open pipes. Examples:
|
||||
* <ul>
|
||||
* <li>Potions: applying potion effects</li>
|
||||
* <li>Milk: clearing effects</li>
|
||||
* <li>Water: extinguishing fire</li>
|
||||
* </ul>
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface OpenPipeEffectHandler {
|
||||
SimpleRegistry<Fluid, OpenPipeEffectHandler> REGISTRY = SimpleRegistry.create();
|
||||
|
||||
/**
|
||||
* @param area the area to apply effects in
|
||||
* @param fluid the fluid in the pipe. Do not modify, it will do nothing
|
||||
*/
|
||||
void apply(Level level, AABB area, FluidStack fluid);
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
package com.simibubi.create.api.lookup;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.impl.lookup.BlockLookupImpl;
|
||||
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
/**
|
||||
* Lookup for objects provided by blocks. Values can either be registered directly
|
||||
* or found lazily through providers. Providers are only queried once per block.
|
||||
* If they return a value, that value is cached. If they don't, that block is recorded
|
||||
* as not having a corresponding value.
|
||||
* <p>
|
||||
* Provided values are reset on resource reloads and will be re-queried and re-cached the
|
||||
* next time a block is queried.
|
||||
* <p>
|
||||
* All providers are expected to be registered synchronously during game init.
|
||||
* Adding new ones late is not supported.
|
||||
*/
|
||||
@ApiStatus.NonExtendable
|
||||
public interface BlockLookup<T> {
|
||||
@Nullable
|
||||
T find(Block block);
|
||||
|
||||
/**
|
||||
* Shortcut to avoid calling getBlock() on a BlockState.
|
||||
*/
|
||||
@Nullable
|
||||
T find(BlockState state);
|
||||
|
||||
/**
|
||||
* Register a value to one block.
|
||||
*/
|
||||
void register(Block block, T value);
|
||||
|
||||
/**
|
||||
* Register a value to all entries of a tag.
|
||||
*/
|
||||
void registerTag(TagKey<Block> tag, T value);
|
||||
|
||||
/**
|
||||
* Register a new provider that will be queried.
|
||||
* Providers are queried in reverse-registration order.
|
||||
*/
|
||||
void registerProvider(Provider<T> provider);
|
||||
|
||||
static <T> BlockLookup<T> create() {
|
||||
return new BlockLookupImpl<>();
|
||||
}
|
||||
|
||||
static <T> BlockLookup<T> create(Provider<T> initialProvider) {
|
||||
BlockLookup<T> lookup = new BlockLookupImpl<>();
|
||||
lookup.registerProvider(initialProvider);
|
||||
return lookup;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface Provider<T> {
|
||||
@Nullable
|
||||
T get(Block block);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
package com.simibubi.create.api.registry;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashSet;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import com.simibubi.create.api.behaviour.display.DisplaySource;
|
||||
import com.simibubi.create.api.behaviour.display.DisplayTarget;
|
||||
import com.simibubi.create.api.contraption.ContraptionType;
|
||||
import com.simibubi.create.api.contraption.storage.fluid.MountedFluidStorageType;
|
||||
import com.simibubi.create.api.contraption.storage.item.MountedItemStorageType;
|
||||
import com.simibubi.create.content.kinetics.fan.processing.FanProcessingType;
|
||||
import com.simibubi.create.content.kinetics.mechanicalArm.ArmInteractionPointType;
|
||||
import com.simibubi.create.content.logistics.item.filter.attribute.ItemAttributeType;
|
||||
import com.simibubi.create.content.logistics.packagePort.PackagePortTargetType;
|
||||
|
||||
import net.minecraft.core.MappedRegistry;
|
||||
import net.minecraft.core.RegistrationInfo;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.WritableRegistry;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.fml.common.EventBusSubscriber.Bus;
|
||||
import net.neoforged.neoforge.registries.NewRegistryEvent;
|
||||
|
||||
/**
|
||||
* Static registries added by Create.
|
||||
*
|
||||
* @see CreateRegistries
|
||||
*/
|
||||
@EventBusSubscriber(bus = Bus.MOD)
|
||||
public class CreateBuiltInRegistries {
|
||||
private static final WritableRegistry<WritableRegistry<?>> ROOT_REGISTRY = getRootRegistry();
|
||||
|
||||
public static final Set<Registry<?>> REGISTRIES = new HashSet<>();
|
||||
|
||||
public static final Registry<ArmInteractionPointType> ARM_INTERACTION_POINT_TYPE = simple(CreateRegistries.ARM_INTERACTION_POINT_TYPE);
|
||||
public static final Registry<FanProcessingType> FAN_PROCESSING_TYPE = simple(CreateRegistries.FAN_PROCESSING_TYPE);
|
||||
public static final Registry<ItemAttributeType> ITEM_ATTRIBUTE_TYPE = simple(CreateRegistries.ITEM_ATTRIBUTE_TYPE);
|
||||
public static final Registry<DisplaySource> DISPLAY_SOURCE = simple(CreateRegistries.DISPLAY_SOURCE);
|
||||
public static final Registry<DisplayTarget> DISPLAY_TARGET = simple(CreateRegistries.DISPLAY_TARGET);
|
||||
public static final Registry<MountedItemStorageType<?>> MOUNTED_ITEM_STORAGE_TYPE = simple(CreateRegistries.MOUNTED_ITEM_STORAGE_TYPE);
|
||||
public static final Registry<MountedFluidStorageType<?>> MOUNTED_FLUID_STORAGE_TYPE = simple(CreateRegistries.MOUNTED_FLUID_STORAGE_TYPE);
|
||||
public static final Registry<ContraptionType> CONTRAPTION_TYPE = withIntrusiveHolders(CreateRegistries.CONTRAPTION_TYPE);
|
||||
public static final Registry<PackagePortTargetType> PACKAGE_PORT_TARGET_TYPE = simple(CreateRegistries.PACKAGE_PORT_TARGET_TYPE);
|
||||
|
||||
private static <T> Registry<T> simple(ResourceKey<Registry<T>> key) {
|
||||
return register(key, new MappedRegistry<>(key, Lifecycle.stable(), false));
|
||||
}
|
||||
|
||||
private static <T> Registry<T> withIntrusiveHolders(ResourceKey<Registry<T>> key) {
|
||||
return register(key, new MappedRegistry<>(key, Lifecycle.stable(), true));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> Registry<T> register(ResourceKey<Registry<T>> key, WritableRegistry<T> registry) {
|
||||
ROOT_REGISTRY.register(
|
||||
(ResourceKey<WritableRegistry<?>>) (Object) key, registry, new RegistrationInfo(Optional.empty(), Lifecycle.stable())
|
||||
);
|
||||
REGISTRIES.add(registry);
|
||||
return registry;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static WritableRegistry<WritableRegistry<?>> getRootRegistry() {
|
||||
// an accessor can't be used here because BuiltInRegistries is loaded too early during datagen.
|
||||
try {
|
||||
Field field = BuiltInRegistries.class.getDeclaredField("WRITABLE_REGISTRY");
|
||||
field.setAccessible(true);
|
||||
return (WritableRegistry<WritableRegistry<?>>) field.get(null);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
throw new RuntimeException("Create: Failed to get root registry", e);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Remove
|
||||
@ApiStatus.Internal
|
||||
public static void init() {
|
||||
// make sure the class is loaded.
|
||||
// this method is called at the tail of BuiltInRegistries, injected by a coremod. See it for details.
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onNewRegistryEvent(NewRegistryEvent event) {
|
||||
for (Registry<?> registry : REGISTRIES)
|
||||
event.register(registry);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.simibubi.create.api.registry;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.api.behaviour.display.DisplaySource;
|
||||
import com.simibubi.create.api.behaviour.display.DisplayTarget;
|
||||
import com.simibubi.create.api.contraption.ContraptionType;
|
||||
import com.simibubi.create.api.contraption.storage.fluid.MountedFluidStorageType;
|
||||
import com.simibubi.create.api.contraption.storage.item.MountedItemStorageType;
|
||||
import com.simibubi.create.content.kinetics.fan.processing.FanProcessingType;
|
||||
import com.simibubi.create.content.kinetics.mechanicalArm.ArmInteractionPointType;
|
||||
import com.simibubi.create.content.logistics.item.filter.attribute.ItemAttributeType;
|
||||
import com.simibubi.create.content.logistics.packagePort.PackagePortTargetType;
|
||||
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
|
||||
/**
|
||||
* Keys for registries added by Create.
|
||||
* @see CreateBuiltInRegistries
|
||||
*/
|
||||
public class CreateRegistries {
|
||||
public static final ResourceKey<Registry<ArmInteractionPointType>> ARM_INTERACTION_POINT_TYPE = key("arm_interaction_point_type");
|
||||
public static final ResourceKey<Registry<FanProcessingType>> FAN_PROCESSING_TYPE = key("fan_processing_type");
|
||||
public static final ResourceKey<Registry<ItemAttributeType>> ITEM_ATTRIBUTE_TYPE = key("item_attribute_type");
|
||||
public static final ResourceKey<Registry<DisplaySource>> DISPLAY_SOURCE = key("display_source");
|
||||
public static final ResourceKey<Registry<DisplayTarget>> DISPLAY_TARGET = key("display_target");
|
||||
public static final ResourceKey<Registry<MountedItemStorageType<?>>> MOUNTED_ITEM_STORAGE_TYPE = key("mounted_item_storage_type");
|
||||
public static final ResourceKey<Registry<MountedFluidStorageType<?>>> MOUNTED_FLUID_STORAGE_TYPE = key("mounted_fluid_storage_type");
|
||||
public static final ResourceKey<Registry<ContraptionType>> CONTRAPTION_TYPE = key("contraption_type");
|
||||
public static final ResourceKey<Registry<PackagePortTargetType>> PACKAGE_PORT_TARGET_TYPE = key("package_port_target_type");
|
||||
|
||||
private static <T> ResourceKey<Registry<T>> key(String name) {
|
||||
return ResourceKey.createRegistryKey(Create.asResource(name));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
package com.simibubi.create.api.registry;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.impl.registry.SimpleRegistryImpl;
|
||||
import com.simibubi.create.impl.registry.TagProviderImpl;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.StateHolder;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
|
||||
/**
|
||||
* A simple registry mapping between objects with identity semantics.
|
||||
* Provides simple registration functionality, as well as lazy providers.
|
||||
* This class is thread-safe, and may be safely used during parallel mod init.
|
||||
*/
|
||||
@ApiStatus.NonExtendable
|
||||
public interface SimpleRegistry<K, V> {
|
||||
/**
|
||||
* Register an association between a key and a value.
|
||||
* Direct registrations here always take priority over providers.
|
||||
* @throws IllegalArgumentException if the object already has an associated value
|
||||
*/
|
||||
void register(K object, V value);
|
||||
|
||||
/**
|
||||
* Add a new provider to this registry. For information on providers, see {@link Provider}.
|
||||
* @throws IllegalArgumentException if the provider has already been registered to this registry
|
||||
*/
|
||||
void registerProvider(Provider<K, V> provider);
|
||||
|
||||
/**
|
||||
* Invalidate the cached values provided by all providers, so they get re-computed on the next query.
|
||||
* This should be called by providers when something changes that would affect their results, such as
|
||||
* a resource reload in the case of providers based on tags.
|
||||
*/
|
||||
void invalidate();
|
||||
|
||||
/**
|
||||
* Query the value associated with the given object. May be null if no association is present.
|
||||
*/
|
||||
@Nullable
|
||||
V get(K object);
|
||||
|
||||
/**
|
||||
* Shortcut for {@link #get(Object)} that accepts a StateHolder, such as BlockState or FluidState.
|
||||
*/
|
||||
@Nullable
|
||||
V get(StateHolder<K, ?> state);
|
||||
|
||||
static <K, V> SimpleRegistry<K, V> create() {
|
||||
return SimpleRegistryImpl.single();
|
||||
}
|
||||
|
||||
/**
|
||||
* A provider can provide values to the registry in a lazy fashion. When a key does not have an
|
||||
* associated value, all providers will be queried in reverse-registration order (newest first).
|
||||
* <p>
|
||||
* The values returned by providers are cached so that repeated queries always return the same value.
|
||||
* To invalidate the cache of a registry, call {@link SimpleRegistry#invalidate()}.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
interface Provider<K, V> {
|
||||
@Nullable
|
||||
V get(K object);
|
||||
|
||||
/**
|
||||
* Called by the SimpleRegistry this provider is registered to after it's registered.
|
||||
* This is useful for behavior that should only happen if a provider is actually registered,
|
||||
* such as registering event listeners.
|
||||
*/
|
||||
default void onRegister(Runnable invalidate) {
|
||||
}
|
||||
|
||||
// factory methods for common Providers
|
||||
|
||||
/**
|
||||
* Create a provider that will return the same value for all entries in a tag.
|
||||
* The Provider will invalidate itself when tags are reloaded.
|
||||
*/
|
||||
static <K, V> Provider<K, V> forTag(TagKey<K> tag, Function<K, Holder<K>> holderGetter, V value) {
|
||||
return new TagProviderImpl<>(tag, holderGetter, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for {@link #forTag} when the registry's type is Block.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
static <V> Provider<Block, V> forBlockTag(TagKey<Block> tag, V value) {
|
||||
return new TagProviderImpl<>(tag, Block::builtInRegistryHolder, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for {@link #forTag} when the registry's type is BlockEntityType.
|
||||
*/
|
||||
static <V> Provider<BlockEntityType<?>, V> forBlockEntityTag(TagKey<BlockEntityType<?>> tag, V value) {
|
||||
return new TagProviderImpl<>(tag, TagProviderImpl::getBeHolder, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for {@link #forTag} when the registry's type is Item.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
static <V> Provider<Item, V> forItemTag(TagKey<Item> tag, V value) {
|
||||
return new TagProviderImpl<>(tag, Item::builtInRegistryHolder, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for {@link #forTag} when the registry's type is EntityType.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
static <V> Provider<EntityType<?>, V> forEntityTag(TagKey<EntityType<?>> tag, V value) {
|
||||
return new TagProviderImpl<>(tag, EntityType::builtInRegistryHolder, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for {@link #forTag} when the registry's type is Fluid.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
static <V> Provider<Fluid, V> forFluidTag(TagKey<Fluid> tag, V value) {
|
||||
return new TagProviderImpl<>(tag, Fluid::builtInRegistryHolder, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An extension of SimpleRegistry that handles multiple registrations per object.
|
||||
* {@link #register(Object, Object)} Will set a whole list of registrations - use {@link #add(Object, Object)} to add one.
|
||||
* Here, all Providers are always queried, and all of their results are returned. Their provided values are also
|
||||
* provided on top of explicit registrations - they do not take priority.
|
||||
*/
|
||||
interface Multi<K, V> extends SimpleRegistry<K, List<V>> {
|
||||
void add(K object, V value);
|
||||
|
||||
/**
|
||||
* Shortcut that wraps a single-value provider into one that provides a List.
|
||||
*/
|
||||
void addProvider(Provider<K, V> provider);
|
||||
|
||||
/**
|
||||
* Never returns null, will return an empty list if no registrations are present
|
||||
*/
|
||||
@Override
|
||||
@NotNull
|
||||
List<V> get(K object);
|
||||
|
||||
/**
|
||||
* Never returns null, will return an empty list if no registrations are present
|
||||
*/
|
||||
@Override
|
||||
@NotNull
|
||||
List<V> get(StateHolder<K, ?> state);
|
||||
|
||||
static <K, V> Multi<K, V> create() {
|
||||
return SimpleRegistryImpl.multi();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
package com.simibubi.create.api.registry.registrate;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.api.registry.SimpleRegistry;
|
||||
import com.simibubi.create.api.registry.SimpleRegistry.Provider;
|
||||
import com.simibubi.create.impl.registry.TagProviderImpl;
|
||||
import com.tterrag.registrate.AbstractRegistrate;
|
||||
import com.tterrag.registrate.builders.AbstractBuilder;
|
||||
import com.tterrag.registrate.builders.BuilderCallback;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
|
||||
public class SimpleBuilder<R, T extends R, P> extends AbstractBuilder<R, T, P, SimpleBuilder<R, T, P>> {
|
||||
private final T value;
|
||||
|
||||
private SimpleRegistryAccess<Block, R> byBlock;
|
||||
private SimpleRegistryAccess<BlockEntityType<?>, R> byBlockEntity;
|
||||
private SimpleRegistryAccess<EntityType<?>, R> byEntity;
|
||||
private SimpleRegistryAccess<Fluid, R> byFluid;
|
||||
|
||||
public SimpleBuilder(AbstractRegistrate<?> owner, P parent, String name, BuilderCallback callback, ResourceKey<Registry<R>> registryKey, T value) {
|
||||
super(owner, parent, name, callback, registryKey);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected T createEntry() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
// for setup
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public SimpleBuilder<R, T, P> byBlock(SimpleRegistry<Block, R> registry) {
|
||||
this.byBlock = SimpleRegistryAccess.of(registry, Block::builtInRegistryHolder);
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public SimpleBuilder<R, T, P> byBlock(SimpleRegistry.Multi<Block, R> registry) {
|
||||
this.byBlock = SimpleRegistryAccess.of(registry, Block::builtInRegistryHolder);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleBuilder<R, T, P> byBlockEntity(SimpleRegistry<BlockEntityType<?>, R> registry) {
|
||||
this.byBlockEntity = SimpleRegistryAccess.of(registry, TagProviderImpl::getBeHolder);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleBuilder<R, T, P> byBlockEntity(SimpleRegistry.Multi<BlockEntityType<?>, R> registry) {
|
||||
this.byBlockEntity = SimpleRegistryAccess.of(registry, TagProviderImpl::getBeHolder);
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public SimpleBuilder<R, T, P> byEntity(SimpleRegistry<EntityType<?>, R> registry) {
|
||||
this.byEntity = SimpleRegistryAccess.of(registry, EntityType::builtInRegistryHolder);
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public SimpleBuilder<R, T, P> byEntity(SimpleRegistry.Multi<EntityType<?>, R> registry) {
|
||||
this.byEntity = SimpleRegistryAccess.of(registry, EntityType::builtInRegistryHolder);
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public SimpleBuilder<R, T, P> byFluid(SimpleRegistry<Fluid, R> registry) {
|
||||
this.byFluid = SimpleRegistryAccess.of(registry, Fluid::builtInRegistryHolder);
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public SimpleBuilder<R, T, P> byFluid(SimpleRegistry.Multi<Fluid, R> registry) {
|
||||
this.byFluid = SimpleRegistryAccess.of(registry, Fluid::builtInRegistryHolder);
|
||||
return this;
|
||||
}
|
||||
|
||||
// association methods
|
||||
|
||||
public SimpleBuilder<R, T, P> associate(Block block) {
|
||||
assertPresent(this.byBlock, "Block");
|
||||
this.byBlock.adder.accept(block, this.value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleBuilder<R, T, P> associateBlockTag(TagKey<Block> tag) {
|
||||
assertPresent(this.byBlock, "Block");
|
||||
this.byBlock.tagAdder.accept(tag, this.value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleBuilder<R, T, P> associate(BlockEntityType<?> type) {
|
||||
assertPresent(this.byBlockEntity, "BlockEntityType");
|
||||
this.byBlockEntity.adder.accept(type, this.value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleBuilder<R, T, P> associateBeTag(TagKey<BlockEntityType<?>> tag) {
|
||||
assertPresent(this.byBlockEntity, "BlockEntityType");
|
||||
this.byBlockEntity.tagAdder.accept(tag, this.value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleBuilder<R, T, P> associate(EntityType<?> type) {
|
||||
assertPresent(this.byEntity, "EntityType");
|
||||
this.byEntity.adder.accept(type, this.value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleBuilder<R, T, P> associateEntityTag(TagKey<EntityType<?>> tag) {
|
||||
assertPresent(this.byEntity, "EntityType");
|
||||
this.byEntity.tagAdder.accept(tag, this.value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleBuilder<R, T, P> associate(Fluid fluid) {
|
||||
assertPresent(this.byFluid, "Fluid");
|
||||
this.byFluid.adder.accept(fluid, this.value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleBuilder<R, T, P> associateFluidTag(TagKey<Fluid> tag) {
|
||||
assertPresent(this.byFluid, "Fluid");
|
||||
this.byFluid.tagAdder.accept(tag, this.value);
|
||||
return this;
|
||||
}
|
||||
|
||||
private static void assertPresent(@Nullable Object object, String type) {
|
||||
if (object == null) {
|
||||
throw new IllegalStateException("This type does not support " + type + " associations");
|
||||
}
|
||||
}
|
||||
|
||||
protected record SimpleRegistryAccess<K, V>(BiConsumer<K, V> adder, BiConsumer<TagKey<K>, V> tagAdder) {
|
||||
public static <K, V> SimpleRegistryAccess<K, V> of(SimpleRegistry<K, V> registry, Function<K, Holder<K>> holderGetter) {
|
||||
return new SimpleRegistryAccess<>(
|
||||
registry::register,
|
||||
(tag, value) -> registry.registerProvider(Provider.forTag(tag, holderGetter, value))
|
||||
);
|
||||
}
|
||||
|
||||
public static <K, V> SimpleRegistryAccess<K, V> of(SimpleRegistry.Multi<K, V> registry, Function<K, Holder<K>> holderGetter) {
|
||||
return new SimpleRegistryAccess<>(
|
||||
registry::add,
|
||||
(tag, value) -> registry.addProvider(Provider.forTag(tag, holderGetter, value))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.simibubi.create.api.schematic.nbt;
|
||||
|
||||
import com.simibubi.create.api.registry.SimpleRegistry;
|
||||
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
|
||||
/**
|
||||
* Registry for safe NBT writers, used for filtering unsafe BlockEntity data out of schematics.
|
||||
* <p>
|
||||
* This is used to exclude specific tags that would result in exploits, ex. signs that execute commands when clicked.
|
||||
* <p>
|
||||
* This is provided as an alternative to {@link PartialSafeNBT}.
|
||||
*/
|
||||
public class SafeNbtWriterRegistry {
|
||||
public static final SimpleRegistry<BlockEntityType<?>, SafeNbtWriter> REGISTRY = SimpleRegistry.create();
|
||||
|
||||
@FunctionalInterface
|
||||
public interface SafeNbtWriter {
|
||||
/**
|
||||
* Write filtered, safe NBT to the given tag. This is always called on the logical server.
|
||||
* @param tag the NBT tag to write to
|
||||
*/
|
||||
void writeSafe(BlockEntity be, CompoundTag tag, HolderLookup.Provider registries);
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
package com.simibubi.create.api.schematic.nbt;
|
||||
|
||||
import com.simibubi.create.impl.schematic.nbt.SchematicSafeNBTRegistryImpl;
|
||||
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
|
||||
/**
|
||||
* Registry for modifying the data of BlockEntities when being placed with the schematic system.
|
||||
* </br>
|
||||
* Mostly used to exclude specific tags that would result in exploits from being written.
|
||||
*/
|
||||
public class SchematicSafeNBTRegistry {
|
||||
/**
|
||||
* Register a new partial safe nbt provider for a specific blockEntityType
|
||||
*
|
||||
* @param blockEntityType The block entity type you would like to register this for
|
||||
* @param safeNBT The custom PartialSafeNBT provider you would like to register for this blockEntityType,
|
||||
* your {@link ContextProvidingPartialSafeNBT#writeSafe(BlockEntity, CompoundTag, HolderLookup.Provider)} method will be
|
||||
* called on the passed {@link ContextProvidingPartialSafeNBT}
|
||||
* when the block entities data is being prepared for placement.
|
||||
*/
|
||||
public static void register(BlockEntityType<? extends BlockEntity> blockEntityType, ContextProvidingPartialSafeNBT safeNBT) {
|
||||
SchematicSafeNBTRegistryImpl.register(blockEntityType, safeNBT);
|
||||
}
|
||||
|
||||
// --- Interface that provides the context that would be available if you were to implement IPartialSafeNBT instead ---
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ContextProvidingPartialSafeNBT {
|
||||
/**
|
||||
* This will always be called from the logical server
|
||||
*/
|
||||
void writeSafe(BlockEntity blockEntity, CompoundTag tag, HolderLookup.Provider registries);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package com.simibubi.create.api.schematic.requirement;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.api.registry.SimpleRegistry;
|
||||
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
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.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
/**
|
||||
* Registries for custom schematic requirements for blocks, block entities, and entities. These requirements determine
|
||||
* the items that are needed for placement into the world through schematics.
|
||||
* <p>
|
||||
* This is provided as an alternative to the following interfaces:
|
||||
* <ul>
|
||||
* <li>{@link SpecialBlockItemRequirement}</li>
|
||||
* <li>{@link SpecialBlockEntityItemRequirement}</li>
|
||||
* <li>{@link SpecialEntityItemRequirement}</li>
|
||||
* </ul>
|
||||
*/
|
||||
public class SchematicRequirementRegistries {
|
||||
public static final SimpleRegistry<Block, BlockRequirement> BLOCKS = SimpleRegistry.create();
|
||||
public static final SimpleRegistry<BlockEntityType<?>, BlockEntityRequirement> BLOCK_ENTITIES = SimpleRegistry.create();
|
||||
public static final SimpleRegistry<EntityType<?>, EntityRequirement> ENTITIES = SimpleRegistry.create();
|
||||
|
||||
@FunctionalInterface
|
||||
public interface BlockRequirement {
|
||||
ItemRequirement getRequiredItems(BlockState state, @Nullable BlockEntity blockEntity);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface BlockEntityRequirement {
|
||||
ItemRequirement getRequiredItems(BlockEntity blockEntity, BlockState state);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface EntityRequirement {
|
||||
ItemRequirement getRequiredItems(Entity entity);
|
||||
}
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
package com.simibubi.create.api.schematic.requirement;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
|
||||
import com.simibubi.create.impl.schematic.requirement.SchematicRequirementsRegistryImpl;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
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.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
/**
|
||||
* Registry for schematic requirements for blocks, block entities, and entities.
|
||||
*/
|
||||
public class SchematicRequirementsRegistry {
|
||||
/**
|
||||
* Register a new special requirement for a specified block
|
||||
*
|
||||
* @param block The block you want to register a {@link ContextProvidingBlockRequirement} for
|
||||
* @param requirement The requirement you would like to add to this block,
|
||||
* the {@link ContextProvidingBlockRequirement#getRequiredItems(BlockState, BlockEntity)}
|
||||
* method will be called on the {@link ContextProvidingBlockRequirement} you have provided,
|
||||
* and you will be able to insert requirements based off the context that is given
|
||||
*/
|
||||
public static void registerForBlock(Block block, ContextProvidingBlockRequirement requirement) {
|
||||
SchematicRequirementsRegistryImpl.registerForBlock(block, requirement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new special requirement for a specified block
|
||||
*
|
||||
* @param block The id of the block you want to register a {@link ContextProvidingBlockRequirement} for
|
||||
* @param requirement The requirement you would like to add to this block,
|
||||
* the {@link ContextProvidingBlockRequirement#getRequiredItems(BlockState, BlockEntity)}
|
||||
* method will be called on the {@link ContextProvidingBlockRequirement} you have provided,
|
||||
* and you will be able to insert requirements based off the context that is given
|
||||
*/
|
||||
public static void registerForBlock(ResourceLocation block, ContextProvidingBlockRequirement requirement) {
|
||||
SchematicRequirementsRegistryImpl.registerForBlock(block, requirement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new special requirement for a specified block entity type
|
||||
*
|
||||
* @param blockEntityType The blockEntityType you want to register a {@link ContextProvidingBlockEntityRequirement} for
|
||||
* @param requirement The requirement you would like to add to this block entity type,
|
||||
* the {@link ContextProvidingBlockEntityRequirement#getRequiredItems(BlockEntity)}
|
||||
* method will be called on the
|
||||
* {@link ContextProvidingBlockEntityRequirement} you have provided,
|
||||
* and you will be able to insert requirements based off the context that is given
|
||||
*/
|
||||
public static void registerForBlockEntity(BlockEntityType<BlockEntity> blockEntityType, ContextProvidingBlockEntityRequirement requirement) {
|
||||
SchematicRequirementsRegistryImpl.registerForBlockEntity(blockEntityType, requirement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new special requirement for a specified block entity type
|
||||
*
|
||||
* @param blockEntityType The id of the blockEntityType you want to register a {@link ContextProvidingBlockEntityRequirement} for
|
||||
* @param requirement The requirement you would like to add to this block entity type,
|
||||
* the {@link ContextProvidingBlockEntityRequirement#getRequiredItems(BlockEntity)}
|
||||
* method will be called on the
|
||||
* {@link ContextProvidingBlockEntityRequirement} you have provided,
|
||||
* and you will be able to insert requirements based off the context that is given
|
||||
*/
|
||||
public static void registerForBlockEntity(ResourceLocation blockEntityType, ContextProvidingBlockEntityRequirement requirement) {
|
||||
SchematicRequirementsRegistryImpl.registerForBlockEntity(blockEntityType, requirement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new special requirement for a specified entity type
|
||||
*
|
||||
* @param entityType The entityType you want to register a {@link ContextProvidingEntityRequirement} for
|
||||
* @param requirement The requirement you would like to add to this entity type,
|
||||
* the {@link ContextProvidingEntityRequirement#getRequiredItems(Entity)}
|
||||
* method will be called on the {@link ContextProvidingEntityRequirement} you have provided,
|
||||
* and you will be able to insert requirements based off the context that is given
|
||||
*/
|
||||
public static void registerForEntity(EntityType<Entity> entityType, ContextProvidingEntityRequirement requirement) {
|
||||
SchematicRequirementsRegistryImpl.registerForEntity(entityType, requirement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new special requirement for a specified entity type
|
||||
*
|
||||
* @param entityType The id of the entityType you want to register a {@link ContextProvidingEntityRequirement} for
|
||||
* @param requirement The requirement you would like to add to this entity type,
|
||||
* the {@link ContextProvidingEntityRequirement#getRequiredItems(Entity)}
|
||||
* method will be called on the {@link ContextProvidingEntityRequirement} you have provided,
|
||||
* and you will be able to insert requirements based off the context that is given
|
||||
*/
|
||||
public static void registerForEntity(ResourceLocation entityType, ContextProvidingEntityRequirement requirement) {
|
||||
SchematicRequirementsRegistryImpl.registerForEntity(entityType, requirement);
|
||||
}
|
||||
|
||||
// --- Interfaces that provide the context that would be accessible if you implemented the ISpecial* interfaces ---
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ContextProvidingBlockRequirement {
|
||||
ItemRequirement getRequiredItems(BlockState state, @Nullable BlockEntity blockEntity);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ContextProvidingBlockEntityRequirement {
|
||||
ItemRequirement getRequiredItems(BlockEntity blockEntity);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ContextProvidingEntityRequirement {
|
||||
ItemRequirement getRequiredItems(Entity entity);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,32 +1,25 @@
|
|||
package com.simibubi.create.compat.tconstruct;
|
||||
|
||||
import com.simibubi.create.api.behaviour.BlockSpoutingBehaviour;
|
||||
import com.simibubi.create.compat.Mods;
|
||||
import com.simibubi.create.api.behaviour.spouting.BlockSpoutingBehaviour;
|
||||
import com.simibubi.create.content.fluids.spout.SpoutBlockEntity;
|
||||
import com.simibubi.create.foundation.fluid.FluidHelper;
|
||||
import com.simibubi.create.infrastructure.config.AllConfigs;
|
||||
|
||||
import net.createmod.catnip.registry.RegisteredObjectsHelper;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
import net.neoforged.neoforge.capabilities.Capabilities;
|
||||
import net.neoforged.neoforge.fluids.FluidStack;
|
||||
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
|
||||
import net.neoforged.neoforge.fluids.capability.IFluidHandler.FluidAction;
|
||||
|
||||
public class SpoutCasting extends BlockSpoutingBehaviour {
|
||||
|
||||
private static final boolean TICON_PRESENT = Mods.TCONSTRUCT.isLoaded();
|
||||
|
||||
ResourceLocation TABLE = ResourceLocation.fromNamespaceAndPath("tconstruct", "table");
|
||||
ResourceLocation BASIN = ResourceLocation.fromNamespaceAndPath("tconstruct", "basin");
|
||||
public enum SpoutCasting implements BlockSpoutingBehaviour {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public int fillBlock(Level level, BlockPos pos, SpoutBlockEntity spout, FluidStack availableFluid,
|
||||
boolean simulate) {
|
||||
public int fillBlock(Level level, BlockPos pos, SpoutBlockEntity spout, FluidStack availableFluid, boolean simulate) {
|
||||
if (!enabled())
|
||||
return 0;
|
||||
|
||||
|
@ -40,9 +33,6 @@ public class SpoutCasting extends BlockSpoutingBehaviour {
|
|||
if (handler.getTanks() != 1)
|
||||
return 0;
|
||||
|
||||
ResourceLocation registryName = RegisteredObjectsHelper.getKeyOrThrow(blockEntity.getType());
|
||||
if (!registryName.equals(TABLE) && !registryName.equals(BASIN))
|
||||
return 0;
|
||||
if (!handler.isFluidValid(0, availableFluid))
|
||||
return 0;
|
||||
|
||||
|
@ -61,9 +51,6 @@ public class SpoutCasting extends BlockSpoutingBehaviour {
|
|||
}
|
||||
|
||||
private boolean enabled() {
|
||||
if (!TICON_PRESENT)
|
||||
return false;
|
||||
return AllConfigs.server().recipes.allowCastingBySpout.get();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,13 +16,12 @@ import org.jetbrains.annotations.NotNull;
|
|||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.AllMovementBehaviours;
|
||||
import com.simibubi.create.AllSoundEvents;
|
||||
import com.simibubi.create.api.behaviour.movement.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.actors.psi.PortableStorageInterfaceMovement;
|
||||
import com.simibubi.create.content.contraptions.actors.seat.SeatBlock;
|
||||
import com.simibubi.create.content.contraptions.actors.seat.SeatEntity;
|
||||
import com.simibubi.create.content.contraptions.actors.trainControls.ControlsStopControllingPacket;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||
import com.simibubi.create.content.contraptions.data.ContraptionSyncLimiting;
|
||||
import com.simibubi.create.content.contraptions.elevator.ElevatorContraption;
|
||||
|
@ -444,7 +443,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
|||
for (MutablePair<StructureBlockInfo, MovementContext> pair : contraption.getActors()) {
|
||||
MovementContext context = pair.right;
|
||||
StructureBlockInfo blockInfo = pair.left;
|
||||
MovementBehaviour actor = AllMovementBehaviours.getBehaviour(blockInfo.state());
|
||||
MovementBehaviour actor = MovementBehaviour.REGISTRY.get(blockInfo.state());
|
||||
|
||||
if (actor == null)
|
||||
continue;
|
||||
|
@ -507,7 +506,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
|||
for (MutablePair<StructureBlockInfo, MovementContext> pair : contraption.getActors()) {
|
||||
MovementContext context = pair.right;
|
||||
StructureBlockInfo blockInfo = pair.left;
|
||||
MovementBehaviour actor = AllMovementBehaviours.getBehaviour(blockInfo.state());
|
||||
MovementBehaviour actor = MovementBehaviour.REGISTRY.get(blockInfo.state());
|
||||
if (actor instanceof PortableStorageInterfaceMovement && isActorActive(context, actor))
|
||||
if (context.position != null)
|
||||
actor.visitNewPosition(context, BlockPos.containing(context.position));
|
||||
|
|
|
@ -29,8 +29,11 @@ import com.google.common.collect.ArrayListMultimap;
|
|||
import com.google.common.collect.Multimap;
|
||||
import com.simibubi.create.AllBlockEntityTypes;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllInteractionBehaviours;
|
||||
import com.simibubi.create.AllMovementBehaviours;
|
||||
import com.simibubi.create.AllTags.AllContraptionTypeTags;
|
||||
import com.simibubi.create.api.behaviour.interaction.MovingInteractionBehaviour;
|
||||
import com.simibubi.create.api.behaviour.movement.MovementBehaviour;
|
||||
import com.simibubi.create.api.contraption.BlockMovementChecks;
|
||||
import com.simibubi.create.api.contraption.ContraptionType;
|
||||
import com.simibubi.create.content.contraptions.actors.contraptionControls.ContraptionControlsMovement;
|
||||
import com.simibubi.create.content.contraptions.actors.harvester.HarvesterMovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.actors.seat.SeatBlock;
|
||||
|
@ -40,9 +43,7 @@ import com.simibubi.create.content.contraptions.bearing.MechanicalBearingBlock;
|
|||
import com.simibubi.create.content.contraptions.bearing.StabilizedContraption;
|
||||
import com.simibubi.create.content.contraptions.bearing.WindmillBearingBlock;
|
||||
import com.simibubi.create.content.contraptions.bearing.WindmillBearingBlockEntity;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovingInteractionBehaviour;
|
||||
import com.simibubi.create.content.contraptions.chassis.AbstractChassisBlock;
|
||||
import com.simibubi.create.content.contraptions.chassis.ChassisBlockEntity;
|
||||
import com.simibubi.create.content.contraptions.chassis.StickerBlock;
|
||||
|
@ -92,6 +93,7 @@ import net.minecraft.nbt.ListTag;
|
|||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.protocol.game.DebugPackets;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.ai.village.poi.PoiTypes;
|
||||
|
@ -617,7 +619,7 @@ public abstract class Contraption {
|
|||
blockstate = blockstate.setValue(RedstoneContactBlock.POWERED, true);
|
||||
if (AllBlocks.POWERED_SHAFT.has(blockstate))
|
||||
blockstate = BlockHelper.copyProperties(blockstate, AllBlocks.SHAFT.getDefaultState());
|
||||
if (blockstate.getBlock() instanceof ControlsBlock && getType() == ContraptionType.CARRIAGE)
|
||||
if (blockstate.getBlock() instanceof ControlsBlock && AllContraptionTypeTags.OPENS_CONTROLS.matches(this.getType()))
|
||||
blockstate = blockstate.setValue(ControlsBlock.OPEN, true);
|
||||
if (blockstate.hasProperty(SlidingDoorBlock.VISIBLE))
|
||||
blockstate = blockstate.setValue(SlidingDoorBlock.VISIBLE, false);
|
||||
|
@ -662,10 +664,10 @@ public abstract class Contraption {
|
|||
|
||||
captureMultiblock(localPos, structureBlockInfo, be);
|
||||
|
||||
if (AllMovementBehaviours.getBehaviour(state) != null)
|
||||
if (MovementBehaviour.REGISTRY.get(state) != null)
|
||||
actors.add(MutablePair.of(structureBlockInfo, null));
|
||||
|
||||
MovingInteractionBehaviour interactionBehaviour = AllInteractionBehaviours.getBehaviour(state);
|
||||
MovingInteractionBehaviour interactionBehaviour = MovingInteractionBehaviour.REGISTRY.get(state);
|
||||
if (interactionBehaviour != null)
|
||||
interactors.put(localPos, interactionBehaviour);
|
||||
|
||||
|
@ -791,7 +793,7 @@ public abstract class Contraption {
|
|||
StructureBlockInfo structureBlockInfo = getBlocks().get(pos);
|
||||
if (structureBlockInfo == null)
|
||||
return;
|
||||
MovingInteractionBehaviour behaviour = AllInteractionBehaviours.getBehaviour(structureBlockInfo.state());
|
||||
MovingInteractionBehaviour behaviour = MovingInteractionBehaviour.REGISTRY.get(structureBlockInfo.state());
|
||||
if (behaviour != null)
|
||||
interactors.put(pos, behaviour);
|
||||
});
|
||||
|
@ -806,7 +808,8 @@ public abstract class Contraption {
|
|||
|
||||
public CompoundTag writeNBT(HolderLookup.Provider registries, boolean spawnPacket) {
|
||||
CompoundTag nbt = new CompoundTag();
|
||||
nbt.putString("Type", getType().id);
|
||||
ResourceLocation typeId = this.getType().holder.key().location();
|
||||
nbt.putString("Type", typeId.toString());
|
||||
|
||||
CompoundTag blocksNBT = writeBlocksCompound(spawnPacket);
|
||||
|
||||
|
@ -829,7 +832,7 @@ public abstract class Contraption {
|
|||
|
||||
ListTag actorsNBT = new ListTag();
|
||||
for (MutablePair<StructureBlockInfo, MovementContext> actor : getActors()) {
|
||||
MovementBehaviour behaviour = AllMovementBehaviours.getBehaviour(actor.left.state());
|
||||
MovementBehaviour behaviour = MovementBehaviour.REGISTRY.get(actor.left.state());
|
||||
if (behaviour == null)
|
||||
continue;
|
||||
CompoundTag compound = new CompoundTag();
|
||||
|
@ -995,7 +998,7 @@ public abstract class Contraption {
|
|||
presentBlockEntities.put(info.pos(), be);
|
||||
modelData.put(info.pos(), be.getModelData());
|
||||
|
||||
MovementBehaviour movementBehaviour = AllMovementBehaviours.getBehaviour(info.state());
|
||||
MovementBehaviour movementBehaviour = MovementBehaviour.REGISTRY.get(info.state());
|
||||
if (movementBehaviour == null || !movementBehaviour.disableBlockEntityRendering()) {
|
||||
renderedBlockEntities.add(be);
|
||||
}
|
||||
|
@ -1321,7 +1324,7 @@ public abstract class Contraption {
|
|||
|
||||
for (MutablePair<StructureBlockInfo, MovementContext> pair : actors) {
|
||||
MovementContext context = new MovementContext(world, pair.left, this);
|
||||
MovementBehaviour behaviour = AllMovementBehaviours.getBehaviour(pair.left.state());
|
||||
MovementBehaviour behaviour = MovementBehaviour.REGISTRY.get(pair.left.state());
|
||||
if (behaviour != null)
|
||||
behaviour.startMoving(context);
|
||||
pair.setRight(context);
|
||||
|
@ -1351,7 +1354,7 @@ public abstract class Contraption {
|
|||
|
||||
public void setActorsActive(ItemStack referenceStack, boolean enable) {
|
||||
for (MutablePair<StructureBlockInfo, MovementContext> pair : actors) {
|
||||
MovementBehaviour behaviour = AllMovementBehaviours.getBehaviour(pair.left.state());
|
||||
MovementBehaviour behaviour = MovementBehaviour.REGISTRY.get(pair.left.state());
|
||||
if (behaviour == null)
|
||||
continue;
|
||||
ItemStack behaviourStack = behaviour.canBeDisabledVia(pair.right);
|
||||
|
@ -1381,7 +1384,7 @@ public abstract class Contraption {
|
|||
|
||||
public void forEachActor(Level world, BiConsumer<MovementBehaviour, MovementContext> callBack) {
|
||||
for (MutablePair<StructureBlockInfo, MovementContext> pair : actors) {
|
||||
MovementBehaviour behaviour = AllMovementBehaviours.getBehaviour(pair.getLeft().state());
|
||||
MovementBehaviour behaviour = MovementBehaviour.REGISTRY.get(pair.getLeft().state());
|
||||
if (behaviour == null)
|
||||
continue;
|
||||
callBack.accept(behaviour, pair.getRight());
|
||||
|
@ -1560,7 +1563,7 @@ public abstract class Contraption {
|
|||
|
||||
public boolean containsBlockBreakers() {
|
||||
for (MutablePair<StructureBlockInfo, MovementContext> pair : actors) {
|
||||
MovementBehaviour behaviour = AllMovementBehaviours.getBehaviour(pair.getLeft().state());
|
||||
MovementBehaviour behaviour = MovementBehaviour.REGISTRY.get(pair.getLeft().state());
|
||||
if (behaviour instanceof BlockBreakingMovementBehaviour || behaviour instanceof HarvesterMovementBehaviour)
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -9,18 +9,18 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import com.simibubi.create.api.behaviour.movement.MovementBehaviour;
|
||||
|
||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||
import org.apache.commons.lang3.mutable.MutableFloat;
|
||||
import org.apache.commons.lang3.mutable.MutableObject;
|
||||
import org.apache.commons.lang3.tuple.MutablePair;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllMovementBehaviours;
|
||||
import com.simibubi.create.api.behaviour.interaction.MovingInteractionBehaviour;
|
||||
import com.simibubi.create.content.contraptions.AbstractContraptionEntity.ContraptionRotationState;
|
||||
import com.simibubi.create.content.contraptions.ContraptionColliderLockPacket.ContraptionColliderLockPacketRequest;
|
||||
import com.simibubi.create.content.contraptions.actors.harvester.HarvesterMovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovingInteractionBehaviour;
|
||||
import com.simibubi.create.content.contraptions.sync.ClientMotionPacket;
|
||||
import com.simibubi.create.content.kinetics.base.BlockBreakingMovementBehaviour;
|
||||
import com.simibubi.create.content.trains.entity.CarriageContraptionEntity;
|
||||
|
@ -763,7 +763,7 @@ public class ContraptionCollider {
|
|||
if (collidedState.getBlock() instanceof CocoaBlock)
|
||||
continue;
|
||||
|
||||
MovementBehaviour movementBehaviour = AllMovementBehaviours.getBehaviour(blockInfo.state());
|
||||
MovementBehaviour movementBehaviour = MovementBehaviour.REGISTRY.get(blockInfo.state());
|
||||
if (movementBehaviour != null) {
|
||||
if (movementBehaviour instanceof BlockBreakingMovementBehaviour behaviour) {
|
||||
if (!behaviour.canBreak(world, colliderPos, collidedState) && !emptyCollider)
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
package com.simibubi.create.content.contraptions;
|
||||
|
||||
import com.simibubi.create.foundation.utility.AttachedRegistry;
|
||||
import com.simibubi.create.infrastructure.config.AllConfigs;
|
||||
|
||||
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.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
|
||||
import net.neoforged.neoforge.common.extensions.IBlockExtension;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public enum ContraptionMovementSetting {
|
||||
MOVABLE, NO_PICKUP, UNMOVABLE;
|
||||
|
||||
private static final AttachedRegistry<Block, Supplier<ContraptionMovementSetting>> SETTING_SUPPLIERS = new AttachedRegistry<>(BuiltInRegistries.BLOCK);
|
||||
|
||||
public static void register(ResourceLocation block, Supplier<ContraptionMovementSetting> settingSupplier) {
|
||||
SETTING_SUPPLIERS.register(block, settingSupplier);
|
||||
}
|
||||
|
||||
public static void register(Block block, Supplier<ContraptionMovementSetting> settingSupplier) {
|
||||
SETTING_SUPPLIERS.register(block, settingSupplier);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ContraptionMovementSetting get(Block block) {
|
||||
if (block instanceof IMovementSettingProvider provider)
|
||||
return provider.getContraptionMovementSetting();
|
||||
Supplier<ContraptionMovementSetting> supplier = SETTING_SUPPLIERS.get(block);
|
||||
if (supplier == null)
|
||||
return null;
|
||||
return supplier.get();
|
||||
}
|
||||
|
||||
public static boolean allAre(Collection<StructureTemplate.StructureBlockInfo> blocks, ContraptionMovementSetting are) {
|
||||
return blocks.stream().anyMatch(b -> get(b.state().getBlock()) == are);
|
||||
}
|
||||
|
||||
public static boolean isNoPickup(Collection<StructureTemplate.StructureBlockInfo> blocks) {
|
||||
return allAre(blocks, ContraptionMovementSetting.NO_PICKUP);
|
||||
}
|
||||
|
||||
public static void registerDefaults() {
|
||||
register(Blocks.SPAWNER, () -> AllConfigs.server().kinetics.spawnerMovement.get());
|
||||
register(Blocks.BUDDING_AMETHYST, () -> AllConfigs.server().kinetics.amethystMovement.get());
|
||||
register(Blocks.OBSIDIAN, () -> AllConfigs.server().kinetics.obsidianMovement.get());
|
||||
register(Blocks.CRYING_OBSIDIAN, () -> AllConfigs.server().kinetics.obsidianMovement.get());
|
||||
register(Blocks.RESPAWN_ANCHOR, () -> AllConfigs.server().kinetics.obsidianMovement.get());
|
||||
register(Blocks.REINFORCED_DEEPSLATE, () -> AllConfigs.server().kinetics.reinforcedDeepslateMovement.get());
|
||||
}
|
||||
|
||||
public interface IMovementSettingProvider extends IBlockExtension {
|
||||
ContraptionMovementSetting getContraptionMovementSetting();
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
package com.simibubi.create.content.contraptions;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.content.contraptions.bearing.BearingContraption;
|
||||
import com.simibubi.create.content.contraptions.bearing.ClockworkContraption;
|
||||
import com.simibubi.create.content.contraptions.bearing.StabilizedContraption;
|
||||
import com.simibubi.create.content.contraptions.elevator.ElevatorContraption;
|
||||
import com.simibubi.create.content.contraptions.gantry.GantryContraption;
|
||||
import com.simibubi.create.content.contraptions.mounted.MountedContraption;
|
||||
import com.simibubi.create.content.contraptions.piston.PistonContraption;
|
||||
import com.simibubi.create.content.contraptions.pulley.PulleyContraption;
|
||||
import com.simibubi.create.content.trains.entity.CarriageContraption;
|
||||
|
||||
public class ContraptionType {
|
||||
|
||||
public static final Map<String, ContraptionType> ENTRIES = new HashMap<>();
|
||||
public static final ContraptionType
|
||||
PISTON = register("piston", PistonContraption::new),
|
||||
BEARING = register("bearing", BearingContraption::new),
|
||||
PULLEY = register("pulley", PulleyContraption::new),
|
||||
CLOCKWORK = register("clockwork", ClockworkContraption::new),
|
||||
MOUNTED = register("mounted", MountedContraption::new),
|
||||
STABILIZED = register("stabilized", StabilizedContraption::new),
|
||||
GANTRY = register("gantry", GantryContraption::new),
|
||||
CARRIAGE = register("carriage", CarriageContraption::new),
|
||||
ELEVATOR = register("elevator", ElevatorContraption::new);
|
||||
|
||||
Supplier<? extends Contraption> factory;
|
||||
String id;
|
||||
|
||||
public static ContraptionType register(String id, Supplier<? extends Contraption> factory) {
|
||||
ContraptionType value = new ContraptionType(id, factory);
|
||||
ENTRIES.put(id, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
private ContraptionType(String id, Supplier<? extends Contraption> factory) {
|
||||
this.factory = factory;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static Contraption fromType(String type) {
|
||||
for (Entry<String, ContraptionType> allContraptionTypes : ENTRIES.entrySet())
|
||||
if (type.equals(allContraptionTypes.getKey()))
|
||||
return allContraptionTypes.getValue().factory.get();
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -2,8 +2,8 @@ package com.simibubi.create.content.contraptions;
|
|||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.simibubi.create.AllEntityTypes;
|
||||
import com.simibubi.create.api.behaviour.movement.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.bearing.BearingContraption;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||
|
||||
import dev.engine_room.flywheel.lib.transform.TransformStack;
|
||||
|
|
|
@ -17,7 +17,6 @@ import com.google.common.collect.ImmutableMap;
|
|||
import com.google.common.collect.Sets;
|
||||
import com.google.common.collect.Sets.SetView;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.api.contraption.storage.MountedStorageTypeRegistry;
|
||||
import com.simibubi.create.api.contraption.storage.SyncedMountedStorage;
|
||||
import com.simibubi.create.api.contraption.storage.fluid.MountedFluidStorage;
|
||||
import com.simibubi.create.api.contraption.storage.fluid.MountedFluidStorageType;
|
||||
|
@ -144,7 +143,7 @@ public class MountedStorageManager {
|
|||
}
|
||||
|
||||
public void addBlock(Level level, BlockState state, BlockPos globalPos, BlockPos localPos, @Nullable BlockEntity be) {
|
||||
MountedItemStorageType<?> itemType = MountedStorageTypeRegistry.ITEM_LOOKUP.find(state);
|
||||
MountedItemStorageType<?> itemType = MountedItemStorageType.REGISTRY.get(state.getBlock());
|
||||
if (itemType != null) {
|
||||
MountedItemStorage storage = itemType.mount(level, state, globalPos, be);
|
||||
if (storage != null) {
|
||||
|
@ -152,7 +151,7 @@ public class MountedStorageManager {
|
|||
}
|
||||
}
|
||||
|
||||
MountedFluidStorageType<?> fluidType = MountedStorageTypeRegistry.FLUID_LOOKUP.find(state);
|
||||
MountedFluidStorageType<?> fluidType = MountedFluidStorageType.REGISTRY.get(state.getBlock());
|
||||
if (fluidType != null) {
|
||||
MountedFluidStorage storage = fluidType.mount(level, state, globalPos, be);
|
||||
if (storage != null) {
|
||||
|
@ -167,7 +166,7 @@ public class MountedStorageManager {
|
|||
|
||||
MountedItemStorage itemStorage = this.getAllItemStorages().get(localPos);
|
||||
if (itemStorage != null) {
|
||||
MountedItemStorageType<?> expectedType = MountedStorageTypeRegistry.ITEM_LOOKUP.find(state);
|
||||
MountedItemStorageType<?> expectedType = MountedItemStorageType.REGISTRY.get(state.getBlock());
|
||||
if (itemStorage.type == expectedType) {
|
||||
itemStorage.unmount(level, state, globalPos, be);
|
||||
}
|
||||
|
@ -175,7 +174,7 @@ public class MountedStorageManager {
|
|||
|
||||
MountedFluidStorage fluidStorage = this.getFluids().storages.get(localPos);
|
||||
if (fluidStorage != null) {
|
||||
MountedFluidStorageType<?> expectedType = MountedStorageTypeRegistry.FLUID_LOOKUP.find(state);
|
||||
MountedFluidStorageType<?> expectedType = MountedFluidStorageType.REGISTRY.get(state.getBlock());
|
||||
if (fluidStorage.type == expectedType) {
|
||||
fluidStorage.unmount(level, state, globalPos, be);
|
||||
}
|
||||
|
|
|
@ -4,14 +4,13 @@ import static net.minecraft.world.level.block.state.properties.BlockStatePropert
|
|||
import static net.minecraft.world.level.block.state.properties.BlockStateProperties.FACING;
|
||||
import static net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.api.contraption.transformable.MovedBlockTransformerRegistries;
|
||||
import com.simibubi.create.api.contraption.transformable.MovedBlockTransformerRegistries.BlockEntityTransformer;
|
||||
import com.simibubi.create.api.contraption.transformable.MovedBlockTransformerRegistries.BlockTransformer;
|
||||
import com.simibubi.create.api.contraption.transformable.TransformableBlock;
|
||||
import com.simibubi.create.api.contraption.transformable.TransformableBlockEntity;
|
||||
import com.simibubi.create.impl.contraption.transformable.ContraptionTransformableRegistryImpl;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.createmod.catnip.codecs.stream.CatnipStreamCodecBuilders;
|
||||
import net.createmod.catnip.codecs.stream.CatnipStreamCodecs;
|
||||
import net.createmod.catnip.math.VecHelper;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -40,28 +39,25 @@ import net.minecraft.world.phys.Vec3;
|
|||
|
||||
public class StructureTransform {
|
||||
public static final StreamCodec<ByteBuf, StructureTransform> STREAM_CODEC = StreamCodec.composite(
|
||||
BlockPos.STREAM_CODEC, transform -> transform.offset,
|
||||
ByteBufCodecs.VAR_INT, transform -> transform.angle,
|
||||
CatnipStreamCodecBuilders.nullable(CatnipStreamCodecs.AXIS), transform -> transform.rotationAxis,
|
||||
CatnipStreamCodecBuilders.nullable(CatnipStreamCodecs.ROTATION), transform -> transform.rotation,
|
||||
CatnipStreamCodecBuilders.nullable(CatnipStreamCodecs.MIRROR), transform -> transform.mirror,
|
||||
BlockPos.STREAM_CODEC, i -> i.offset,
|
||||
ByteBufCodecs.INT, i -> i.angle,
|
||||
CatnipStreamCodecs.AXIS, i -> i.rotationAxis,
|
||||
CatnipStreamCodecs.ROTATION, i -> i.rotation,
|
||||
CatnipStreamCodecs.MIRROR, i -> i.mirror,
|
||||
StructureTransform::new
|
||||
);
|
||||
|
||||
// Assuming structures cannot be rotated around multiple axes at once
|
||||
public Axis rotationAxis;
|
||||
public BlockPos offset;
|
||||
public int angle;
|
||||
// Assuming structures cannot be rotated around multiple axes at once
|
||||
@Nullable
|
||||
public Axis rotationAxis;
|
||||
@Nullable
|
||||
public Rotation rotation;
|
||||
@Nullable
|
||||
public Mirror mirror;
|
||||
|
||||
private StructureTransform(BlockPos offset, int angle, @Nullable Axis axis, @Nullable Rotation rotation, @Nullable Mirror mirror) {
|
||||
private StructureTransform(BlockPos offset, int angle, Axis axis, Rotation rotation, Mirror mirror) {
|
||||
this.offset = offset;
|
||||
this.angle = angle;
|
||||
this.rotationAxis = axis;
|
||||
rotationAxis = axis;
|
||||
this.rotation = rotation;
|
||||
this.mirror = mirror;
|
||||
}
|
||||
|
@ -149,9 +145,9 @@ public class StructureTransform {
|
|||
}
|
||||
|
||||
public void apply(BlockEntity be) {
|
||||
TransformableBlockEntity transformableBlockEntity = ContraptionTransformableRegistryImpl.get(be.getType());
|
||||
if (transformableBlockEntity != null) {
|
||||
transformableBlockEntity.transform(be, this);
|
||||
BlockEntityTransformer transformer = MovedBlockTransformerRegistries.BLOCK_ENTITY_TRANSFORMERS.get(be.getType());
|
||||
if (transformer != null) {
|
||||
transformer.transform(be, this);
|
||||
} else if (be instanceof TransformableBlockEntity itbe) {
|
||||
itbe.transform(be, this);
|
||||
}
|
||||
|
@ -164,9 +160,9 @@ public class StructureTransform {
|
|||
*/
|
||||
public BlockState apply(BlockState state) {
|
||||
Block block = state.getBlock();
|
||||
TransformableBlock transformableBlock = ContraptionTransformableRegistryImpl.get(block);
|
||||
if (transformableBlock != null) {
|
||||
return transformableBlock.transform(state, this);
|
||||
BlockTransformer transformer = MovedBlockTransformerRegistries.BLOCK_TRANSFORMERS.get(block);
|
||||
if (transformer != null) {
|
||||
return transformer.transform(state, this);
|
||||
} else if (block instanceof TransformableBlock transformable) {
|
||||
return transformable.transform(state, this);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.simibubi.create.content.contraptions.actors.contraptionControls;
|
||||
|
||||
import com.simibubi.create.api.behaviour.movement.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.Contraption;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||
import com.simibubi.create.content.contraptions.elevator.ElevatorContraption;
|
||||
import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
package com.simibubi.create.content.contraptions.actors.contraptionControls;
|
||||
|
||||
import com.simibubi.create.AllMovementBehaviours;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.tuple.MutablePair;
|
||||
|
||||
import com.simibubi.create.AllSoundEvents;
|
||||
import com.simibubi.create.api.behaviour.interaction.MovingInteractionBehaviour;
|
||||
import com.simibubi.create.api.behaviour.movement.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.Contraption;
|
||||
import com.simibubi.create.content.contraptions.actors.contraptionControls.ContraptionControlsMovement.ElevatorFloorSelection;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovingInteractionBehaviour;
|
||||
import com.simibubi.create.content.contraptions.elevator.ElevatorContraption;
|
||||
import com.simibubi.create.content.contraptions.elevator.ElevatorTargetFloorPacket;
|
||||
import net.createmod.catnip.platform.CatnipServices;
|
||||
|
||||
|
||||
import net.createmod.catnip.platform.CatnipServices;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
|
@ -20,11 +25,6 @@ import net.minecraft.world.level.Level;
|
|||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import org.apache.commons.lang3.tuple.MutablePair;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class ContraptionControlsMovingInteraction extends MovingInteractionBehaviour {
|
||||
|
||||
@Override
|
||||
|
@ -70,7 +70,7 @@ public class ContraptionControlsMovingInteraction extends MovingInteractionBehav
|
|||
|
||||
if (invert) {
|
||||
for (MutablePair<StructureBlockInfo, MovementContext> pair : contraption.getActors()) {
|
||||
MovementBehaviour behaviour = AllMovementBehaviours.getBehaviour(pair.left.state());
|
||||
MovementBehaviour behaviour = MovementBehaviour.REGISTRY.get(pair.left.state());
|
||||
if (behaviour == null)
|
||||
continue;
|
||||
ItemStack behaviourStack = behaviour.canBeDisabledVia(pair.right);
|
||||
|
|
|
@ -6,8 +6,8 @@ import net.neoforged.neoforge.common.SpecialPlantable;
|
|||
|
||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||
|
||||
import com.simibubi.create.AllTags;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
|
||||
import com.simibubi.create.AllTags.AllBlockTags;
|
||||
import com.simibubi.create.api.behaviour.movement.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||
import com.simibubi.create.content.contraptions.render.ActorVisual;
|
||||
import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
|
||||
|
@ -172,7 +172,7 @@ public class HarvesterMovementBehaviour implements MovementBehaviour {
|
|||
if (block == Blocks.SWEET_BERRY_BUSH) {
|
||||
return state.setValue(BlockStateProperties.AGE_3, Integer.valueOf(1));
|
||||
}
|
||||
if (state.is(AllTags.AllBlockTags.SUGAR_CANE_VARIANTS.tag) || block instanceof GrowingPlantBlock) {
|
||||
if (AllBlockTags.SUGAR_CANE_VARIANTS.matches(block) || block instanceof GrowingPlantBlock) {
|
||||
if (state.getFluidState()
|
||||
.isEmpty())
|
||||
return Blocks.AIR.defaultBlockState();
|
||||
|
|
|
@ -4,7 +4,7 @@ import java.util.Optional;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
|
||||
import com.simibubi.create.api.behaviour.movement.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||
import com.simibubi.create.content.contraptions.render.ActorVisual;
|
||||
import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package com.simibubi.create.content.contraptions.actors.seat;
|
||||
|
||||
import com.simibubi.create.api.behaviour.interaction.MovingInteractionBehaviour;
|
||||
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.Contraption;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovingInteractionBehaviour;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
|
|
|
@ -3,8 +3,8 @@ package com.simibubi.create.content.contraptions.actors.seat;
|
|||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.simibubi.create.api.behaviour.movement.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||
|
||||
import net.createmod.catnip.math.VecHelper;
|
||||
|
|
|
@ -4,12 +4,13 @@ import java.util.UUID;
|
|||
|
||||
import com.google.common.base.Objects;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.api.behaviour.interaction.MovingInteractionBehaviour;
|
||||
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovingInteractionBehaviour;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
|
||||
public class ControlsInteractionBehaviour extends MovingInteractionBehaviour {
|
||||
|
|
|
@ -2,8 +2,8 @@ package com.simibubi.create.content.contraptions.actors.trainControls;
|
|||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.simibubi.create.api.behaviour.movement.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||
import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
|
||||
import com.simibubi.create.content.trains.entity.CarriageContraptionEntity;
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
package com.simibubi.create.content.contraptions.bearing;
|
||||
|
||||
import net.minecraft.core.HolderLookup;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllContraptionTypes;
|
||||
import com.simibubi.create.AllTags.AllBlockTags;
|
||||
import com.simibubi.create.api.contraption.ContraptionType;
|
||||
import com.simibubi.create.content.contraptions.AssemblyException;
|
||||
import com.simibubi.create.content.contraptions.Contraption;
|
||||
import com.simibubi.create.content.contraptions.ContraptionType;
|
||||
import com.simibubi.create.content.decoration.copycat.CopycatBlockEntity;
|
||||
import com.simibubi.create.infrastructure.config.AllConfigs;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
@ -50,7 +50,7 @@ public class BearingContraption extends Contraption {
|
|||
|
||||
@Override
|
||||
public ContraptionType getType() {
|
||||
return ContraptionType.BEARING;
|
||||
return AllContraptionTypes.BEARING.value();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -4,17 +4,17 @@ import java.util.HashSet;
|
|||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.core.HolderLookup;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.simibubi.create.AllContraptionTypes;
|
||||
import com.simibubi.create.api.contraption.ContraptionType;
|
||||
import com.simibubi.create.content.contraptions.AssemblyException;
|
||||
import com.simibubi.create.content.contraptions.Contraption;
|
||||
import com.simibubi.create.content.contraptions.ContraptionType;
|
||||
|
||||
import net.createmod.catnip.nbt.NBTHelper;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
|
@ -27,7 +27,7 @@ public class ClockworkContraption extends Contraption {
|
|||
|
||||
@Override
|
||||
public ContraptionType getType() {
|
||||
return ContraptionType.CLOCKWORK;
|
||||
return AllContraptionTypes.CLOCKWORK.value();
|
||||
}
|
||||
|
||||
private void ignoreBlocks(Set<BlockPos> blocks, BlockPos anchor) {
|
||||
|
|
|
@ -6,10 +6,10 @@ import org.joml.Quaternionf;
|
|||
|
||||
import com.mojang.math.Axis;
|
||||
import com.simibubi.create.AllPartialModels;
|
||||
import com.simibubi.create.api.behaviour.movement.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.ControlledContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.OrientedContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||
import com.simibubi.create.content.contraptions.render.ActorVisual;
|
||||
import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package com.simibubi.create.content.contraptions.bearing;
|
||||
|
||||
import com.simibubi.create.AllContraptionTypes;
|
||||
import com.simibubi.create.api.contraption.ContraptionType;
|
||||
import com.simibubi.create.content.contraptions.AssemblyException;
|
||||
import com.simibubi.create.content.contraptions.Contraption;
|
||||
import com.simibubi.create.content.contraptions.ContraptionType;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
|
@ -38,7 +39,7 @@ public class StabilizedContraption extends Contraption {
|
|||
|
||||
@Override
|
||||
public ContraptionType getType() {
|
||||
return ContraptionType.STABILIZED;
|
||||
return AllContraptionTypes.STABILIZED.value();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.content.contraptions.behaviour;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.api.behaviour.movement.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.Contraption;
|
||||
import com.simibubi.create.content.contraptions.elevator.ElevatorContraption;
|
||||
import com.simibubi.create.content.equipment.bell.AbstractBellBlock;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.simibubi.create.content.contraptions.behaviour;
|
||||
|
||||
import com.simibubi.create.api.behaviour.movement.MovementBehaviour;
|
||||
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.block.CampfireBlock;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.simibubi.create.content.contraptions.behaviour;
|
||||
|
||||
import com.simibubi.create.api.behaviour.interaction.MovingInteractionBehaviour;
|
||||
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.Contraption;
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@ import java.util.function.Predicate;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.api.behaviour.movement.MovementBehaviour;
|
||||
import com.simibubi.create.api.contraption.storage.item.MountedItemStorage;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||
import com.simibubi.create.foundation.item.ItemHelper;
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import java.util.function.Function;
|
|||
import com.google.common.collect.ImmutableList;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllKeys;
|
||||
import com.simibubi.create.content.contraptions.BlockMovementChecks;
|
||||
import com.simibubi.create.api.contraption.BlockMovementChecks;
|
||||
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.CenteredSideValueBoxTransform;
|
||||
|
|
|
@ -7,19 +7,20 @@ import org.apache.commons.lang3.tuple.Pair;
|
|||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllContraptionTypes;
|
||||
import com.simibubi.create.api.contraption.ContraptionType;
|
||||
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.AssemblyException;
|
||||
import com.simibubi.create.content.contraptions.ContraptionType;
|
||||
import com.simibubi.create.content.contraptions.actors.contraptionControls.ContraptionControlsMovement.ElevatorFloorSelection;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||
import com.simibubi.create.content.contraptions.elevator.ElevatorColumn.ColumnCoords;
|
||||
import com.simibubi.create.content.contraptions.pulley.PulleyContraption;
|
||||
import com.simibubi.create.content.redstone.contact.RedstoneContactBlock;
|
||||
import net.createmod.catnip.platform.CatnipServices;
|
||||
import com.simibubi.create.foundation.utility.CreateLang;
|
||||
|
||||
import net.createmod.catnip.data.Couple;
|
||||
import net.createmod.catnip.data.IntAttached;
|
||||
import net.createmod.catnip.platform.CatnipServices;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Direction.Axis;
|
||||
|
@ -170,7 +171,7 @@ public class ElevatorContraption extends PulleyContraption {
|
|||
|
||||
@Override
|
||||
public ContraptionType getType() {
|
||||
return ContraptionType.ELEVATOR;
|
||||
return AllContraptionTypes.ELEVATOR.value();
|
||||
}
|
||||
|
||||
public void setClientYTarget(int clientYTarget) {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package com.simibubi.create.content.contraptions.gantry;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllContraptionTypes;
|
||||
import com.simibubi.create.api.contraption.ContraptionType;
|
||||
import com.simibubi.create.content.contraptions.AssemblyException;
|
||||
import com.simibubi.create.content.contraptions.ContraptionType;
|
||||
import com.simibubi.create.content.contraptions.TranslatingContraption;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -50,7 +51,7 @@ public class GantryContraption extends TranslatingContraption {
|
|||
|
||||
@Override
|
||||
public ContraptionType getType() {
|
||||
return ContraptionType.GANTRY;
|
||||
return AllContraptionTypes.GANTRY.value();
|
||||
}
|
||||
|
||||
public Direction getFacing() {
|
||||
|
|
|
@ -12,8 +12,8 @@ import com.simibubi.create.AllBlocks;
|
|||
import com.simibubi.create.AllEntityTypes;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.AllSoundEvents;
|
||||
import com.simibubi.create.api.contraption.BlockMovementChecks;
|
||||
import com.simibubi.create.api.schematic.requirement.SpecialEntityItemRequirement;
|
||||
import com.simibubi.create.content.contraptions.BlockMovementChecks;
|
||||
import com.simibubi.create.content.contraptions.bearing.BearingBlock;
|
||||
import com.simibubi.create.content.contraptions.chassis.AbstractChassisBlock;
|
||||
import com.simibubi.create.content.kinetics.base.DirectionalKineticBlock;
|
||||
|
|
|
@ -4,7 +4,7 @@ import java.util.HashSet;
|
|||
import java.util.Set;
|
||||
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.content.contraptions.BlockMovementChecks;
|
||||
import com.simibubi.create.api.contraption.BlockMovementChecks;
|
||||
|
||||
import net.createmod.catnip.platform.CatnipServices;
|
||||
import net.createmod.catnip.data.Iterate;
|
||||
|
|
|
@ -5,7 +5,7 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.simibubi.create.content.contraptions.BlockMovementChecks;
|
||||
import com.simibubi.create.api.contraption.BlockMovementChecks;
|
||||
|
||||
import net.createmod.catnip.data.Iterate;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
|
|
@ -8,10 +8,10 @@ import org.apache.commons.lang3.tuple.MutablePair;
|
|||
|
||||
import com.simibubi.create.AllDataComponents;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.AllMovementBehaviours;
|
||||
import com.simibubi.create.api.behaviour.movement.MovementBehaviour;
|
||||
import com.simibubi.create.api.contraption.ContraptionMovementSetting;
|
||||
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.Contraption;
|
||||
import com.simibubi.create.content.contraptions.ContraptionMovementSetting;
|
||||
import com.simibubi.create.content.contraptions.OrientedContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.actors.psi.PortableStorageInterfaceMovement;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||
|
@ -245,7 +245,7 @@ public class MinecartContraptionItem extends Item {
|
|||
contraption.stop(event.getLevel());
|
||||
|
||||
for (MutablePair<StructureBlockInfo, MovementContext> pair : contraption.getActors())
|
||||
if (AllMovementBehaviours.getBehaviour(pair.left.state()) instanceof PortableStorageInterfaceMovement psim)
|
||||
if (MovementBehaviour.REGISTRY.get(pair.left.state()) instanceof PortableStorageInterfaceMovement psim)
|
||||
psim.reset(pair.right);
|
||||
|
||||
ItemStack generatedStack = create(type, oce);
|
||||
|
|
|
@ -4,14 +4,13 @@ import static com.simibubi.create.content.contraptions.mounted.CartAssemblerBloc
|
|||
|
||||
import java.util.Queue;
|
||||
|
||||
import net.minecraft.core.HolderLookup;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllContraptionTypes;
|
||||
import com.simibubi.create.api.contraption.ContraptionType;
|
||||
import com.simibubi.create.content.contraptions.AssemblyException;
|
||||
import com.simibubi.create.content.contraptions.Contraption;
|
||||
import com.simibubi.create.content.contraptions.ContraptionType;
|
||||
import com.simibubi.create.content.contraptions.mounted.CartAssemblerBlockEntity.CartMovementMode;
|
||||
|
||||
import net.createmod.catnip.data.Iterate;
|
||||
|
@ -20,6 +19,7 @@ import net.createmod.catnip.nbt.NBTHelper;
|
|||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Direction.Axis;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
|
@ -50,7 +50,7 @@ public class MountedContraption extends Contraption {
|
|||
|
||||
@Override
|
||||
public ContraptionType getType() {
|
||||
return ContraptionType.MOUNTED;
|
||||
return AllContraptionTypes.MOUNTED.value();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -12,14 +12,12 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.simibubi.create.AllContraptionTypes;
|
||||
import com.simibubi.create.api.contraption.BlockMovementChecks;
|
||||
import com.simibubi.create.api.contraption.ContraptionType;
|
||||
import com.simibubi.create.content.contraptions.AssemblyException;
|
||||
import com.simibubi.create.content.contraptions.BlockMovementChecks;
|
||||
import com.simibubi.create.content.contraptions.ContraptionType;
|
||||
import com.simibubi.create.content.contraptions.TranslatingContraption;
|
||||
import com.simibubi.create.content.contraptions.piston.MechanicalPistonBlock.PistonState;
|
||||
import com.simibubi.create.infrastructure.config.AllConfigs;
|
||||
|
@ -27,6 +25,7 @@ import com.simibubi.create.infrastructure.config.AllConfigs;
|
|||
import net.createmod.catnip.math.VecHelper;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
|
@ -38,6 +37,7 @@ import net.minecraft.world.level.block.state.properties.PistonType;
|
|||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo;
|
||||
import net.minecraft.world.level.material.PushReaction;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class PistonContraption extends TranslatingContraption {
|
||||
|
||||
|
@ -50,10 +50,11 @@ public class PistonContraption extends TranslatingContraption {
|
|||
|
||||
@Override
|
||||
public ContraptionType getType() {
|
||||
return ContraptionType.PISTON;
|
||||
return AllContraptionTypes.PISTON.value();
|
||||
}
|
||||
|
||||
public PistonContraption() {}
|
||||
public PistonContraption() {
|
||||
}
|
||||
|
||||
public PistonContraption(Direction direction, boolean retract) {
|
||||
orientation = direction;
|
||||
|
|
|
@ -7,9 +7,9 @@ import java.util.List;
|
|||
import javax.annotation.Nullable;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.api.contraption.BlockMovementChecks;
|
||||
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.AssemblyException;
|
||||
import com.simibubi.create.content.contraptions.BlockMovementChecks;
|
||||
import com.simibubi.create.content.contraptions.ContraptionCollider;
|
||||
import com.simibubi.create.content.contraptions.ControlledContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.piston.LinearActuatorBlockEntity;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
package com.simibubi.create.content.contraptions.pulley;
|
||||
|
||||
import com.simibubi.create.AllContraptionTypes;
|
||||
import com.simibubi.create.api.contraption.ContraptionType;
|
||||
import com.simibubi.create.content.contraptions.AssemblyException;
|
||||
import com.simibubi.create.content.contraptions.ContraptionType;
|
||||
import com.simibubi.create.content.contraptions.TranslatingContraption;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -15,7 +16,7 @@ public class PulleyContraption extends TranslatingContraption {
|
|||
|
||||
@Override
|
||||
public ContraptionType getType() {
|
||||
return ContraptionType.PULLEY;
|
||||
return AllContraptionTypes.PULLEY.value();
|
||||
}
|
||||
|
||||
public PulleyContraption() {}
|
||||
|
|
|
@ -4,10 +4,9 @@ import org.apache.commons.lang3.tuple.Pair;
|
|||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import com.simibubi.create.AllMovementBehaviours;
|
||||
import com.simibubi.create.api.behaviour.movement.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.Contraption;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||
import com.simibubi.create.foundation.render.BlockEntityRenderHelper;
|
||||
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
|
||||
|
@ -99,7 +98,7 @@ public class ContraptionEntityRenderer<C extends AbstractContraptionEntity> exte
|
|||
context.world = level;
|
||||
StructureTemplate.StructureBlockInfo blockInfo = actor.getLeft();
|
||||
|
||||
MovementBehaviour movementBehaviour = AllMovementBehaviours.getBehaviour(blockInfo.state());
|
||||
MovementBehaviour movementBehaviour = MovementBehaviour.REGISTRY.get(blockInfo.state());
|
||||
if (movementBehaviour != null) {
|
||||
if (c.isHiddenInPortal(blockInfo.pos()))
|
||||
continue;
|
||||
|
|
|
@ -6,11 +6,10 @@ import java.util.List;
|
|||
import org.apache.commons.lang3.tuple.MutablePair;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.simibubi.create.AllMovementBehaviours;
|
||||
import com.simibubi.create.api.behaviour.movement.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.Contraption;
|
||||
import com.simibubi.create.content.contraptions.Contraption.RenderedBlocks;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||
import com.simibubi.create.foundation.utility.worldWrappers.WrappedBlockAndTintGetter;
|
||||
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
|
||||
|
@ -167,7 +166,7 @@ public class ContraptionVisual<E extends AbstractContraptionEntity> extends Abst
|
|||
|
||||
StructureTemplate.StructureBlockInfo blockInfo = actor.getLeft();
|
||||
|
||||
MovementBehaviour movementBehaviour = AllMovementBehaviours.getBehaviour(blockInfo.state());
|
||||
MovementBehaviour movementBehaviour = MovementBehaviour.REGISTRY.get(blockInfo.state());
|
||||
if (movementBehaviour == null) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.simibubi.create.content.contraptions.render;
|
||||
|
||||
import com.simibubi.create.content.contraptions.ContraptionType;
|
||||
import com.simibubi.create.AllTags.AllContraptionTypeTags;
|
||||
import com.simibubi.create.content.contraptions.OrientedContraptionEntity;
|
||||
|
||||
import net.minecraft.client.renderer.culling.Frustum;
|
||||
|
@ -16,9 +16,9 @@ public class OrientedContraptionEntityRenderer extends ContraptionEntityRenderer
|
|||
double cameraZ) {
|
||||
if (!super.shouldRender(entity, frustum, cameraX, cameraY, cameraZ))
|
||||
return false;
|
||||
if (entity.getContraption()
|
||||
.getType() == ContraptionType.MOUNTED && entity.getVehicle() == null)
|
||||
if (entity.getVehicle() == null && AllContraptionTypeTags.REQUIRES_VEHICLE_FOR_RENDER.matches(entity.getContraption().getType()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@ package com.simibubi.create.content.decoration.slidingDoor;
|
|||
import java.lang.ref.WeakReference;
|
||||
import java.util.Map;
|
||||
|
||||
import com.simibubi.create.api.behaviour.movement.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.Contraption;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||
import com.simibubi.create.content.contraptions.elevator.ElevatorColumn;
|
||||
import com.simibubi.create.content.contraptions.elevator.ElevatorColumn.ColumnCoords;
|
||||
|
|
|
@ -2,14 +2,11 @@ package com.simibubi.create.content.fluids;
|
|||
|
||||
import static net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.AllFluids;
|
||||
import com.simibubi.create.api.effect.OpenPipeEffectHandler;
|
||||
import com.simibubi.create.content.fluids.pipes.VanillaFluidTargets;
|
||||
import com.simibubi.create.content.fluids.potion.PotionFluidHandler;
|
||||
import com.simibubi.create.foundation.ICapabilityProvider;
|
||||
import com.simibubi.create.foundation.advancement.AdvancementBehaviour;
|
||||
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
||||
|
@ -21,23 +18,11 @@ import net.createmod.catnip.math.BlockFace;
|
|||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.tags.FluidTags;
|
||||
import net.minecraft.world.effect.MobEffect;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.effect.MobEffects;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.alchemy.PotionContents;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.AbstractCandleBlock;
|
||||
import net.minecraft.world.level.block.CampfireBlock;
|
||||
import net.minecraft.world.level.block.LiquidBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
|
@ -45,24 +30,13 @@ import net.minecraft.world.level.material.FlowingFluid;
|
|||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.neoforged.neoforge.common.EffectCures;
|
||||
import net.neoforged.neoforge.common.Tags;
|
||||
|
||||
import net.neoforged.neoforge.fluids.FluidStack;
|
||||
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
|
||||
import net.neoforged.neoforge.fluids.capability.templates.FluidTank;
|
||||
|
||||
public class OpenEndedPipe extends FlowSource {
|
||||
|
||||
private static final List<IEffectHandler> EFFECT_HANDLERS = new ArrayList<>();
|
||||
|
||||
static {
|
||||
registerEffectHandler(new PotionEffectHandler());
|
||||
registerEffectHandler(new MilkEffectHandler());
|
||||
registerEffectHandler(new WaterEffectHandler());
|
||||
registerEffectHandler(new LavaEffectHandler());
|
||||
registerEffectHandler(new TeaEffectHandler());
|
||||
}
|
||||
|
||||
private Level world;
|
||||
private BlockPos pos;
|
||||
private AABB aoe;
|
||||
|
@ -71,9 +45,6 @@ public class OpenEndedPipe extends FlowSource {
|
|||
private BlockPos outputPos;
|
||||
private boolean wasPulling;
|
||||
|
||||
private FluidStack cachedFluid;
|
||||
private PotionContents cachedEffects;
|
||||
|
||||
private final ICapabilityProvider<IFluidHandler> fluidHandlerProvider = ICapabilityProvider.of(() -> fluidHandler);
|
||||
|
||||
public OpenEndedPipe(BlockFace face) {
|
||||
|
@ -86,10 +57,6 @@ public class OpenEndedPipe extends FlowSource {
|
|||
aoe = aoe.expandTowards(0, -1, 0);
|
||||
}
|
||||
|
||||
public static void registerEffectHandler(IEffectHandler handler) {
|
||||
EFFECT_HANDLERS.add(handler);
|
||||
}
|
||||
|
||||
public Level getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
@ -252,23 +219,6 @@ public class OpenEndedPipe extends FlowSource {
|
|||
return true;
|
||||
}
|
||||
|
||||
private boolean canApplyEffects(FluidStack fluid) {
|
||||
for (IEffectHandler handler : EFFECT_HANDLERS) {
|
||||
if (handler.canApplyEffects(this, fluid)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void applyEffects(FluidStack fluid) {
|
||||
for (IEffectHandler handler : EFFECT_HANDLERS) {
|
||||
if (handler.canApplyEffects(this, fluid)) {
|
||||
handler.applyEffects(this, fluid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class OpenEndFluidHandler extends FluidTank {
|
||||
|
||||
public OpenEndFluidHandler() {
|
||||
|
@ -294,14 +244,22 @@ public class OpenEndedPipe extends FlowSource {
|
|||
setFluid(FluidStack.EMPTY);
|
||||
if (wasPulling)
|
||||
wasPulling = false;
|
||||
if (canApplyEffects(resource) && !hasBlockState)
|
||||
|
||||
OpenPipeEffectHandler effectHandler = OpenPipeEffectHandler.REGISTRY.get(resource.getFluid());
|
||||
if (effectHandler != null && !hasBlockState)
|
||||
resource = FluidHelper.copyStackWithAmount(resource, 1);
|
||||
|
||||
int fill = super.fill(resource, action);
|
||||
if (action.simulate())
|
||||
return fill;
|
||||
if (!resource.isEmpty())
|
||||
applyEffects(resource);
|
||||
|
||||
if (effectHandler != null && !resource.isEmpty()) {
|
||||
// resource should be copied before giving it to the handler.
|
||||
// if hasBlockState is false, it was already copied above.
|
||||
FluidStack exposed = hasBlockState ? resource.copy() : resource;
|
||||
effectHandler.apply(world, aoe, exposed);
|
||||
}
|
||||
|
||||
if (getFluidAmount() == 1000 || !hasBlockState)
|
||||
if (provideFluidToSpace(containedFluidStack, false))
|
||||
setFluid(FluidStack.EMPTY);
|
||||
|
@ -359,132 +317,4 @@ public class OpenEndedPipe extends FlowSource {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
public interface IEffectHandler {
|
||||
boolean canApplyEffects(OpenEndedPipe pipe, FluidStack fluid);
|
||||
|
||||
void applyEffects(OpenEndedPipe pipe, FluidStack fluid);
|
||||
}
|
||||
|
||||
public static class PotionEffectHandler implements IEffectHandler {
|
||||
@Override
|
||||
public boolean canApplyEffects(OpenEndedPipe pipe, FluidStack fluid) {
|
||||
return fluid.getFluid()
|
||||
.isSame(AllFluids.POTION.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyEffects(OpenEndedPipe pipe, FluidStack fluid) {
|
||||
if (pipe.cachedFluid == null || pipe.cachedEffects == null || !FluidStack.isSameFluidSameComponents(fluid, pipe.cachedFluid)) {
|
||||
FluidStack copy = fluid.copy();
|
||||
copy.setAmount(250);
|
||||
ItemStack bottle = PotionFluidHandler.fillBottle(new ItemStack(Items.GLASS_BOTTLE), fluid);
|
||||
pipe.cachedEffects = bottle.get(DataComponents.POTION_CONTENTS);
|
||||
}
|
||||
|
||||
if (pipe.cachedEffects == null)
|
||||
return;
|
||||
|
||||
List<LivingEntity> entities = pipe.getWorld()
|
||||
.getEntitiesOfClass(LivingEntity.class, pipe.getAOE(), LivingEntity::isAffectedByPotions);
|
||||
for (LivingEntity entity : entities) {
|
||||
pipe.cachedEffects.forEachEffect(effectInstance -> {
|
||||
MobEffect effect = effectInstance.getEffect().value();
|
||||
if (effect.isInstantenous()) {
|
||||
effect.applyInstantenousEffect(null, null, entity, effectInstance.getAmplifier(), 0.5D);
|
||||
} else {
|
||||
entity.addEffect(new MobEffectInstance(effectInstance));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class MilkEffectHandler implements IEffectHandler {
|
||||
@Override
|
||||
public boolean canApplyEffects(OpenEndedPipe pipe, FluidStack fluid) {
|
||||
return FluidHelper.isTag(fluid, Tags.Fluids.MILK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyEffects(OpenEndedPipe pipe, FluidStack fluid) {
|
||||
Level world = pipe.getWorld();
|
||||
if (world.getGameTime() % 5 != 0)
|
||||
return;
|
||||
List<LivingEntity> entities =
|
||||
world.getEntitiesOfClass(LivingEntity.class, pipe.getAOE(), LivingEntity::isAffectedByPotions);
|
||||
for (LivingEntity entity : entities)
|
||||
entity.removeEffectsCuredBy(EffectCures.MILK);
|
||||
}
|
||||
}
|
||||
|
||||
public static class WaterEffectHandler implements IEffectHandler {
|
||||
@Override
|
||||
public boolean canApplyEffects(OpenEndedPipe pipe, FluidStack fluid) {
|
||||
return FluidHelper.isTag(fluid, FluidTags.WATER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyEffects(OpenEndedPipe pipe, FluidStack fluid) {
|
||||
Level world = pipe.getWorld();
|
||||
if (world.getGameTime() % 5 != 0)
|
||||
return;
|
||||
List<Entity> entities = world.getEntities((Entity) null, pipe.getAOE(), Entity::isOnFire);
|
||||
for (Entity entity : entities)
|
||||
entity.clearFire();
|
||||
BlockPos.betweenClosedStream(pipe.getAOE())
|
||||
.forEach(pos -> dowseFire(world, pos));
|
||||
}
|
||||
|
||||
// Adapted from ThrownPotion
|
||||
private static void dowseFire(Level level, BlockPos pos) {
|
||||
BlockState state = level.getBlockState(pos);
|
||||
if (state.is(BlockTags.FIRE)) {
|
||||
level.removeBlock(pos, false);
|
||||
} else if (AbstractCandleBlock.isLit(state)) {
|
||||
AbstractCandleBlock.extinguish(null, state, level, pos);
|
||||
} else if (CampfireBlock.isLitCampfire(state)) {
|
||||
level.levelEvent(null, 1009, pos, 0);
|
||||
CampfireBlock.dowse(null, level, pos, state);
|
||||
level.setBlockAndUpdate(pos, state.setValue(CampfireBlock.LIT, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class LavaEffectHandler implements IEffectHandler {
|
||||
@Override
|
||||
public boolean canApplyEffects(OpenEndedPipe pipe, FluidStack fluid) {
|
||||
return FluidHelper.isTag(fluid, FluidTags.LAVA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyEffects(OpenEndedPipe pipe, FluidStack fluid) {
|
||||
Level world = pipe.getWorld();
|
||||
if (world.getGameTime() % 5 != 0)
|
||||
return;
|
||||
List<Entity> entities = world.getEntities((Entity) null, pipe.getAOE(), entity -> !entity.fireImmune());
|
||||
for (Entity entity : entities)
|
||||
entity.igniteForSeconds(3);
|
||||
}
|
||||
}
|
||||
|
||||
public static class TeaEffectHandler implements IEffectHandler {
|
||||
@Override
|
||||
public boolean canApplyEffects(OpenEndedPipe pipe, FluidStack fluid) {
|
||||
return fluid.getFluid().isSame(AllFluids.TEA.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyEffects(OpenEndedPipe pipe, FluidStack fluid) {
|
||||
Level world = pipe.getWorld();
|
||||
if (world.getGameTime() % 5 != 0)
|
||||
return;
|
||||
List<LivingEntity> entities = world
|
||||
.getEntitiesOfClass(LivingEntity.class, pipe.getAOE(), LivingEntity::isAffectedByPotions);
|
||||
for (LivingEntity entity : entities) {
|
||||
entity.addEffect(new MobEffectInstance(MobEffects.DIG_SPEED, 21, 0, false, false, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import java.util.List;
|
|||
import com.simibubi.create.AllBlockEntityTypes;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.AllSoundEvents;
|
||||
import com.simibubi.create.api.behaviour.BlockSpoutingBehaviour;
|
||||
import com.simibubi.create.api.behaviour.spouting.BlockSpoutingBehaviour;
|
||||
import com.simibubi.create.api.equipment.goggles.IHaveGoggleInformation;
|
||||
import com.simibubi.create.content.fluids.FluidFX;
|
||||
import com.simibubi.create.content.kinetics.belt.behaviour.BeltProcessingBehaviour;
|
||||
|
@ -23,7 +23,6 @@ import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
|
|||
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.fluid.SmartFluidTankBehaviour;
|
||||
import com.simibubi.create.foundation.fluid.FluidHelper;
|
||||
import com.simibubi.create.impl.behaviour.BlockSpoutingBehaviourImpl;
|
||||
|
||||
import net.createmod.catnip.math.VecHelper;
|
||||
import net.createmod.catnip.nbt.NBTHelper;
|
||||
|
@ -205,15 +204,13 @@ public class SpoutBlockEntity extends SmartBlockEntity implements IHaveGoggleInf
|
|||
|
||||
FluidStack currentFluidInTank = getCurrentFluidInTank();
|
||||
if (processingTicks == -1 && (isVirtual() || !level.isClientSide()) && !currentFluidInTank.isEmpty()) {
|
||||
BlockSpoutingBehaviourImpl.forEach(behaviour -> {
|
||||
if (customProcess != null)
|
||||
return;
|
||||
if (behaviour.fillBlock(level, worldPosition.below(2), this, currentFluidInTank.copy(), true) > 0) {
|
||||
BlockPos filling = this.worldPosition.below(2);
|
||||
BlockSpoutingBehaviour behavior = BlockSpoutingBehaviour.get(this.level, filling);
|
||||
if (behavior != null && behavior.fillBlock(this.level, filling, this, currentFluidInTank.copy(), true) > 0) {
|
||||
processingTicks = FILLING_TIME;
|
||||
customProcess = behaviour;
|
||||
customProcess = behavior;
|
||||
notifyUpdate();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (processingTicks >= 0) {
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.jetbrains.annotations.NotNull;
|
|||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllSoundEvents;
|
||||
import com.simibubi.create.api.boiler.BoilerHeater;
|
||||
import com.simibubi.create.content.decoration.steamWhistle.WhistleBlock;
|
||||
import com.simibubi.create.content.decoration.steamWhistle.WhistleBlockEntity;
|
||||
import com.simibubi.create.content.kinetics.BlockStressValues;
|
||||
|
@ -392,7 +393,7 @@ public class BoilerData {
|
|||
for (int zOffset = 0; zOffset < controller.width; zOffset++) {
|
||||
BlockPos pos = controllerPos.offset(xOffset, -1, zOffset);
|
||||
BlockState blockState = level.getBlockState(pos);
|
||||
float heat = BoilerHeaters.getActiveHeat(level, pos, blockState);
|
||||
float heat = BoilerHeater.findHeat(level, pos, blockState);
|
||||
if (heat == 0) {
|
||||
passiveHeat = true;
|
||||
} else if (heat > 0) {
|
||||
|
|
|
@ -1,66 +1,31 @@
|
|||
package com.simibubi.create.content.fluids.tank;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllTags.AllBlockTags;
|
||||
import com.simibubi.create.api.boiler.BoilerHeater;
|
||||
import com.simibubi.create.api.registry.SimpleRegistry;
|
||||
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
|
||||
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock.HeatLevel;
|
||||
import com.simibubi.create.foundation.utility.AttachedRegistry;
|
||||
import com.simibubi.create.foundation.utility.BlockHelper;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class BoilerHeaters {
|
||||
private static final AttachedRegistry<Block, Heater> BLOCK_HEATERS = new AttachedRegistry<>(BuiltInRegistries.BLOCK);
|
||||
private static final List<HeaterProvider> GLOBAL_HEATERS = new ArrayList<>();
|
||||
|
||||
public static void registerHeater(ResourceLocation block, Heater heater) {
|
||||
BLOCK_HEATERS.register(block, heater);
|
||||
}
|
||||
|
||||
public static void registerHeater(Block block, Heater heater) {
|
||||
BLOCK_HEATERS.register(block, heater);
|
||||
}
|
||||
|
||||
public static void registerHeaterProvider(HeaterProvider provider) {
|
||||
GLOBAL_HEATERS.add(provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* A return value of {@code -1} represents no heat.
|
||||
* A return value of {@code 0} represents passive heat.
|
||||
* All other positive values are used as the amount of active heat.
|
||||
*/
|
||||
public static float getActiveHeat(Level level, BlockPos pos, BlockState state) {
|
||||
Heater heater = BLOCK_HEATERS.get(state.getBlock());
|
||||
if (heater != null) {
|
||||
return heater.getActiveHeat(level, pos, state);
|
||||
}
|
||||
|
||||
for (HeaterProvider provider : GLOBAL_HEATERS) {
|
||||
heater = provider.getHeater(level, pos, state);
|
||||
if (heater != null) {
|
||||
return heater.getActiveHeat(level, pos, state);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static void registerDefaults() {
|
||||
registerHeater(AllBlocks.BLAZE_BURNER.get(), (level, pos, state) -> {
|
||||
BoilerHeater.REGISTRY.register(AllBlocks.BLAZE_BURNER.get(), BoilerHeater.BLAZE_BURNER);
|
||||
BoilerHeater.REGISTRY.registerProvider(SimpleRegistry.Provider.forBlockTag(AllBlockTags.PASSIVE_BOILER_HEATERS.tag, BoilerHeater.PASSIVE));
|
||||
}
|
||||
|
||||
public static int passive(Level level, BlockPos pos, BlockState state) {
|
||||
return BlockHelper.isNotUnheated(state) ? BoilerHeater.PASSIVE_HEAT : BoilerHeater.NO_HEAT;
|
||||
}
|
||||
|
||||
public static int blazeBurner(Level level, BlockPos pos, BlockState state) {
|
||||
HeatLevel value = state.getValue(BlazeBurnerBlock.HEAT_LEVEL);
|
||||
if (value == HeatLevel.NONE) {
|
||||
return -1;
|
||||
return BoilerHeater.NO_HEAT;
|
||||
}
|
||||
if (value == HeatLevel.SEETHING) {
|
||||
return 2;
|
||||
|
@ -68,28 +33,6 @@ public class BoilerHeaters {
|
|||
if (value.isAtLeast(HeatLevel.FADING)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
registerHeaterProvider((level, pos, state) -> {
|
||||
if (AllBlockTags.PASSIVE_BOILER_HEATERS.matches(state) && BlockHelper.isNotUnheated(state)) {
|
||||
return (level1, pos1, state1) -> 0;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
public interface Heater {
|
||||
/**
|
||||
* A return value of {@code -1} represents no heat.
|
||||
* A return value of {@code 0} represents passive heat.
|
||||
* All other positive values are used as the amount of active heat.
|
||||
*/
|
||||
float getActiveHeat(Level level, BlockPos pos, BlockState state);
|
||||
}
|
||||
|
||||
public interface HeaterProvider {
|
||||
@Nullable
|
||||
Heater getHeater(Level level, BlockPos pos, BlockState state);
|
||||
return BoilerHeater.PASSIVE_HEAT;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.simibubi.create.content.fluids.tank;
|
||||
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
|
||||
import com.simibubi.create.api.behaviour.movement.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.simibubi.create.content.kinetics.base;
|
|||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.simibubi.create.AllTags.AllBlockTags;
|
||||
import com.simibubi.create.foundation.utility.BlockHelper;
|
||||
|
||||
import net.createmod.catnip.math.VecHelper;
|
||||
|
@ -132,7 +133,7 @@ public abstract class BlockBreakingKineticBlockEntity extends KineticBlockEntity
|
|||
}
|
||||
|
||||
public static boolean isBreakable(BlockState stateToBreak, float blockHardness) {
|
||||
return !(stateToBreak.liquid() || stateToBreak.getBlock() instanceof AirBlock || blockHardness == -1);
|
||||
return !(stateToBreak.liquid() || stateToBreak.getBlock() instanceof AirBlock || blockHardness == -1 || AllBlockTags.NON_BREAKABLE.matches(stateToBreak));
|
||||
}
|
||||
|
||||
public void onBlockBroken(BlockState stateToBreak) {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package com.simibubi.create.content.kinetics.base;
|
||||
|
||||
import com.simibubi.create.api.behaviour.movement.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.OrientedContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||
import com.simibubi.create.content.contraptions.mounted.MountedContraption;
|
||||
import com.simibubi.create.content.trains.entity.CarriageContraption;
|
||||
|
|
|
@ -2,7 +2,7 @@ package com.simibubi.create.content.kinetics.belt.transport;
|
|||
|
||||
import java.util.Random;
|
||||
|
||||
import com.simibubi.create.AllRegistries;
|
||||
import com.simibubi.create.api.registry.CreateBuiltInRegistries;
|
||||
import com.simibubi.create.content.kinetics.belt.BeltHelper;
|
||||
import com.simibubi.create.content.kinetics.fan.processing.AllFanProcessingTypes;
|
||||
import com.simibubi.create.content.kinetics.fan.processing.FanProcessingType;
|
||||
|
@ -82,8 +82,8 @@ public class TransportedItemStack implements Comparable<TransportedItemStack> {
|
|||
nbt.putInt("Angle", angle);
|
||||
nbt.putInt("InDirection", insertedFrom.get3DDataValue());
|
||||
|
||||
if (processedBy != null && processedBy != AllFanProcessingTypes.NONE) {
|
||||
ResourceLocation key = AllRegistries.FAN_PROCESSING_TYPE.getKey(processedBy);
|
||||
if (processedBy != null) {
|
||||
ResourceLocation key = CreateBuiltInRegistries.FAN_PROCESSING_TYPE.getKey(processedBy);
|
||||
if (key == null)
|
||||
throw new IllegalArgumentException("Could not get id for FanProcessingType " + processedBy + "!");
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue