Sequenced Gearshift screen "greys out" when being controlled by a computer

- This is to stop players from trying to using both the builtin sequencing and a computer to control the Sequenced Gearshift at the same time, leading to undefined behaviour
- The "greyed out" screen should have a message added explaining why it's greyed out.
- Added ComputerControllable#isComputerControlled to check if a tile entity is connected to a modem
This commit is contained in:
caelwarner 2022-10-04 21:11:38 -07:00
parent 9a80781401
commit 96dc4db6dc
No known key found for this signature in database
GPG Key ID: 514BEF5EADE889FF
6 changed files with 75 additions and 21 deletions

View File

@ -5,7 +5,10 @@ import java.util.function.Supplier;
import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.Block;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.registries.ForgeRegistries;
/**
* For compatibility with and without another mod present, we have to define load conditions of the specific code
@ -51,4 +54,8 @@ public enum Mods {
toExecute.get().run();
}
}
public Block getBlock(String id) {
return ForgeRegistries.BLOCKS.getValue(new ResourceLocation(asId(), id));
}
}

View File

@ -2,7 +2,14 @@ package com.simibubi.create.compat.computercraft;
import org.jetbrains.annotations.NotNull;
import com.simibubi.create.compat.Mods;
import com.simibubi.create.foundation.utility.Iterate;
import dan200.computercraft.api.peripheral.IPeripheral;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityManager;
import net.minecraftforge.common.capabilities.CapabilityToken;
@ -30,8 +37,27 @@ public interface ComputerControllable {
}
default void removePeripheral() {
if (getPeripheral() != null)
if (getPeripheral() != null) {
getPeripheral().invalidate();
}
}
default boolean isComputerControlled(BlockEntity tile) {
if (tile.getLevel() == null || !(tile instanceof ComputerControllable))
return false;
for (Direction direction : Iterate.directions) {
BlockState state = tile.getLevel().getBlockState(tile.getBlockPos().relative(direction));
// TODO: Add a check for "cable" wired modem.
// The difficulty comes since the "cable" wired modem uses an enum property instead of a boolean property.
// This could possibly be surpassed with reflection. It would be good to find a more solid solution.
if (state.getBlock().equals(Mods.COMPUTERCRAFT.getBlock("wired_modem_full"))) {
return state.getOptionalValue(BooleanProperty.create("peripheral")).orElse(false);
}
}
return false;
}
}

View File

@ -35,6 +35,9 @@ public class ConfigureSequencedGearshiftPacket extends TileEntityConfigurationPa
@Override
protected void applySettings(SequencedGearshiftTileEntity te) {
if (te.isComputerControlled(te))
return;
te.run(-1);
te.instructions = Instruction.deserializeAll(instructions);
te.sendData();

View File

@ -29,6 +29,7 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen {
private ListTag compareTag;
private Vector<Instruction> instructions;
private BlockPos pos;
private final boolean isComputerControlled;
private Vector<Vector<ScrollInput>> inputs;
@ -36,6 +37,7 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen {
super(Lang.translateDirect("gui.sequenced_gearshift.title"));
this.instructions = te.instructions;
this.pos = te.getBlockPos();
this.isComputerControlled = te.isComputerControlled(te);
compareTag = Instruction.serializeAll(instructions);
}
@ -49,11 +51,13 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen {
int y = guiTop;
inputs = new Vector<>(5);
if (!isComputerControlled) {
for (int row = 0; row < inputs.capacity(); row++)
inputs.add(new Vector<>(3));
for (int row = 0; row < instructions.size(); row++)
initInputsOfRow(row, x, y);
}
confirmButton =
new IconButton(x + background.width - 33, y + background.height - 24, AllIcons.I_CONFIRM);
@ -134,6 +138,15 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen {
background.render(ms, x, y, this);
if (isComputerControlled) {
for (int row = 0; row < instructions.capacity(); row++) {
AllGuiTextures toDraw = AllGuiTextures.SEQUENCER_EMPTY;
int yOffset = toDraw.height * row;
toDraw.render(ms, x, y + 14 + yOffset, this);
}
} else {
for (int row = 0; row < instructions.capacity(); row++) {
AllGuiTextures toDraw = AllGuiTextures.SEQUENCER_EMPTY;
int yOffset = toDraw.height * row;
@ -155,6 +168,7 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen {
if (def.hasSpeedParameter)
label(ms, 127, yOffset - 3, instruction.speedModifier.label);
}
}
drawCenteredString(ms, font, title, x + (background.width - 8) / 2, y + 3, 0xFFFFFF);
@ -169,6 +183,9 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen {
}
public void sendPacket() {
if (isComputerControlled)
return;
ListTag serialized = Instruction.serializeAll(instructions);
if (serialized.equals(compareTag))
return;

View File

@ -82,6 +82,8 @@ public class SequencedGearshiftTileEntity extends SplitShaftTileEntity implement
}
public void onRedstoneUpdate(boolean isPowered, boolean isRunning) {
if (isComputerControlled(this))
return;
if (!poweredPreviously && isPowered)
risingFlank();
poweredPreviously = isPowered;

View File

@ -244,7 +244,6 @@ public class AllDisplayBehaviours {
DisplayBehaviour computerDisplaySource = register(Create.asResource("computer_display_source"), new ComputerDisplaySource());
assignTile(computerDisplaySource, new ResourceLocation(Mods.COMPUTERCRAFT.asId(), "wired_modem_full"));
assignTile(computerDisplaySource, new ResourceLocation("computercraft", "wired_modem"));
});
}
}