Merge pull request #10 from Creators-of-Create/jay/mc1.20.1/rework-block-conductors

Rework Block Conductors
This commit is contained in:
IThundxr 2025-02-20 08:45:27 -05:00 committed by GitHub
commit d52fea34dd
Failed to generate hash of commit
5 changed files with 38 additions and 84 deletions

View file

@ -18,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;
@ -269,7 +270,6 @@ import com.simibubi.create.foundation.item.ItemDescription;
import com.simibubi.create.foundation.item.UncontainableBlockItem;
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.providers.loot.RegistrateBlockLootTables;
import com.tterrag.registrate.util.DataIngredient;
@ -748,7 +748,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(TrainConductorHandlerImpl::registerBlazeBurner)
.onRegister(interactionBehaviour(new ConductorBlockInteractionBehavior.BlazeBurner()))
.item(BlazeBurnerBlockItem::withBlaze)
.model(AssetLookup.customBlockItemModel("blaze_burner", "block_with_blaze"))
.build()

View file

@ -1,13 +1,12 @@
package com.simibubi.create.content.processing.burner;
package com.simibubi.create.api.behaviour.interaction;
import java.util.function.Predicate;
import java.util.function.Consumer;
import com.simibubi.create.AllItems;
import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.api.behaviour.interaction.MovingInteractionBehaviour;
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.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;
@ -27,18 +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;
public class BlockBasedTrainConductorInteractionBehaviour extends MovingInteractionBehaviour {
/**
* 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);
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());
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;
}
}
}

View file

@ -1,36 +0,0 @@
package com.simibubi.create.api.contraption.train;
import java.util.function.Consumer;
import java.util.function.Predicate;
import com.simibubi.create.api.behaviour.interaction.MovingInteractionBehaviour;
import com.simibubi.create.content.processing.burner.BlockBasedTrainConductorInteractionBehaviour;
import com.simibubi.create.impl.contraption.train.TrainConductorHandlerImpl;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
/**
* All required methods to make your block a train conductor similar to the blaze burner
*/
@FunctionalInterface
public interface TrainConductorHandler {
boolean isValidConductor(BlockState state);
private static void registerHandler(TrainConductorHandler handler) {
TrainConductorHandlerImpl.CONDUCTOR_HANDLERS.add(handler);
}
static void registerConductor(Block block, Predicate<BlockState> isValidConductor, UpdateScheduleCallback updateScheduleCallback) {
BlockBasedTrainConductorInteractionBehaviour behavior = new BlockBasedTrainConductorInteractionBehaviour(isValidConductor, updateScheduleCallback);
MovingInteractionBehaviour.REGISTRY.register(block, behavior);
registerHandler(isValidConductor::test);
}
interface UpdateScheduleCallback {
UpdateScheduleCallback EMPTY = (hasSchedule, blockState, blockStateSetter) -> {};
void update(boolean hasSchedule, BlockState currentBlockState, Consumer<BlockState> blockStateSetter);
}
}

View file

@ -10,7 +10,8 @@ import java.util.Optional;
import org.apache.commons.lang3.tuple.Pair;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.api.contraption.train.TrainConductorHandler;
import com.simibubi.create.api.behaviour.interaction.ConductorBlockInteractionBehavior;
import com.simibubi.create.api.behaviour.interaction.MovingInteractionBehaviour;
import com.simibubi.create.content.contraptions.AssemblyException;
import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.content.contraptions.ContraptionType;
@ -19,7 +20,6 @@ import com.simibubi.create.content.contraptions.actors.trainControls.ControlsBlo
import com.simibubi.create.content.contraptions.minecart.TrainCargoManager;
import com.simibubi.create.content.trains.bogey.AbstractBogeyBlock;
import com.simibubi.create.foundation.utility.CreateLang;
import com.simibubi.create.impl.contraption.train.TrainConductorHandlerImpl;
import net.createmod.catnip.data.Couple;
import net.createmod.catnip.data.Iterate;
@ -165,11 +165,9 @@ public class CarriageContraption extends Contraption {
captureBE ? world.getBlockEntity(pos) : null);
}
for (TrainConductorHandler handler : TrainConductorHandlerImpl.CONDUCTOR_HANDLERS) {
if (handler.isValidConductor(blockState)) {
assembledBlockConductors.add(toLocalPos(pos));
break;
}
MovingInteractionBehaviour behaviour = MovingInteractionBehaviour.REGISTRY.get(blockState);
if (behaviour instanceof ConductorBlockInteractionBehavior conductor && conductor.isValidConductor(blockState)) {
assembledBlockConductors.add(toLocalPos(pos));
}
if (AllBlocks.TRAIN_CONTROLS.has(blockState)) {

View file

@ -1,24 +0,0 @@
package com.simibubi.create.impl.contraption.train;
import java.util.ArrayList;
import java.util.List;
import org.jetbrains.annotations.ApiStatus;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.api.contraption.train.TrainConductorHandler;
import com.simibubi.create.api.contraption.train.TrainConductorHandler.UpdateScheduleCallback;
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
import net.minecraft.world.level.block.Block;
@ApiStatus.Internal
public class TrainConductorHandlerImpl {
public static final List<TrainConductorHandler> CONDUCTOR_HANDLERS = new ArrayList<>();
@ApiStatus.Internal
public static void registerBlazeBurner(Block block) {
TrainConductorHandler.registerConductor(block, blockState -> AllBlocks.BLAZE_BURNER.has(blockState)
&& blockState.getValue(BlazeBurnerBlock.HEAT_LEVEL) != BlazeBurnerBlock.HeatLevel.NONE, UpdateScheduleCallback.EMPTY);
}
}