Changed method of checking if a computer attached

- After talking with SquidDev from CC: Tweaked I've changed to monitoring IPeripheral#attach and IPeripheral#detach for changes in the number of computers connected to the network, then updating the client using AttachedComputerPacket
- This works with wired full modems, wired cabled modems and directly connected computers
- Added SyncedPeripheralBase and SyncedComputerControllable for TE's and peripherals that want to be aware of attached computers
This commit is contained in:
caelwarner 2022-10-06 02:50:41 -07:00
parent 96dc4db6dc
commit 18bfb216b1
No known key found for this signature in database
GPG Key ID: 514BEF5EADE889FF
9 changed files with 101 additions and 37 deletions

View File

@ -0,0 +1,35 @@
package com.simibubi.create.compat.computercraft;
import com.simibubi.create.foundation.networking.TileEntityDataPacket;
import com.simibubi.create.foundation.tileEntity.SyncedTileEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.network.FriendlyByteBuf;
public class AttachedComputerPacket extends TileEntityDataPacket<SyncedTileEntity> {
private final boolean hasAttachedComputer;
public AttachedComputerPacket(BlockPos tilePos, boolean hasAttachedComputer) {
super(tilePos);
this.hasAttachedComputer = hasAttachedComputer;
}
public AttachedComputerPacket(FriendlyByteBuf buffer) {
super(buffer);
this.hasAttachedComputer = buffer.readBoolean();
}
@Override
protected void writeData(FriendlyByteBuf buffer) {
buffer.writeBoolean(hasAttachedComputer);
}
@Override
protected void handlePacket(SyncedTileEntity tile) {
if (tile instanceof SyncedComputerControllable computerControllable) {
computerControllable.setHasAttachedComputer(hasAttachedComputer);
}
}
}

View File

