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 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;
@ -24,7 +17,6 @@ public interface ComputerControllable {
void setPeripheral(LazyOptional<IPeripheral> peripheral);
LazyOptional<IPeripheral> getPeripheral();
default <T> LazyOptional<T> getPeripheralCapability(@NotNull Capability<T> cap) {
if (cap == PERIPHERAL_CAPABILITY) {
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.LuaFunction;
public class SequencedGearshiftPeripheral extends PeripheralBase<SequencedGearshiftTileEntity> {
public class SequencedGearshiftPeripheral extends SyncedPeripheralBase<SequencedGearshiftTileEntity> {
public SequencedGearshiftPeripheral(SequencedGearshiftTileEntity 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
protected void applySettings(SequencedGearshiftTileEntity te) {
if (te.isComputerControlled(te))
if (te.hasAttachedComputer)
return;
te.run(-1);

View file

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

View file

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

View file

@ -8,6 +8,7 @@ import java.util.function.Function;
import java.util.function.Supplier;
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.ContraptionDisassemblyPacket;
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),
CONTRAPTION_RELOCATION(ContraptionRelocationPacket.class, ContraptionRelocationPacket::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");