mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-01-28 22:05:01 +01:00
Add api to add custom conductors to trains
This commit is contained in:
parent
aa15182005
commit
d37b37964b
5 changed files with 97 additions and 23 deletions
|
@ -3,6 +3,9 @@ package com.simibubi.create;
|
||||||
import static com.simibubi.create.AllInteractionBehaviours.interactionBehaviour;
|
import static com.simibubi.create.AllInteractionBehaviours.interactionBehaviour;
|
||||||
import static com.simibubi.create.AllMovementBehaviours.movementBehaviour;
|
import static com.simibubi.create.AllMovementBehaviours.movementBehaviour;
|
||||||
import static com.simibubi.create.Create.REGISTRATE;
|
import static com.simibubi.create.Create.REGISTRATE;
|
||||||
|
|
||||||
|
import com.simibubi.create.api.contraption.train.TrainConductorHandler;
|
||||||
|
|
||||||
import static com.simibubi.create.content.redstone.displayLink.AllDisplayBehaviours.assignDataBehaviour;
|
import static com.simibubi.create.content.redstone.displayLink.AllDisplayBehaviours.assignDataBehaviour;
|
||||||
import static com.simibubi.create.foundation.data.BlockStateGen.axisBlock;
|
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.BlockStateGen.simpleCubeAll;
|
||||||
|
@ -185,7 +188,7 @@ import com.simibubi.create.content.processing.basin.BasinGenerator;
|
||||||
import com.simibubi.create.content.processing.basin.BasinMovementBehaviour;
|
import com.simibubi.create.content.processing.basin.BasinMovementBehaviour;
|
||||||
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
|
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
|
||||||
import com.simibubi.create.content.processing.burner.BlazeBurnerBlockItem;
|
import com.simibubi.create.content.processing.burner.BlazeBurnerBlockItem;
|
||||||
import com.simibubi.create.content.processing.burner.BlazeBurnerInteractionBehaviour;
|
import com.simibubi.create.content.processing.burner.BlockBasedTrainConductorInteractionBehaviour;
|
||||||
import com.simibubi.create.content.processing.burner.BlazeBurnerMovementBehaviour;
|
import com.simibubi.create.content.processing.burner.BlazeBurnerMovementBehaviour;
|
||||||
import com.simibubi.create.content.processing.burner.LitBlazeBurnerBlock;
|
import com.simibubi.create.content.processing.burner.LitBlazeBurnerBlock;
|
||||||
import com.simibubi.create.content.redstone.RoseQuartzLampBlock;
|
import com.simibubi.create.content.redstone.RoseQuartzLampBlock;
|
||||||
|
@ -708,7 +711,7 @@ public class AllBlocks {
|
||||||
.loot((lt, block) -> lt.add(block, BlazeBurnerBlock.buildLootTable()))
|
.loot((lt, block) -> lt.add(block, BlazeBurnerBlock.buildLootTable()))
|
||||||
.blockstate((c, p) -> p.simpleBlock(c.getEntry(), AssetLookup.partialBaseModel(c, p)))
|
.blockstate((c, p) -> p.simpleBlock(c.getEntry(), AssetLookup.partialBaseModel(c, p)))
|
||||||
.onRegister(movementBehaviour(new BlazeBurnerMovementBehaviour()))
|
.onRegister(movementBehaviour(new BlazeBurnerMovementBehaviour()))
|
||||||
.onRegister(interactionBehaviour(new BlazeBurnerInteractionBehaviour()))
|
.onRegister(block -> TrainConductorHandler.registerBlazeBurner())
|
||||||
.item(BlazeBurnerBlockItem::withBlaze)
|
.item(BlazeBurnerBlockItem::withBlaze)
|
||||||
.model(AssetLookup.customBlockItemModel("blaze_burner", "block_with_blaze"))
|
.model(AssetLookup.customBlockItemModel("blaze_burner", "block_with_blaze"))
|
||||||
.build()
|
.build()
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
package com.simibubi.create.api.contraption.train;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllBlocks;
|
||||||
|
import com.simibubi.create.AllInteractionBehaviours;
|
||||||
|
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
|
||||||
|
|
||||||
|
import com.simibubi.create.content.processing.burner.BlockBasedTrainConductorInteractionBehaviour;
|
||||||
|
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All required methods to make your block a train conductor similar to the blaze burner
|
||||||
|
*/
|
||||||
|
public interface TrainConductorHandler {
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
|
List<TrainConductorHandler> CONDUCTOR_HANDLERS = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
boolean isValidConductor(BlockState state);
|
||||||
|
|
||||||
|
private static void registerHandler(TrainConductorHandler handler) {
|
||||||
|
CONDUCTOR_HANDLERS.add(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void registerConductor(ResourceLocation blockRl, Predicate<BlockState> isValidConductor, UpdateScheduleCallback updateScheduleCallback) {
|
||||||
|
AllInteractionBehaviours.registerBehaviour(blockRl, new BlockBasedTrainConductorInteractionBehaviour(isValidConductor, updateScheduleCallback));
|
||||||
|
registerHandler(isValidConductor::test);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
|
static void registerBlazeBurner() {
|
||||||
|
registerConductor(AllBlocks.BLAZE_BURNER.getId(), blockState -> AllBlocks.BLAZE_BURNER.has(blockState)
|
||||||
|
&& blockState.getValue(BlazeBurnerBlock.HEAT_LEVEL) != BlazeBurnerBlock.HeatLevel.NONE, UpdateScheduleCallback.EMPTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface UpdateScheduleCallback {
|
||||||
|
|
||||||
|
UpdateScheduleCallback EMPTY = (hasSchedule, blockState, blockStateSetter) -> {};
|
||||||
|
|
||||||
|
void update(boolean hasSchedule, BlockState currentBlockState, Consumer<BlockState> blockStateSetter);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,10 +2,10 @@ package com.simibubi.create.content.processing.burner;
|
||||||
|
|
||||||
import com.simibubi.create.AllItems;
|
import com.simibubi.create.AllItems;
|
||||||
import com.simibubi.create.AllSoundEvents;
|
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.AbstractContraptionEntity;
|
||||||
import com.simibubi.create.content.contraptions.Contraption;
|
import com.simibubi.create.content.contraptions.Contraption;
|
||||||
import com.simibubi.create.content.contraptions.behaviour.MovingInteractionBehaviour;
|
import com.simibubi.create.content.contraptions.behaviour.MovingInteractionBehaviour;
|
||||||
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock.HeatLevel;
|
|
||||||
import com.simibubi.create.content.trains.entity.CarriageContraption;
|
import com.simibubi.create.content.trains.entity.CarriageContraption;
|
||||||
import com.simibubi.create.content.trains.entity.CarriageContraptionEntity;
|
import com.simibubi.create.content.trains.entity.CarriageContraptionEntity;
|
||||||
import com.simibubi.create.content.trains.entity.Train;
|
import com.simibubi.create.content.trains.entity.Train;
|
||||||
|
@ -21,9 +21,21 @@ import net.minecraft.core.Direction;
|
||||||
import net.minecraft.world.InteractionHand;
|
import net.minecraft.world.InteractionHand;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.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 net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo;
|
||||||
|
|
||||||
public class BlazeBurnerInteractionBehaviour extends MovingInteractionBehaviour {
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handlePlayerInteraction(Player player, InteractionHand activeHand, BlockPos localPos,
|
public boolean handlePlayerInteraction(Player player, InteractionHand activeHand, BlockPos localPos,
|
||||||
|
@ -40,8 +52,7 @@ public class BlazeBurnerInteractionBehaviour extends MovingInteractionBehaviour
|
||||||
|
|
||||||
StructureBlockInfo info = carriageContraption.getBlocks()
|
StructureBlockInfo info = carriageContraption.getBlocks()
|
||||||
.get(localPos);
|
.get(localPos);
|
||||||
if (info == null || !info.state().hasProperty(BlazeBurnerBlock.HEAT_LEVEL)
|
if (info == null || !isValidConductor.test(info.state()))
|
||||||
|| info.state().getValue(BlazeBurnerBlock.HEAT_LEVEL) == HeatLevel.NONE)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Direction assemblyDirection = carriageContraption.getAssemblyDirection();
|
Direction assemblyDirection = carriageContraption.getAssemblyDirection();
|
||||||
|
@ -74,6 +85,7 @@ public class BlazeBurnerInteractionBehaviour extends MovingInteractionBehaviour
|
||||||
train.runtime.isAutoSchedule ? "schedule.auto_removed_from_train" : "schedule.removed_from_train"),
|
train.runtime.isAutoSchedule ? "schedule.auto_removed_from_train" : "schedule.removed_from_train"),
|
||||||
true);
|
true);
|
||||||
player.setItemInHand(activeHand, train.runtime.returnSchedule());
|
player.setItemInHand(activeHand, train.runtime.returnSchedule());
|
||||||
|
callback.update(false, info.state(), newBlockState -> setBlockState(localPos, contraptionEntity, newBlockState));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +101,7 @@ public class BlazeBurnerInteractionBehaviour extends MovingInteractionBehaviour
|
||||||
player.displayClientMessage(Lang.translateDirect("schedule.no_stops"), true);
|
player.displayClientMessage(Lang.translateDirect("schedule.no_stops"), true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
callback.update(true, info.state(), newBlockState -> setBlockState(localPos, contraptionEntity, newBlockState));
|
||||||
train.runtime.setSchedule(schedule, false);
|
train.runtime.setSchedule(schedule, false);
|
||||||
AllAdvancements.CONDUCTOR.awardTo(player);
|
AllAdvancements.CONDUCTOR.awardTo(player);
|
||||||
AllSoundEvents.CONFIRM.playOnServer(player.level(), player.blockPosition(), 1, 1);
|
AllSoundEvents.CONFIRM.playOnServer(player.level(), player.blockPosition(), 1, 1);
|
||||||
|
@ -105,4 +117,10 @@ public class BlazeBurnerInteractionBehaviour extends MovingInteractionBehaviour
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setBlockState(BlockPos localPos, AbstractContraptionEntity contraption, BlockState newState) {
|
||||||
|
StructureTemplate.StructureBlockInfo info = contraption.getContraption().getBlocks().get(localPos);
|
||||||
|
if (info != null) {
|
||||||
|
setContraptionBlockData(contraption, localPos, new StructureTemplate.StructureBlockInfo(info.pos(), newState, info.nbt()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -7,6 +7,8 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import com.simibubi.create.api.contraption.train.TrainConductorHandler;
|
||||||
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
|
@ -17,8 +19,6 @@ import com.simibubi.create.content.contraptions.ContraptionType;
|
||||||
import com.simibubi.create.content.contraptions.MountedStorageManager;
|
import com.simibubi.create.content.contraptions.MountedStorageManager;
|
||||||
import com.simibubi.create.content.contraptions.actors.trainControls.ControlsBlock;
|
import com.simibubi.create.content.contraptions.actors.trainControls.ControlsBlock;
|
||||||
import com.simibubi.create.content.contraptions.minecart.TrainCargoManager;
|
import com.simibubi.create.content.contraptions.minecart.TrainCargoManager;
|
||||||
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
|
|
||||||
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock.HeatLevel;
|
|
||||||
import com.simibubi.create.content.trains.bogey.AbstractBogeyBlock;
|
import com.simibubi.create.content.trains.bogey.AbstractBogeyBlock;
|
||||||
import com.simibubi.create.foundation.utility.Couple;
|
import com.simibubi.create.foundation.utility.Couple;
|
||||||
import com.simibubi.create.foundation.utility.Iterate;
|
import com.simibubi.create.foundation.utility.Iterate;
|
||||||
|
@ -51,7 +51,7 @@ public class CarriageContraption extends Contraption {
|
||||||
private boolean forwardControls;
|
private boolean forwardControls;
|
||||||
private boolean backwardControls;
|
private boolean backwardControls;
|
||||||
|
|
||||||
public Couple<Boolean> blazeBurnerConductors;
|
public Couple<Boolean> blockConductors;
|
||||||
public Map<BlockPos, Couple<Boolean>> conductorSeats;
|
public Map<BlockPos, Couple<Boolean>> conductorSeats;
|
||||||
public ArrivalSoundQueue soundQueue;
|
public ArrivalSoundQueue soundQueue;
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ public class CarriageContraption extends Contraption {
|
||||||
private int bogeys;
|
private int bogeys;
|
||||||
private boolean sidewaysControls;
|
private boolean sidewaysControls;
|
||||||
private BlockPos secondBogeyPos;
|
private BlockPos secondBogeyPos;
|
||||||
private List<BlockPos> assembledBlazeBurners;
|
private List<BlockPos> assembledBlockConductors;
|
||||||
|
|
||||||
// render
|
// render
|
||||||
public int portalCutoffMin;
|
public int portalCutoffMin;
|
||||||
|
@ -72,8 +72,8 @@ public class CarriageContraption extends Contraption {
|
||||||
|
|
||||||
public CarriageContraption() {
|
public CarriageContraption() {
|
||||||
conductorSeats = new HashMap<>();
|
conductorSeats = new HashMap<>();
|
||||||
assembledBlazeBurners = new ArrayList<>();
|
assembledBlockConductors = new ArrayList<>();
|
||||||
blazeBurnerConductors = Couple.create(false, false);
|
blockConductors = Couple.create(false, false);
|
||||||
soundQueue = new ArrivalSoundQueue();
|
soundQueue = new ArrivalSoundQueue();
|
||||||
portalCutoffMin = Integer.MIN_VALUE;
|
portalCutoffMin = Integer.MIN_VALUE;
|
||||||
portalCutoffMax = Integer.MAX_VALUE;
|
portalCutoffMax = Integer.MAX_VALUE;
|
||||||
|
@ -103,10 +103,10 @@ public class CarriageContraption extends Contraption {
|
||||||
if (sidewaysControls)
|
if (sidewaysControls)
|
||||||
throw new AssemblyException(Lang.translateDirect("train_assembly.sideways_controls"));
|
throw new AssemblyException(Lang.translateDirect("train_assembly.sideways_controls"));
|
||||||
|
|
||||||
for (BlockPos blazePos : assembledBlazeBurners)
|
for (BlockPos blazePos : assembledBlockConductors)
|
||||||
for (Direction direction : Iterate.directionsInAxis(assemblyDirection.getAxis()))
|
for (Direction direction : Iterate.directionsInAxis(assemblyDirection.getAxis()))
|
||||||
if (inControl(blazePos, direction))
|
if (inControl(blazePos, direction))
|
||||||
blazeBurnerConductors.set(direction != assemblyDirection, true);
|
blockConductors.set(direction != assemblyDirection, true);
|
||||||
for (BlockPos seatPos : getSeats())
|
for (BlockPos seatPos : getSeats())
|
||||||
for (Direction direction : Iterate.directionsInAxis(assemblyDirection.getAxis()))
|
for (Direction direction : Iterate.directionsInAxis(assemblyDirection.getAxis()))
|
||||||
if (inControl(seatPos, direction))
|
if (inControl(seatPos, direction))
|
||||||
|
@ -166,9 +166,8 @@ public class CarriageContraption extends Contraption {
|
||||||
captureBE ? world.getBlockEntity(pos) : null);
|
captureBE ? world.getBlockEntity(pos) : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AllBlocks.BLAZE_BURNER.has(blockState)
|
if (TrainConductorHandler.CONDUCTOR_HANDLERS.stream().anyMatch(handler -> handler.isValidConductor(blockState)))
|
||||||
&& blockState.getValue(BlazeBurnerBlock.HEAT_LEVEL) != HeatLevel.NONE)
|
assembledBlockConductors.add(toLocalPos(pos));
|
||||||
assembledBlazeBurners.add(toLocalPos(pos));
|
|
||||||
|
|
||||||
if (AllBlocks.TRAIN_CONTROLS.has(blockState)) {
|
if (AllBlocks.TRAIN_CONTROLS.has(blockState)) {
|
||||||
Direction facing = blockState.getValue(ControlsBlock.FACING);
|
Direction facing = blockState.getValue(ControlsBlock.FACING);
|
||||||
|
@ -192,8 +191,8 @@ public class CarriageContraption extends Contraption {
|
||||||
NBTHelper.writeEnum(tag, "AssemblyDirection", getAssemblyDirection());
|
NBTHelper.writeEnum(tag, "AssemblyDirection", getAssemblyDirection());
|
||||||
tag.putBoolean("FrontControls", forwardControls);
|
tag.putBoolean("FrontControls", forwardControls);
|
||||||
tag.putBoolean("BackControls", backwardControls);
|
tag.putBoolean("BackControls", backwardControls);
|
||||||
tag.putBoolean("FrontBlazeConductor", blazeBurnerConductors.getFirst());
|
tag.putBoolean("FrontBlazeConductor", blockConductors.getFirst());
|
||||||
tag.putBoolean("BackBlazeConductor", blazeBurnerConductors.getSecond());
|
tag.putBoolean("BackBlazeConductor", blockConductors.getSecond());
|
||||||
ListTag list = NBTHelper.writeCompoundList(conductorSeats.entrySet(), e -> {
|
ListTag list = NBTHelper.writeCompoundList(conductorSeats.entrySet(), e -> {
|
||||||
CompoundTag compoundTag = new CompoundTag();
|
CompoundTag compoundTag = new CompoundTag();
|
||||||
compoundTag.put("Pos", NbtUtils.writeBlockPos(e.getKey()));
|
compoundTag.put("Pos", NbtUtils.writeBlockPos(e.getKey()));
|
||||||
|
@ -213,7 +212,7 @@ public class CarriageContraption extends Contraption {
|
||||||
assemblyDirection = NBTHelper.readEnum(nbt, "AssemblyDirection", Direction.class);
|
assemblyDirection = NBTHelper.readEnum(nbt, "AssemblyDirection", Direction.class);
|
||||||
forwardControls = nbt.getBoolean("FrontControls");
|
forwardControls = nbt.getBoolean("FrontControls");
|
||||||
backwardControls = nbt.getBoolean("BackControls");
|
backwardControls = nbt.getBoolean("BackControls");
|
||||||
blazeBurnerConductors =
|
blockConductors =
|
||||||
Couple.create(nbt.getBoolean("FrontBlazeConductor"), nbt.getBoolean("BackBlazeConductor"));
|
Couple.create(nbt.getBoolean("FrontBlazeConductor"), nbt.getBoolean("BackBlazeConductor"));
|
||||||
conductorSeats.clear();
|
conductorSeats.clear();
|
||||||
NBTHelper.iterateCompoundList(nbt.getList("ConductorSeats", Tag.TAG_COMPOUND),
|
NBTHelper.iterateCompoundList(nbt.getList("ConductorSeats", Tag.TAG_COMPOUND),
|
||||||
|
|
|
@ -492,8 +492,8 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
||||||
if (!(contraption instanceof CarriageContraption cc))
|
if (!(contraption instanceof CarriageContraption cc))
|
||||||
return sides;
|
return sides;
|
||||||
|
|
||||||
sides.setFirst(cc.blazeBurnerConductors.getFirst());
|
sides.setFirst(cc.blockConductors.getFirst());
|
||||||
sides.setSecond(cc.blazeBurnerConductors.getSecond());
|
sides.setSecond(cc.blockConductors.getSecond());
|
||||||
|
|
||||||
for (Entity entity : getPassengers()) {
|
for (Entity entity : getPassengers()) {
|
||||||
if (entity instanceof Player)
|
if (entity instanceof Player)
|
||||||
|
|
Loading…
Reference in a new issue