@ -2,14 +2,7 @@ package com.simibubi.create.compat.computercraft;
import org.jetbrains.annotations.NotNull; 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 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.Capability;
import net.minecraftforge.common.capabilities.CapabilityManager; import net.minecraftforge.common.capabilities.CapabilityManager;
import net.minecraftforge.common.capabilities.CapabilityToken; import net.minecraftforge.common.capabilities.CapabilityToken;
@ -24,7 +17,6 @@ public interface ComputerControllable {
void setPeripheral(LazyOptional<IPeripheral> peripheral); void setPeripheral(LazyOptional<IPeripheral> peripheral);
LazyOptional<IPeripheral> getPeripheral(); LazyOptional<IPeripheral> getPeripheral();
default <T> LazyOptional<T> getPeripheralCapability(@NotNull Capability<T> cap) { default <T> LazyOptional<T> getPeripheralCapability(@NotNull Capability<T> cap) {
if (cap == PERIPHERAL_CAPABILITY) { if (cap == PERIPHERAL_CAPABILITY) {
if (getPeripheral() == null || !getPeripheral().isPresent()) if (getPeripheral() == null || !getPeripheral().isPresent())
@ -42,22 +34,4 @@ public interface ComputerControllable {
} }
} }
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

@ -11,7 +11,7 @@ import dan200.computercraft.api.lua.IArguments;
import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaFunction; import dan200.computercraft.api.lua.LuaFunction;
public class SequencedGearshiftPeripheral extends PeripheralBase<SequencedGearshiftTileEntity> { public class SequencedGearshiftPeripheral extends SyncedPeripheralBase<SequencedGearshiftTileEntity> {
public SequencedGearshiftPeripheral(SequencedGearshiftTileEntity tile) { public SequencedGearshiftPeripheral(SequencedGearshiftTileEntity tile) {
super(tile); super(tile);

View File

@ -0,0 +1,7 @@
package com.simibubi.create.compat.computercraft;
public interface SyncedComputerControllable extends ComputerControllable {
void setHasAttachedComputer(boolean hasAttachedComputer);
}

View File

@ -0,0 +1,40 @@
package com.simibubi.create.compat.computercraft;
import java.util.concurrent.atomic.AtomicInteger;
import org.jetbrains.annotations.NotNull;
import com.simibubi.create.foundation.networking.AllPackets;
import dan200.computercraft.api.peripheral.IComputerAccess;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.network.PacketDistributor;
public abstract class SyncedPeripheralBase<T extends BlockEntity & SyncedComputerControllable> extends PeripheralBase<T> {
private final AtomicInteger computers = new AtomicInteger();
public SyncedPeripheralBase(T tile) {
super(tile);
}
@Override
public void attach(@NotNull IComputerAccess computer) {
computers.incrementAndGet();
updateTile();
}
@Override
public void detach(@NotNull IComputerAccess computer) {
computers.decrementAndGet();
updateTile();
}
private void updateTile() {
boolean hasAttachedComputer = computers.get() > 0;
tile.setHasAttachedComputer(hasAttachedComputer);
AllPackets.channel.send(PacketDistributor.ALL.noArg(), new AttachedComputerPacket(tile.getBlockPos(), hasAttachedComputer));
}
}

View File

@ -35,7 +35,7 @@ public class ConfigureSequencedGearshiftPacket extends TileEntityConfigurationPa
@Override @Override
protected void applySettings(SequencedGearshiftTileEntity te) { protected void applySettings(SequencedGearshiftTileEntity te) {
if (te.isComputerControlled(te)) if (te.hasAttachedComputer)
return; return;
te.run(-1); te.run(-1);

View File

@ -29,7 +29,7 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen {
private ListTag compareTag; private ListTag compareTag;
private Vector<Instruction> instructions; private Vector<Instruction> instructions;
private BlockPos pos; private BlockPos pos;
private final boolean isComputerControlled; private final boolean hasAttachedComputer;
private Vector<Vector<ScrollInput>> inputs; private Vector<Vector<ScrollInput>> inputs;
@ -37,7 +37,7 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen {
super(Lang.translateDirect("gui.sequenced_gearshift.title")); super(Lang.translateDirect("gui.sequenced_gearshift.title"));
this.instructions = te.instructions; this.instructions = te.instructions;
this.pos = te.getBlockPos(); this.pos = te.getBlockPos();
this.isComputerControlled = te.isComputerControlled(te); this.hasAttachedComputer = te.hasAttachedComputer;
compareTag = Instruction.serializeAll(instructions); compareTag = Instruction.serializeAll(instructions);
} }
@ -51,7 +51,7 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen {
int y = guiTop; int y = guiTop;
inputs = new Vector<>(5); inputs = new Vector<>(5);
if (!isComputerControlled) { if (!hasAttachedComputer) {
for (int row = 0; row < inputs.capacity(); row++) for (int row = 0; row < inputs.capacity(); row++)
inputs.add(new Vector<>(3)); inputs.add(new Vector<>(3));
@ -138,7 +138,7 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen {
background.render(ms, x, y, this); background.render(ms, x, y, this);
if (isComputerControlled) { if (hasAttachedComputer) {
for (int row = 0; row < instructions.capacity(); row++) { for (int row = 0; row < instructions.capacity(); row++) {
AllGuiTextures toDraw = AllGuiTextures.SEQUENCER_EMPTY; AllGuiTextures toDraw = AllGuiTextures.SEQUENCER_EMPTY;
int yOffset = toDraw.height * row; int yOffset = toDraw.height * row;
@ -183,7 +183,7 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen {
} }
public void sendPacket() { public void sendPacket() {
if (isComputerControlled) if (hasAttachedComputer)
return; return;
ListTag serialized = Instruction.serializeAll(instructions); ListTag serialized = Instruction.serializeAll(instructions);

View File

@ -5,8 +5,8 @@ import java.util.Vector;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import com.simibubi.create.compat.computercraft.ComputerControllable;
import com.simibubi.create.compat.computercraft.SequencedGearshiftPeripheral; import com.simibubi.create.compat.computercraft.SequencedGearshiftPeripheral;
import com.simibubi.create.compat.computercraft.SyncedComputerControllable;
import com.simibubi.create.content.contraptions.relays.encased.SplitShaftTileEntity; import com.simibubi.create.content.contraptions.relays.encased.SplitShaftTileEntity;
import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheral;
@ -19,7 +19,7 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.LazyOptional;
public class SequencedGearshiftTileEntity extends SplitShaftTileEntity implements ComputerControllable { public class SequencedGearshiftTileEntity extends SplitShaftTileEntity implements SyncedComputerControllable {
Vector<Instruction> instructions; Vector<Instruction> instructions;
int currentInstruction; int currentInstruction;
@ -29,6 +29,7 @@ public class SequencedGearshiftTileEntity extends SplitShaftTileEntity implement
boolean poweredPreviously; boolean poweredPreviously;
LazyOptional<IPeripheral> peripheral; LazyOptional<IPeripheral> peripheral;
boolean hasAttachedComputer;
public SequencedGearshiftTileEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) { public SequencedGearshiftTileEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state); super(type, pos, state);
@ -38,6 +39,7 @@ public class SequencedGearshiftTileEntity extends SplitShaftTileEntity implement
currentInstructionProgress = 0; currentInstructionProgress = 0;
timer = 0; timer = 0;
poweredPreviously = false; poweredPreviously = false;
hasAttachedComputer = false;
} }
@Override @Override
@ -82,7 +84,7 @@ public class SequencedGearshiftTileEntity extends SplitShaftTileEntity implement
} }
public void onRedstoneUpdate(boolean isPowered, boolean isRunning) { public void onRedstoneUpdate(boolean isPowered, boolean isRunning) {
if (isComputerControlled(this)) if (hasAttachedComputer)
return; return;
if (!poweredPreviously && isPowered) if (!poweredPreviously && isPowered)
risingFlank(); risingFlank();
@ -197,6 +199,11 @@ public class SequencedGearshiftTileEntity extends SplitShaftTileEntity implement
return this.peripheral; return this.peripheral;
} }
@Override
public void setHasAttachedComputer(boolean hasAttachedComputer) {
this.hasAttachedComputer = hasAttachedComputer;
}
@Override @Override
public float getRotationSpeedModifier(Direction face) { public float getRotationSpeedModifier(Direction face) {
if (isVirtual()) if (isVirtual())

View File

@ -8,6 +8,7 @@ import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.compat.computercraft.AttachedComputerPacket;
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionBlockChangedPacket; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionBlockChangedPacket;
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionDisassemblyPacket; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionDisassemblyPacket;
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionRelocationPacket; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionRelocationPacket;
@ -184,7 +185,7 @@ public enum AllPackets {
S_TRAIN_PROMPT(TrainPromptPacket.class, TrainPromptPacket::new, PLAY_TO_CLIENT), S_TRAIN_PROMPT(TrainPromptPacket.class, TrainPromptPacket::new, PLAY_TO_CLIENT),
CONTRAPTION_RELOCATION(ContraptionRelocationPacket.class, ContraptionRelocationPacket::new, PLAY_TO_CLIENT), CONTRAPTION_RELOCATION(ContraptionRelocationPacket.class, ContraptionRelocationPacket::new, PLAY_TO_CLIENT),
TRACK_GRAPH_ROLL_CALL(TrackGraphRollCallPacket.class, TrackGraphRollCallPacket::new, PLAY_TO_CLIENT), TRACK_GRAPH_ROLL_CALL(TrackGraphRollCallPacket.class, TrackGraphRollCallPacket::new, PLAY_TO_CLIENT),
ATTACHED_COMPUTER(AttachedComputerPacket.class, AttachedComputerPacket::new, PLAY_TO_CLIENT),
; ;
public static final ResourceLocation CHANNEL_NAME = Create.asResource("main"); public static final ResourceLocation CHANNEL_NAME = Create.asResource("main");