Compare commits
27 commits
mc1.18/dev
...
mc1.18/com
Author | SHA1 | Date | |
---|---|---|---|
374848f978 | |||
b2cd60b619 | |||
ee3a079bac | |||
8e1e4e8bd3 | |||
952941e5fc | |||
7f3ca1cfa0 | |||
fac1ebcd3f | |||
3e21996984 | |||
7141c10025 | |||
909484ed5b | |||
31ad3aa671 | |||
574cd93a89 | |||
94e3ed44ad | |||
9afdcaded7 | |||
7d47fdcd06 | |||
56a1210fff | |||
19d283b923 | |||
ab18034b98 | |||
1091f3227c | |||
18bfb216b1 | |||
96dc4db6dc | |||
9a80781401 | |||
d404f07319 | |||
654476d9f3 | |||
1420406ab7 | |||
47b8619d07 | |||
6591c2d46e |
19
build.gradle
19
build.gradle
|
@ -135,6 +135,14 @@ repositories {
|
|||
includeGroup "maven.modrinth"
|
||||
}
|
||||
}
|
||||
maven {
|
||||
// Location of maven for CC: Tweaked
|
||||
name = "squiddev"
|
||||
url = "https://squiddev.cc/maven/"
|
||||
content {
|
||||
includeGroup "org.squiddev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
@ -162,6 +170,11 @@ dependencies {
|
|||
compileOnly fg.deobf("top.theillusivec4.curios:curios-forge:${curios_minecraft_version}-${curios_version}:api")
|
||||
runtimeOnly fg.deobf("top.theillusivec4.curios:curios-forge:${curios_minecraft_version}-${curios_version}")
|
||||
|
||||
if (cc_tweaked_enable.toBoolean()) {
|
||||
compileOnly fg.deobf("org.squiddev:cc-tweaked-${cc_tweaked_minecraft_version}:${cc_tweaked_version}:api")
|
||||
runtimeOnly fg.deobf("org.squiddev:cc-tweaked-${cc_tweaked_minecraft_version}:${cc_tweaked_version}")
|
||||
}
|
||||
|
||||
// implementation fg.deobf("curse.maven:druidcraft-340991:3101903")
|
||||
// implementation fg.deobf("com.ferreusveritas.dynamictrees:DynamicTrees-1.16.5:0.10.0-Beta25")
|
||||
// runtimeOnly fg.deobf("vazkii.arl:AutoRegLib:1.4-35.69")
|
||||
|
@ -178,6 +191,12 @@ dependencies {
|
|||
}
|
||||
}
|
||||
|
||||
sourceSets.main.java {
|
||||
if (!cc_tweaked_enable.toBoolean()) {
|
||||
exclude 'com/simibubi/create/compat/computercraft/implementation/**'
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets.main.resources {
|
||||
srcDir 'src/generated/resources'
|
||||
exclude '.cache/'
|
||||
|
|
|
@ -27,6 +27,10 @@ jei_version = 9.7.0.209
|
|||
curios_minecraft_version = 1.18.2
|
||||
curios_version = 5.0.7.0
|
||||
|
||||
cc_tweaked_enable = true
|
||||
cc_tweaked_minecraft_version = 1.18.2
|
||||
cc_tweaked_version = 1.100.10
|
||||
|
||||
# curseforge information
|
||||
projectId = 328085
|
||||
curse_type = beta
|
||||
|
|
|
@ -1706,6 +1706,7 @@
|
|||
"create.display_source.redstone_power.progress_bar": "Progress Bar",
|
||||
"create.display_source.boiler.not_enough_space": "Not enough space ",
|
||||
"create.display_source.boiler.for_boiler_status": "for Boiler Status",
|
||||
"create.display_source.computer_display_source": "From Computer",
|
||||
|
||||
"create.display_target.line": "Line %1$s",
|
||||
"create.display_target.page": "Page %1$s",
|
||||
|
@ -1748,6 +1749,9 @@
|
|||
"create.contraption.minecart_contraption_too_big": "This Cart Contraption seems too big to pick up",
|
||||
"create.contraption.minecart_contraption_illegal_pickup": "A mystical force is binding this Cart Contraption to the world",
|
||||
|
||||
"create.gui.attached_computer.controlled": "This device is being controlled by a computer",
|
||||
"create.gui.attached_computer.hint": "To use device manually, disconnect all computers and modems",
|
||||
|
||||
|
||||
"_": "->------------------------] Subtitles [------------------------<-",
|
||||
|
||||
|
@ -3027,4 +3031,4 @@
|
|||
|
||||
"_": "Thank you for translating Create!"
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import com.google.gson.Gson;
|
|||
import com.google.gson.GsonBuilder;
|
||||
import com.simibubi.create.api.behaviour.BlockSpoutingBehaviour;
|
||||
import com.simibubi.create.compat.Mods;
|
||||
import com.simibubi.create.compat.computercraft.ComputerCraftProxy;
|
||||
import com.simibubi.create.compat.curios.Curios;
|
||||
import com.simibubi.create.content.CreateItemGroup;
|
||||
import com.simibubi.create.content.contraptions.TorquePropagator;
|
||||
|
@ -126,6 +127,7 @@ public class Create {
|
|||
ContraptionMovementSetting.registerDefaults();
|
||||
AllArmInteractionPointTypes.register();
|
||||
BlockSpoutingBehaviour.registerDefaults();
|
||||
ComputerCraftProxy.register();
|
||||
|
||||
ForgeMod.enableMilkFluid();
|
||||
CopperRegistries.inject();
|
||||
|
|
|
@ -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
|
||||
|
@ -13,7 +16,9 @@ import net.minecraftforge.fml.ModList;
|
|||
public enum Mods {
|
||||
DYNAMICTREES,
|
||||
TCONSTRUCT,
|
||||
CURIOS;
|
||||
CURIOS,
|
||||
|
||||
COMPUTERCRAFT;
|
||||
|
||||
/**
|
||||
* @return a boolean of whether the mod is loaded or not based on mod id
|
||||
|
@ -49,4 +54,8 @@ public enum Mods {
|
|||
toExecute.get().run();
|
||||
}
|
||||
}
|
||||
|
||||
public Block getBlock(String id) {
|
||||
return ForgeRegistries.BLOCKS.getValue(new ResourceLocation(asId(), id));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
package com.simibubi.create.compat.computercraft;
|
||||
|
||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
public class AbstractComputerBehaviour extends TileEntityBehaviour {
|
||||
|
||||
public static final BehaviourType<AbstractComputerBehaviour> TYPE = new BehaviourType<>();
|
||||
|
||||
boolean hasAttachedComputer;
|
||||
|
||||
public AbstractComputerBehaviour(SmartTileEntity te) {
|
||||
super(te);
|
||||
this.hasAttachedComputer = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundTag nbt, boolean clientPacket) {
|
||||
hasAttachedComputer = nbt.getBoolean("HasAttachedComputer");
|
||||
super.read(nbt, clientPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CompoundTag nbt, boolean clientPacket) {
|
||||
nbt.putBoolean("HasAttachedComputer", hasAttachedComputer);
|
||||
super.write(nbt, clientPacket);
|
||||
}
|
||||
|
||||
public <T> boolean isPeripheralCap(Capability<T> cap) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public <T> LazyOptional<T> getPeripheralCapability() {
|
||||
return LazyOptional.empty();
|
||||
}
|
||||
|
||||
public void removePeripheral() {}
|
||||
|
||||
public void setHasAttachedComputer(boolean hasAttachedComputer) {
|
||||
this.hasAttachedComputer = hasAttachedComputer;
|
||||
}
|
||||
|
||||
public boolean hasAttachedComputer() {
|
||||
return hasAttachedComputer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BehaviourType<?> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package com.simibubi.create.compat.computercraft;
|
||||
|
||||
import com.simibubi.create.foundation.networking.TileEntityDataPacket;
|
||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||
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 SmartTileEntity smartTile) {
|
||||
smartTile.getBehaviour(AbstractComputerBehaviour.TYPE)
|
||||
.setHasAttachedComputer(hasAttachedComputer);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.simibubi.create.compat.computercraft;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.simibubi.create.compat.Mods;
|
||||
import com.simibubi.create.compat.computercraft.implementation.ComputerBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||
|
||||
public class ComputerCraftProxy {
|
||||
|
||||
public static void register() {
|
||||
fallbackFactory = FallbackComputerBehaviour::new;
|
||||
Mods.COMPUTERCRAFT.executeIfInstalled(() -> ComputerCraftProxy::registerWithDependency);
|
||||
}
|
||||
|
||||
private static void registerWithDependency() {
|
||||
/* Comment if computercraft.implementation is not in the source set */
|
||||
computerFactory = ComputerBehaviour::new;
|
||||
}
|
||||
|
||||
private static Function<SmartTileEntity, ? extends AbstractComputerBehaviour> fallbackFactory;
|
||||
private static Function<SmartTileEntity, ? extends AbstractComputerBehaviour> computerFactory;
|
||||
|
||||
public static AbstractComputerBehaviour behaviour(SmartTileEntity ste) {
|
||||
if (computerFactory == null)
|
||||
return fallbackFactory.apply(ste);
|
||||
return computerFactory.apply(ste);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
package com.simibubi.create.compat.computercraft;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.simibubi.create.compat.Mods;
|
||||
import com.simibubi.create.foundation.gui.AbstractSimiScreen;
|
||||
import com.simibubi.create.foundation.gui.AllGuiTextures;
|
||||
import com.simibubi.create.foundation.gui.AllIcons;
|
||||
import com.simibubi.create.foundation.gui.element.GuiGameElement;
|
||||
import com.simibubi.create.foundation.gui.widget.AbstractSimiWidget;
|
||||
import com.simibubi.create.foundation.gui.widget.ElementWidget;
|
||||
import com.simibubi.create.foundation.gui.widget.IconButton;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
public class ComputerScreen extends AbstractSimiScreen {
|
||||
|
||||
private final AllGuiTextures background = AllGuiTextures.COMPUTER;
|
||||
|
||||
private final Supplier<Component> displayTitle;
|
||||
private final RenderWindowFunction additional;
|
||||
private final Screen previousScreen;
|
||||
private final Supplier<Boolean> hasAttachedComputer;
|
||||
|
||||
private AbstractSimiWidget computerWidget;
|
||||
private IconButton confirmButton;
|
||||
|
||||
public ComputerScreen(Component title, @Nullable RenderWindowFunction additional, Screen previousScreen, Supplier<Boolean> hasAttachedComputer) {
|
||||
this(title, () -> title, additional, previousScreen, hasAttachedComputer);
|
||||
}
|
||||
|
||||
public ComputerScreen(Component title, Supplier<Component> displayTitle, @Nullable RenderWindowFunction additional, Screen previousScreen, Supplier<Boolean> hasAttachedComputer) {
|
||||
super(title);
|
||||
this.displayTitle = displayTitle;
|
||||
this.additional = additional;
|
||||
this.previousScreen = previousScreen;
|
||||
this.hasAttachedComputer = hasAttachedComputer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (!hasAttachedComputer.get())
|
||||
minecraft.setScreen(previousScreen);
|
||||
|
||||
super.tick();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
setWindowSize(background.width, background.height);
|
||||
super.init();
|
||||
|
||||
int x = guiLeft;
|
||||
int y = guiTop;
|
||||
|
||||
Mods.COMPUTERCRAFT.executeIfInstalled(() -> () -> {
|
||||
computerWidget = new ElementWidget(x + 33, y + 38)
|
||||
.showingElement(GuiGameElement.of(Mods.COMPUTERCRAFT.getBlock("computer_advanced")));
|
||||
computerWidget.getToolTip().add(Lang.translate("gui.attached_computer.hint").component());
|
||||
addRenderableWidget(computerWidget);
|
||||
});
|
||||
|
||||
confirmButton = new IconButton(x + background.width - 33, y + background.height - 24, AllIcons.I_CONFIRM);
|
||||
confirmButton.withCallback(this::onClose);
|
||||
addRenderableWidget(confirmButton);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void renderWindow(PoseStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
int x = guiLeft;
|
||||
int y = guiTop;
|
||||
|
||||
background.render(ms, x, y, this);
|
||||
|
||||
font.draw(ms, displayTitle.get(), x + background.width / 2.0F - font.width(displayTitle.get()) / 2.0F, y + 4, 0x442000);
|
||||
font.drawWordWrap(Lang.translate("gui.attached_computer.controlled").component(), x + 55, y + 32, 111, 0x7A7A7A);
|
||||
|
||||
if (additional != null)
|
||||
additional.render(ms, mouseX, mouseY, partialTicks, x, y, background);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface RenderWindowFunction {
|
||||
|
||||
void render(PoseStack ms, int mouseX, int mouseY, float partialTicks, int guiLeft, int guiTop, AllGuiTextures background);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.simibubi.create.compat.computercraft;
|
||||
|
||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||
|
||||
public class FallbackComputerBehaviour extends AbstractComputerBehaviour {
|
||||
|
||||
public FallbackComputerBehaviour(SmartTileEntity te) {
|
||||
super(te);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAttachedComputer() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package com.simibubi.create.compat.computercraft.implementation;
|
||||
|
||||
import com.simibubi.create.compat.computercraft.AbstractComputerBehaviour;
|
||||
import com.simibubi.create.compat.computercraft.implementation.peripherals.DisplayLinkPeripheral;
|
||||
import com.simibubi.create.compat.computercraft.implementation.peripherals.SequencedGearshiftPeripheral;
|
||||
import com.simibubi.create.compat.computercraft.implementation.peripherals.SpeedControllerPeripheral;
|
||||
import com.simibubi.create.compat.computercraft.implementation.peripherals.SpeedGaugePeripheral;
|
||||
import com.simibubi.create.compat.computercraft.implementation.peripherals.StationPeripheral;
|
||||
import com.simibubi.create.compat.computercraft.implementation.peripherals.StressGaugePeripheral;
|
||||
import com.simibubi.create.content.contraptions.relays.advanced.SpeedControllerTileEntity;
|
||||
import com.simibubi.create.content.contraptions.relays.advanced.sequencer.SequencedGearshiftTileEntity;
|
||||
import com.simibubi.create.content.contraptions.relays.gauge.SpeedGaugeTileEntity;
|
||||
import com.simibubi.create.content.contraptions.relays.gauge.StressGaugeTileEntity;
|
||||
import com.simibubi.create.content.logistics.block.display.DisplayLinkTileEntity;
|
||||
import com.simibubi.create.content.logistics.trains.management.edgePoint.station.StationTileEntity;
|
||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.capabilities.CapabilityManager;
|
||||
import net.minecraftforge.common.capabilities.CapabilityToken;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.common.util.NonNullSupplier;
|
||||
|
||||
public class ComputerBehaviour extends AbstractComputerBehaviour {
|
||||
|
||||
protected static final Capability<IPeripheral> PERIPHERAL_CAPABILITY =
|
||||
CapabilityManager.get(new CapabilityToken<>() {
|
||||
});
|
||||
LazyOptional<IPeripheral> peripheral;
|
||||
NonNullSupplier<IPeripheral> peripheralSupplier;
|
||||
|
||||
public ComputerBehaviour(SmartTileEntity te) {
|
||||
super(te);
|
||||
this.peripheralSupplier = getPeripheralFor(te);
|
||||
}
|
||||
|
||||
public static NonNullSupplier<IPeripheral> getPeripheralFor(SmartTileEntity te) {
|
||||
if (te instanceof SpeedControllerTileEntity scte)
|
||||
return () -> new SpeedControllerPeripheral(scte, scte.targetSpeed);
|
||||
if (te instanceof DisplayLinkTileEntity dlte)
|
||||
return () -> new DisplayLinkPeripheral(dlte);
|
||||
if (te instanceof SequencedGearshiftTileEntity sgte)
|
||||
return () -> new SequencedGearshiftPeripheral(sgte);
|
||||
if (te instanceof SpeedGaugeTileEntity sgte)
|
||||
return () -> new SpeedGaugePeripheral(sgte);
|
||||
if (te instanceof StressGaugeTileEntity sgte)
|
||||
return () -> new StressGaugePeripheral(sgte);
|
||||
if (te instanceof StationTileEntity ste)
|
||||
return () -> new StationPeripheral(ste);
|
||||
|
||||
throw new IllegalArgumentException("No peripheral available for " + te.getType()
|
||||
.getRegistryName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> boolean isPeripheralCap(Capability<T> cap) {
|
||||
return cap == PERIPHERAL_CAPABILITY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> LazyOptional<T> getPeripheralCapability() {
|
||||
if (peripheral == null || !peripheral.isPresent())
|
||||
peripheral = LazyOptional.of(peripheralSupplier);
|
||||
return peripheral.cast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePeripheral() {
|
||||
if (peripheral != null)
|
||||
peripheral.invalidate();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,172 @@
|
|||
package com.simibubi.create.compat.computercraft.implementation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.api.lua.LuaTable;
|
||||
import dan200.computercraft.api.lua.LuaValues;
|
||||
|
||||
public class CreateLuaTable implements LuaTable<Object, Object> {
|
||||
|
||||
private final Map<Object, Object> map;
|
||||
|
||||
public CreateLuaTable() {
|
||||
this.map = new HashMap<>();
|
||||
}
|
||||
|
||||
public CreateLuaTable(Map<?, ?> map) {
|
||||
this.map = new HashMap<>(map);
|
||||
}
|
||||
|
||||
public boolean getBoolean(String key) throws LuaException {
|
||||
Object value = get(key);
|
||||
|
||||
if (!(value instanceof Boolean))
|
||||
throw LuaValues.badField(key, "boolean", LuaValues.getType(value));
|
||||
|
||||
return (Boolean) value;
|
||||
}
|
||||
|
||||
public String getString(String key) throws LuaException {
|
||||
Object value = get(key);
|
||||
|
||||
if (!(value instanceof String))
|
||||
throw LuaValues.badField(key, "string", LuaValues.getType(value));
|
||||
|
||||
return (String) value;
|
||||
}
|
||||
|
||||
public CreateLuaTable getTable(String key) throws LuaException {
|
||||
Object value = get(key);
|
||||
|
||||
if (!(value instanceof Map<?, ?>))
|
||||
throw LuaValues.badField(key, "table", LuaValues.getType(value));
|
||||
|
||||
return new CreateLuaTable((Map<?, ?>) value);
|
||||
}
|
||||
|
||||
public Optional<Boolean> getOptBoolean(String key) throws LuaException {
|
||||
Object value = get(key);
|
||||
|
||||
if (value == null)
|
||||
return Optional.empty();
|
||||
|
||||
if (!(value instanceof Boolean))
|
||||
throw LuaValues.badField(key, "boolean", LuaValues.getType(value));
|
||||
|
||||
return Optional.of((Boolean) value);
|
||||
}
|
||||
|
||||
public Set<String> stringKeySet() throws LuaException {
|
||||
Set<String> stringSet = new HashSet<>();
|
||||
|
||||
for (Object key : keySet()) {
|
||||
if (!(key instanceof String))
|
||||
throw new LuaException("key " + key + " is not string (got " + LuaValues.getType(key) + ")");
|
||||
|
||||
stringSet.add((String) key);
|
||||
}
|
||||
|
||||
return Collections.unmodifiableSet(stringSet);
|
||||
}
|
||||
|
||||
public Collection<CreateLuaTable> tableValues() throws LuaException {
|
||||
List<CreateLuaTable> tables = new ArrayList<>();
|
||||
|
||||
for (int i = 1; i <= size(); i++) {
|
||||
Object value = get((double) i);
|
||||
|
||||
if (!(value instanceof Map<?, ?>))
|
||||
throw new LuaException("value " + value + " is not table (got " + LuaValues.getType(value) + ")");
|
||||
|
||||
tables.add(new CreateLuaTable((Map<?, ?>) value));
|
||||
}
|
||||
|
||||
return Collections.unmodifiableList(tables);
|
||||
}
|
||||
|
||||
public Map<Object, Object> getMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Object put(Object key, Object value) {
|
||||
return map.put(key, value);
|
||||
}
|
||||
|
||||
public void putBoolean(String key, boolean value) {
|
||||
map.put(key, value);
|
||||
}
|
||||
|
||||
public void putDouble(String key, double value) {
|
||||
map.put(key, value);
|
||||
}
|
||||
|
||||
public void putString(String key, String value) {
|
||||
map.put(key, value);
|
||||
}
|
||||
|
||||
public void putTable(String key, CreateLuaTable value) {
|
||||
map.put(key, value);
|
||||
}
|
||||
|
||||
public void putTable(int i, CreateLuaTable value) {
|
||||
map.put(i, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return map.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(Object o) {
|
||||
return map.containsKey(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(Object o) {
|
||||
return map.containsValue(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(Object o) {
|
||||
return map.get(o);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<Object> keySet() {
|
||||
return map.keySet();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<Object> values() {
|
||||
return map.values();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<Entry<Object, Object>> entrySet() {
|
||||
return map.entrySet();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
package com.simibubi.create.compat.computercraft.implementation.peripherals;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.simibubi.create.content.logistics.block.display.DisplayLinkContext;
|
||||
import com.simibubi.create.content.logistics.block.display.DisplayLinkTileEntity;
|
||||
import com.simibubi.create.content.logistics.block.display.target.DisplayTargetStats;
|
||||
|
||||
import dan200.computercraft.api.lua.LuaFunction;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
|
||||
public class DisplayLinkPeripheral extends SyncedPeripheral<DisplayLinkTileEntity> {
|
||||
|
||||
public static final String TAG_KEY = "ComputerSourceList";
|
||||
private final AtomicInteger cursorX = new AtomicInteger();
|
||||
private final AtomicInteger cursorY = new AtomicInteger();
|
||||
|
||||
public DisplayLinkPeripheral(DisplayLinkTileEntity tile) {
|
||||
super(tile);
|
||||
}
|
||||
|
||||
@LuaFunction
|
||||
public final void setCursorPos(int x, int y) {
|
||||
cursorX.set(x - 1);
|
||||
cursorY.set(y - 1);
|
||||
}
|
||||
|
||||
@LuaFunction
|
||||
public final Object[] getCursorPos() {
|
||||
return new Object[] {cursorX.get() + 1, cursorY.get() + 1};
|
||||
}
|
||||
|
||||
@LuaFunction(mainThread = true)
|
||||
public final Object[] getSize() {
|
||||
DisplayTargetStats stats = tile.activeTarget.provideStats(new DisplayLinkContext(tile.getLevel(), tile));
|
||||
return new Object[]{stats.maxRows(), stats.maxColumns()};
|
||||
}
|
||||
|
||||
@LuaFunction
|
||||
public final boolean isColor() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@LuaFunction
|
||||
public final boolean isColour() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@LuaFunction
|
||||
public final void write(String text) {
|
||||
ListTag tag = tile.getSourceConfig().getList(TAG_KEY, Tag.TAG_STRING);
|
||||
|
||||
int x = cursorX.get();
|
||||
int y = cursorY.get();
|
||||
|
||||
for (int i = tag.size(); i <= y; i++) {
|
||||
tag.add(StringTag.valueOf(""));
|
||||
}
|
||||
|
||||
StringBuilder builder = new StringBuilder(tag.getString(y));
|
||||
|
||||
builder.append(" ".repeat(Math.max(0, x - builder.length())));
|
||||
builder.replace(x, x + text.length(), text);
|
||||
|
||||
tag.set(y, StringTag.valueOf(builder.toString()));
|
||||
|
||||
synchronized (tile) {
|
||||
tile.getSourceConfig().put(TAG_KEY, tag);
|
||||
}
|
||||
|
||||
cursorX.set(x + text.length());
|
||||
}
|
||||
|
||||
@LuaFunction
|
||||
public final void clearLine() {
|
||||
ListTag tag = tile.getSourceConfig().getList(TAG_KEY, Tag.TAG_STRING);
|
||||
|
||||
if (tag.size() > cursorY.get())
|
||||
tag.set(cursorY.get(), StringTag.valueOf(""));
|
||||
|
||||
synchronized (tile) {
|
||||
tile.getSourceConfig().put(TAG_KEY, tag);
|
||||
}
|
||||
}
|
||||
|
||||
@LuaFunction
|
||||
public final void clear() {
|
||||
synchronized (tile) {
|
||||
tile.getSourceConfig().put(TAG_KEY, new ListTag());
|
||||
}
|
||||
}
|
||||
|
||||
@LuaFunction(mainThread = true)
|
||||
public final void update() {
|
||||
tile.tickSource();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getType() {
|
||||
return "Create_DisplayLink";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package com.simibubi.create.compat.computercraft.implementation.peripherals;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.simibubi.create.content.contraptions.relays.advanced.sequencer.Instruction;
|
||||
import com.simibubi.create.content.contraptions.relays.advanced.sequencer.InstructionSpeedModifiers;
|
||||
import com.simibubi.create.content.contraptions.relays.advanced.sequencer.SequencedGearshiftTileEntity;
|
||||
import com.simibubi.create.content.contraptions.relays.advanced.sequencer.SequencerInstructions;
|
||||
|
||||
import dan200.computercraft.api.lua.IArguments;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.api.lua.LuaFunction;
|
||||
|
||||
public class SequencedGearshiftPeripheral extends SyncedPeripheral<SequencedGearshiftTileEntity> {
|
||||
|
||||
public SequencedGearshiftPeripheral(SequencedGearshiftTileEntity tile) {
|
||||
super(tile);
|
||||
}
|
||||
|
||||
@LuaFunction(mainThread = true)
|
||||
public final void rotate(IArguments arguments) throws LuaException {
|
||||
runInstruction(arguments, SequencerInstructions.TURN_ANGLE);
|
||||
}
|
||||
|
||||
@LuaFunction(mainThread = true)
|
||||
public final void move(IArguments arguments) throws LuaException {
|
||||
runInstruction(arguments, SequencerInstructions.TURN_DISTANCE);
|
||||
}
|
||||
|
||||
@LuaFunction
|
||||
public final boolean isRunning() {
|
||||
return !this.tile.isIdle();
|
||||
}
|
||||
|
||||
private void runInstruction(IArguments arguments, SequencerInstructions instructionType) throws LuaException {
|
||||
int speedModifier = arguments.count() > 1 ? arguments.getInt(1) : 1;
|
||||
this.tile.getInstructions().clear();
|
||||
|
||||
this.tile.getInstructions().add(new Instruction(
|
||||
instructionType,
|
||||
InstructionSpeedModifiers.getByModifier(speedModifier),
|
||||
Math.abs(arguments.getInt(0))));
|
||||
this.tile.getInstructions().add(new Instruction(SequencerInstructions.END));
|
||||
|
||||
this.tile.run(0);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getType() {
|
||||
return "Create_SequencedGearshift";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.simibubi.create.compat.computercraft.implementation.peripherals;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.simibubi.create.content.contraptions.relays.advanced.SpeedControllerTileEntity;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollValueBehaviour;
|
||||
|
||||
import dan200.computercraft.api.lua.LuaFunction;
|
||||
|
||||
public class SpeedControllerPeripheral extends SyncedPeripheral<SpeedControllerTileEntity> {
|
||||
|
||||
private final ScrollValueBehaviour targetSpeed;
|
||||
|
||||
public SpeedControllerPeripheral(SpeedControllerTileEntity tile, ScrollValueBehaviour targetSpeed) {
|
||||
super(tile);
|
||||
this.targetSpeed = targetSpeed;
|
||||
}
|
||||
|
||||
@LuaFunction(mainThread = true)
|
||||
public final void setTargetSpeed(int speed) {
|
||||
this.targetSpeed.setValue(speed);
|
||||
}
|
||||
|
||||
@LuaFunction
|
||||
public final float getTargetSpeed() {
|
||||
return this.targetSpeed.getValue();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getType() {
|
||||
return "Create_RotationSpeedController";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.simibubi.create.compat.computercraft.implementation.peripherals;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.simibubi.create.content.contraptions.relays.gauge.SpeedGaugeTileEntity;
|
||||
|
||||
import dan200.computercraft.api.lua.LuaFunction;
|
||||
|
||||
public class SpeedGaugePeripheral extends SyncedPeripheral<SpeedGaugeTileEntity> {
|
||||
|
||||
public SpeedGaugePeripheral(SpeedGaugeTileEntity tile) {
|
||||
super(tile);
|
||||
}
|
||||
|
||||
@LuaFunction
|
||||
public final float getSpeed() {
|
||||
return this.tile.getSpeed();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getType() {
|
||||
return "Create_Speedometer";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,269 @@
|
|||
package com.simibubi.create.compat.computercraft.implementation.peripherals;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.simibubi.create.compat.computercraft.implementation.CreateLuaTable;
|
||||
import com.simibubi.create.content.logistics.trains.entity.Train;
|
||||
import com.simibubi.create.content.logistics.trains.management.edgePoint.station.GlobalStation;
|
||||
import com.simibubi.create.content.logistics.trains.management.edgePoint.station.StationTileEntity;
|
||||
import com.simibubi.create.content.logistics.trains.management.edgePoint.station.TrainEditPacket;
|
||||
import com.simibubi.create.content.logistics.trains.management.schedule.Schedule;
|
||||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
import com.simibubi.create.foundation.utility.Components;
|
||||
import com.simibubi.create.foundation.utility.StringHelper;
|
||||
|
||||
import dan200.computercraft.api.lua.IArguments;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.api.lua.LuaFunction;
|
||||
import net.minecraft.nbt.ByteTag;
|
||||
import net.minecraft.nbt.CollectionTag;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.DoubleTag;
|
||||
import net.minecraft.nbt.IntTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.NumericTag;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
|
||||
public class StationPeripheral extends SyncedPeripheral<StationTileEntity> {
|
||||
|
||||
public StationPeripheral(StationTileEntity tile) {
|
||||
super(tile);
|
||||
}
|
||||
|
||||
@LuaFunction(mainThread = true)
|
||||
public final void assemble() throws LuaException {
|
||||
if (!tile.isAssembling())
|
||||
throw new LuaException("station must be in assembly mode");
|
||||
|
||||
tile.assemble(null);
|
||||
|
||||
if (tile.getStation() == null || tile.getStation().getPresentTrain() == null)
|
||||
throw new LuaException("failed to assemble train");
|
||||
|
||||
if (!tile.exitAssemblyMode())
|
||||
throw new LuaException("failed to exit assembly mode");
|
||||
}
|
||||
|
||||
@LuaFunction(mainThread = true)
|
||||
public final void disassemble() throws LuaException {
|
||||
if (tile.isAssembling())
|
||||
throw new LuaException("station must not be in assembly mode");
|
||||
|
||||
getTrainOrThrow();
|
||||
|
||||
if (!tile.enterAssemblyMode(null))
|
||||
throw new LuaException("could not disassemble train");
|
||||
}
|
||||
|
||||
@LuaFunction(mainThread = true)
|
||||
public final void setAssemblyMode(boolean assemblyMode) throws LuaException {
|
||||
if (assemblyMode) {
|
||||
if (!tile.enterAssemblyMode(null))
|
||||
throw new LuaException("failed to enter assembly mode");
|
||||
} else {
|
||||
if (!tile.exitAssemblyMode())
|
||||
throw new LuaException("failed to exit assembly mode");
|
||||
}
|
||||
}
|
||||
|
||||
@LuaFunction
|
||||
public final boolean isInAssemblyMode() {
|
||||
return tile.isAssembling();
|
||||
}
|
||||
|
||||
@LuaFunction
|
||||
public final String getStationName() throws LuaException {
|
||||
GlobalStation station = tile.getStation();
|
||||
if (station == null)
|
||||
throw new LuaException("station is not connected to a track");
|
||||
|
||||
return station.name;
|
||||
}
|
||||
|
||||
@LuaFunction(mainThread = true)
|
||||
public final void setStationName(String name) throws LuaException {
|
||||
if (!tile.updateName(name))
|
||||
throw new LuaException("could not set station name");
|
||||
}
|
||||
|
||||
@LuaFunction
|
||||
public final boolean isTrainPresent() throws LuaException {
|
||||
GlobalStation station = tile.getStation();
|
||||
if (station == null)
|
||||
throw new LuaException("station is not connected to a track");
|
||||
|
||||
return station.getPresentTrain() != null;
|
||||
}
|
||||
|
||||
@LuaFunction
|
||||
public final boolean isTrainImminent() throws LuaException {
|
||||
GlobalStation station = tile.getStation();
|
||||
if (station == null)
|
||||
throw new LuaException("station is not connected to a track");
|
||||
|
||||
return station.getImminentTrain() != null;
|
||||
}
|
||||
|
||||
@LuaFunction
|
||||
public final boolean isTrainEnroute() throws LuaException {
|
||||
GlobalStation station = tile.getStation();
|
||||
if (station == null)
|
||||
throw new LuaException("station is not connected to a track");
|
||||
|
||||
return station.getNearestTrain() != null;
|
||||
}
|
||||
|
||||
@LuaFunction
|
||||
public final String getTrainName() throws LuaException {
|
||||
Train train = getTrainOrThrow();
|
||||
return train.name.getString();
|
||||
}
|
||||
|
||||
@LuaFunction(mainThread = true)
|
||||
public final void setTrainName(String name) throws LuaException {
|
||||
Train train = getTrainOrThrow();
|
||||
train.name = Components.literal(name);
|
||||
AllPackets.channel.send(PacketDistributor.ALL.noArg(), new TrainEditPacket.TrainEditReturnPacket(train.id, name, train.icon.getId()));
|
||||
}
|
||||
|
||||
@LuaFunction
|
||||
public final boolean hasSchedule() throws LuaException {
|
||||
Train train = getTrainOrThrow();
|
||||
return train.runtime.getSchedule() != null;
|
||||
}
|
||||
|
||||
@LuaFunction
|
||||
public final CreateLuaTable getSchedule() throws LuaException {
|
||||
Train train = getTrainOrThrow();
|
||||
|
||||
Schedule schedule = train.runtime.getSchedule();
|
||||
if (schedule == null)
|
||||
throw new LuaException("train doesn't have a schedule");
|
||||
|
||||
return fromCompoundTag(schedule.write());
|
||||
}
|
||||
|
||||
@LuaFunction(mainThread = true)
|
||||
public final void setSchedule(IArguments arguments) throws LuaException {
|
||||
Train train = getTrainOrThrow();
|
||||
Schedule schedule = Schedule.fromTag(toCompoundTag(new CreateLuaTable(arguments.getTable(0))));
|
||||
boolean autoSchedule = train.runtime.getSchedule() == null || train.runtime.isAutoSchedule;
|
||||
train.runtime.setSchedule(schedule, autoSchedule);
|
||||
}
|
||||
|
||||
private @NotNull Train getTrainOrThrow() throws LuaException {
|
||||
GlobalStation station = tile.getStation();
|
||||
if (station == null)
|
||||
throw new LuaException("station is not connected to a track");
|
||||
|
||||
Train train = station.getPresentTrain();
|
||||
if (train == null)
|
||||
throw new LuaException("there is no train present");
|
||||
|
||||
return train;
|
||||
}
|
||||
|
||||
private static @NotNull CreateLuaTable fromCompoundTag(CompoundTag tag) throws LuaException {
|
||||
return (CreateLuaTable) fromNBTTag(null, tag);
|
||||
}
|
||||
|
||||
private static @NotNull Object fromNBTTag(@Nullable String key, Tag tag) throws LuaException {
|
||||
byte type = tag.getId();
|
||||
|
||||
if (type == Tag.TAG_BYTE && key != null && key.equals("Count"))
|
||||
return ((NumericTag) tag).getAsByte();
|
||||
else if (type == Tag.TAG_BYTE)
|
||||
return ((NumericTag) tag).getAsByte() != 0;
|
||||
else if (type == Tag.TAG_SHORT || type == Tag.TAG_INT || type == Tag.TAG_LONG)
|
||||
return ((NumericTag) tag).getAsLong();
|
||||
else if (type == Tag.TAG_FLOAT || type == Tag.TAG_DOUBLE)
|
||||
return ((NumericTag) tag).getAsDouble();
|
||||
else if (type == Tag.TAG_STRING)
|
||||
return tag.getAsString();
|
||||
else if (type == Tag.TAG_LIST || type == Tag.TAG_BYTE_ARRAY || type == Tag.TAG_INT_ARRAY || type == Tag.TAG_LONG_ARRAY) {
|
||||
CreateLuaTable list = new CreateLuaTable();
|
||||
CollectionTag<?> listTag = (CollectionTag<?>) tag;
|
||||
|
||||
for (int i = 0; i < listTag.size(); i++) {
|
||||
list.put(i + 1, fromNBTTag(null, listTag.get(i)));
|
||||
}
|
||||
|
||||
return list;
|
||||
|
||||
} else if (type == Tag.TAG_COMPOUND) {
|
||||
CreateLuaTable table = new CreateLuaTable();
|
||||
CompoundTag compoundTag = (CompoundTag) tag;
|
||||
|
||||
for (String compoundKey : compoundTag.getAllKeys()) {
|
||||
table.put(
|
||||
StringHelper.camelCaseToSnakeCase(compoundKey),
|
||||
fromNBTTag(compoundKey, compoundTag.get(compoundKey))
|
||||
);
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
throw new LuaException("unknown tag type " + tag.getType().getName());
|
||||
}
|
||||
|
||||
private static @NotNull CompoundTag toCompoundTag(CreateLuaTable table) throws LuaException {
|
||||
return (CompoundTag) toNBTTag(null, table.getMap());
|
||||
}
|
||||
|
||||
private static @NotNull Tag toNBTTag(@Nullable String key, Object value) throws LuaException {
|
||||
if (value instanceof Boolean v)
|
||||
return ByteTag.valueOf(v);
|
||||
else if (value instanceof Byte || (key != null && key.equals("count")))
|
||||
return ByteTag.valueOf(((Number) value).byteValue());
|
||||
else if (value instanceof Number v) {
|
||||
// If number is numerical integer
|
||||
if (v.intValue() == v.doubleValue())
|
||||
return IntTag.valueOf(v.intValue());
|
||||
else
|
||||
return DoubleTag.valueOf(v.doubleValue());
|
||||
|
||||
} else if (value instanceof String v)
|
||||
return StringTag.valueOf(v);
|
||||
else if (value instanceof Map<?, ?> v && v.containsKey(1.0)) { // List
|
||||
ListTag list = new ListTag();
|
||||
for (Object o : v.values()) {
|
||||
list.add(toNBTTag(null, o));
|
||||
}
|
||||
|
||||
return list;
|
||||
|
||||
} else if (value instanceof Map<?, ?> v) { // Table/Map
|
||||
CompoundTag compound = new CompoundTag();
|
||||
for (Object objectKey : v.keySet()) {
|
||||
if (!(objectKey instanceof String compoundKey))
|
||||
throw new LuaException("table key is not of type string");
|
||||
|
||||
compound.put(
|
||||
// Items serialize their resource location as "id" and not as "Id".
|
||||
// This check is needed to see if the 'i' should be left lowercase or not.
|
||||
// Items store "count" in the same compound tag, so we can check for its presence to see if this is a serialized item
|
||||
compoundKey.equals("id") && v.containsKey("count") ? "id" : StringHelper.snakeCaseToCamelCase(compoundKey),
|
||||
toNBTTag(compoundKey, v.get(compoundKey))
|
||||
);
|
||||
}
|
||||
|
||||
return compound;
|
||||
}
|
||||
|
||||
throw new LuaException("unknown object type " + value.getClass().getName());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getType() {
|
||||
return "Create_Station";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.simibubi.create.compat.computercraft.implementation.peripherals;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.simibubi.create.content.contraptions.relays.gauge.StressGaugeTileEntity;
|
||||
|
||||
import dan200.computercraft.api.lua.LuaFunction;
|
||||
|
||||
public class StressGaugePeripheral extends SyncedPeripheral<StressGaugeTileEntity> {
|
||||
|
||||
public StressGaugePeripheral(StressGaugeTileEntity tile) {
|
||||
super(tile);
|
||||
}
|
||||
|
||||
@LuaFunction
|
||||
public final float getStress() {
|
||||
return this.tile.getNetworkStress();
|
||||
}
|
||||
|
||||
@LuaFunction
|
||||
public final float getStressCapacity() {
|
||||
return this.tile.getNetworkCapacity();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getType() {
|
||||
return "Create_Stressometer";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.simibubi.create.compat.computercraft.implementation.peripherals;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.compat.computercraft.AttachedComputerPacket;
|
||||
import com.simibubi.create.compat.computercraft.implementation.ComputerBehaviour;
|
||||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
|
||||
public abstract class SyncedPeripheral<T extends SmartTileEntity> implements IPeripheral {
|
||||
|
||||
protected final T tile;
|
||||
private final AtomicInteger computers = new AtomicInteger();
|
||||
|
||||
public SyncedPeripheral(T tile) {
|
||||
this.tile = 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.getBehaviour(ComputerBehaviour.TYPE).setHasAttachedComputer(hasAttachedComputer);
|
||||
AllPackets.channel.send(PacketDistributor.ALL.noArg(), new AttachedComputerPacket(tile.getBlockPos(), hasAttachedComputer));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable IPeripheral other) {
|
||||
return this == other;
|
||||
}
|
||||
|
||||
}
|
|
@ -2,6 +2,11 @@ package com.simibubi.create.content.contraptions.relays.advanced;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.compat.computercraft.AbstractComputerBehaviour;
|
||||
import com.simibubi.create.compat.computercraft.ComputerCraftProxy;
|
||||
import com.simibubi.create.content.contraptions.RotationPropagator;
|
||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.content.contraptions.components.motor.CreativeMotorTileEntity;
|
||||
|
@ -20,11 +25,14 @@ import net.minecraft.core.Direction;
|
|||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
public class SpeedControllerTileEntity extends KineticTileEntity {
|
||||
|
||||
public static final int DEFAULT_SPEED = 16;
|
||||
protected ScrollValueBehaviour targetSpeed;
|
||||
public ScrollValueBehaviour targetSpeed;
|
||||
public AbstractComputerBehaviour computerBehaviour;
|
||||
|
||||
boolean hasBracket;
|
||||
|
||||
|
@ -53,7 +61,8 @@ public class SpeedControllerTileEntity extends KineticTileEntity {
|
|||
targetSpeed.withCallback(i -> this.updateTargetRotation());
|
||||
targetSpeed.withStepFunction(CreativeMotorTileEntity::step);
|
||||
behaviours.add(targetSpeed);
|
||||
|
||||
behaviours.add(computerBehaviour = ComputerCraftProxy.behaviour(this));
|
||||
|
||||
registerAwardables(behaviours, AllAdvancements.SPEED_CONTROLLER);
|
||||
}
|
||||
|
||||
|
@ -63,7 +72,7 @@ public class SpeedControllerTileEntity extends KineticTileEntity {
|
|||
RotationPropagator.handleRemoved(level, worldPosition, this);
|
||||
removeSource();
|
||||
attachKinetics();
|
||||
|
||||
|
||||
if (isCogwheelPresent() && getSpeed() != 0)
|
||||
award(AllAdvancements.SPEED_CONTROLLER);
|
||||
}
|
||||
|
@ -127,6 +136,20 @@ public class SpeedControllerTileEntity extends KineticTileEntity {
|
|||
&& stateAbove.getValue(CogWheelBlock.AXIS).isHorizontal();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
|
||||
if (computerBehaviour.isPeripheralCap(cap))
|
||||
return computerBehaviour.getPeripheralCapability();
|
||||
return super.getCapability(cap, side);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateCaps() {
|
||||
super.invalidateCaps();
|
||||
computerBehaviour.removePeripheral();
|
||||
}
|
||||
|
||||
private class ControllerValueBoxTransform extends ValueBoxTransform.Sided {
|
||||
|
||||
@Override
|
||||
|
|
|
@ -35,6 +35,9 @@ public class ConfigureSequencedGearshiftPacket extends TileEntityConfigurationPa
|
|||
|
||||
@Override
|
||||
protected void applySettings(SequencedGearshiftTileEntity te) {
|
||||
if (te.computerBehaviour.hasAttachedComputer())
|
||||
return;
|
||||
|
||||
te.run(-1);
|
||||
te.instructions = Instruction.deserializeAll(instructions);
|
||||
te.sendData();
|
||||
|
|
|
@ -19,8 +19,12 @@ public class Instruction {
|
|||
}
|
||||
|
||||
public Instruction(SequencerInstructions instruction, int value) {
|
||||
this(instruction, InstructionSpeedModifiers.FORWARD, value);
|
||||
}
|
||||
|
||||
public Instruction(SequencerInstructions instruction, InstructionSpeedModifiers speedModifier, int value) {
|
||||
this.instruction = instruction;
|
||||
speedModifier = InstructionSpeedModifiers.FORWARD;
|
||||
this.speedModifier = speedModifier;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.content.contraptions.relays.advanced.sequencer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.foundation.utility.Components;
|
||||
|
@ -36,4 +37,11 @@ public enum InstructionSpeedModifiers {
|
|||
return options;
|
||||
}
|
||||
|
||||
public static InstructionSpeedModifiers getByModifier(int modifier) {
|
||||
return Arrays.stream(InstructionSpeedModifiers.values())
|
||||
.filter(speedModifier -> speedModifier.value == modifier)
|
||||
.findAny()
|
||||
.orElse(InstructionSpeedModifiers.FORWARD);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.util.Vector;
|
|||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.compat.computercraft.ComputerScreen;
|
||||
import com.simibubi.create.foundation.gui.AbstractSimiScreen;
|
||||
import com.simibubi.create.foundation.gui.AllGuiTextures;
|
||||
import com.simibubi.create.foundation.gui.AllIcons;
|
||||
|
@ -15,7 +16,6 @@ import com.simibubi.create.foundation.networking.AllPackets;
|
|||
import com.simibubi.create.foundation.utility.Components;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
@ -25,22 +25,26 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen {
|
|||
private final ItemStack renderedItem = AllBlocks.SEQUENCED_GEARSHIFT.asStack();
|
||||
private final AllGuiTextures background = AllGuiTextures.SEQUENCER;
|
||||
private IconButton confirmButton;
|
||||
private SequencedGearshiftTileEntity te;
|
||||
|
||||
private ListTag compareTag;
|
||||
private Vector<Instruction> instructions;
|
||||
private BlockPos pos;
|
||||
|
||||
private Vector<Vector<ScrollInput>> inputs;
|
||||
|
||||
public SequencedGearshiftScreen(SequencedGearshiftTileEntity te) {
|
||||
super(Lang.translateDirect("gui.sequenced_gearshift.title"));
|
||||
this.instructions = te.instructions;
|
||||
this.pos = te.getBlockPos();
|
||||
this.te = te;
|
||||
compareTag = Instruction.serializeAll(instructions);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
if (te.computerBehaviour.hasAttachedComputer())
|
||||
minecraft.setScreen(new ComputerScreen(title, this::renderAdditional,
|
||||
this, te.computerBehaviour::hasAttachedComputer));
|
||||
|
||||
setWindowSize(background.width, background.height);
|
||||
setWindowOffset(-20, 0);
|
||||
super.init();
|
||||
|
@ -127,6 +131,15 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen {
|
|||
modifier.setState(instruction.speedModifier.ordinal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
if (te.computerBehaviour.hasAttachedComputer())
|
||||
minecraft.setScreen(new ComputerScreen(title, this::renderAdditional,
|
||||
this, te.computerBehaviour::hasAttachedComputer));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderWindow(PoseStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
int x = guiLeft;
|
||||
|
@ -134,6 +147,13 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen {
|
|||
|
||||
background.render(ms, x, y, this);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
for (int row = 0; row < instructions.capacity(); row++) {
|
||||
AllGuiTextures toDraw = AllGuiTextures.SEQUENCER_EMPTY;
|
||||
int yOffset = toDraw.height * row;
|
||||
|
@ -156,10 +176,13 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen {
|
|||
label(ms, 127, yOffset - 3, instruction.speedModifier.label);
|
||||
}
|
||||
|
||||
renderAdditional(ms, mouseX, mouseY, partialTicks, x, y, background);
|
||||
drawCenteredString(ms, font, title, x + (background.width - 8) / 2, y + 3, 0xFFFFFF);
|
||||
}
|
||||
|
||||
private void renderAdditional(PoseStack ms, int mouseX, int mouseY, float partialTicks, int guiLeft, int guiTop, AllGuiTextures background) {
|
||||
GuiGameElement.of(renderedItem)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(x + background.width + 6, y + background.height - 56, -200)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(guiLeft + background.width + 6, guiTop + background.height - 56, 100)
|
||||
.scale(5)
|
||||
.render(ms);
|
||||
}
|
||||
|
@ -172,7 +195,7 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen {
|
|||
ListTag serialized = Instruction.serializeAll(instructions);
|
||||
if (serialized.equals(compareTag))
|
||||
return;
|
||||
AllPackets.channel.sendToServer(new ConfigureSequencedGearshiftPacket(pos, serialized));
|
||||
AllPackets.channel.sendToServer(new ConfigureSequencedGearshiftPacket(te.getBlockPos(), serialized));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
package com.simibubi.create.content.contraptions.relays.advanced.sequencer;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.compat.computercraft.AbstractComputerBehaviour;
|
||||
import com.simibubi.create.compat.computercraft.ComputerCraftProxy;
|
||||
import com.simibubi.create.content.contraptions.relays.encased.SplitShaftTileEntity;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
|
@ -10,6 +17,8 @@ import net.minecraft.nbt.CompoundTag;
|
|||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
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 {
|
||||
|
||||
|
@ -20,6 +29,8 @@ public class SequencedGearshiftTileEntity extends SplitShaftTileEntity {
|
|||
int timer;
|
||||
boolean poweredPreviously;
|
||||
|
||||
public AbstractComputerBehaviour computerBehaviour;
|
||||
|
||||
public SequencedGearshiftTileEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||
super(type, pos, state);
|
||||
instructions = Instruction.createDefault();
|
||||
|
@ -30,6 +41,12 @@ public class SequencedGearshiftTileEntity extends SplitShaftTileEntity {
|
|||
poweredPreviously = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||
super.addBehaviours(behaviours);
|
||||
behaviours.add(computerBehaviour = ComputerCraftProxy.behaviour(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
@ -72,6 +89,8 @@ public class SequencedGearshiftTileEntity extends SplitShaftTileEntity {
|
|||
}
|
||||
|
||||
public void onRedstoneUpdate(boolean isPowered, boolean isRunning) {
|
||||
if (computerBehaviour.hasAttachedComputer())
|
||||
return;
|
||||
if (!poweredPreviously && isPowered)
|
||||
risingFlank();
|
||||
poweredPreviously = isPowered;
|
||||
|
@ -105,7 +124,7 @@ public class SequencedGearshiftTileEntity extends SplitShaftTileEntity {
|
|||
}
|
||||
}
|
||||
|
||||
protected void run(int instructionIndex) {
|
||||
public void run(int instructionIndex) {
|
||||
Instruction instruction = getInstruction(instructionIndex);
|
||||
if (instruction == null || instruction.instruction == SequencerInstructions.END) {
|
||||
if (getModifier() != 0)
|
||||
|
@ -156,6 +175,20 @@ public class SequencedGearshiftTileEntity extends SplitShaftTileEntity {
|
|||
super.read(compound, clientPacket);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
|
||||
if (computerBehaviour.isPeripheralCap(cap))
|
||||
return computerBehaviour.getPeripheralCapability();
|
||||
return super.getCapability(cap, side);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateCaps() {
|
||||
super.invalidateCaps();
|
||||
computerBehaviour.removePeripheral();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getRotationSpeedModifier(Direction face) {
|
||||
if (isVirtual())
|
||||
|
@ -171,4 +204,8 @@ public class SequencedGearshiftTileEntity extends SplitShaftTileEntity {
|
|||
.getSpeedModifier();
|
||||
}
|
||||
|
||||
public Vector<Instruction> getInstructions() {
|
||||
return this.instructions;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import net.minecraft.network.chat.Component;
|
|||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class GaugeTileEntity extends KineticTileEntity implements IHaveGoggleInformation {
|
||||
public abstract class GaugeTileEntity extends KineticTileEntity implements IHaveGoggleInformation {
|
||||
|
||||
public float dialTarget;
|
||||
public float dialState;
|
||||
|
@ -52,4 +52,5 @@ public class GaugeTileEntity extends KineticTileEntity implements IHaveGoggleInf
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,24 +2,41 @@ package com.simibubi.create.content.contraptions.relays.gauge;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.compat.computercraft.AbstractComputerBehaviour;
|
||||
import com.simibubi.create.compat.computercraft.ComputerCraftProxy;
|
||||
import com.simibubi.create.content.contraptions.base.IRotate.SpeedLevel;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
import com.simibubi.create.foundation.utility.Color;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
public class SpeedGaugeTileEntity extends GaugeTileEntity {
|
||||
|
||||
public AbstractComputerBehaviour computerBehaviour;
|
||||
|
||||
public SpeedGaugeTileEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||
super(type, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||
super.addBehaviours(behaviours);
|
||||
behaviours.add(computerBehaviour = ComputerCraftProxy.behaviour(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpeedChanged(float prevSpeed) {
|
||||
super.onSpeedChanged(prevSpeed);
|
||||
|
@ -62,4 +79,19 @@ public class SpeedGaugeTileEntity extends GaugeTileEntity {
|
|||
.forGoggles(tooltip);
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
|
||||
if (computerBehaviour.isPeripheralCap(cap))
|
||||
return computerBehaviour.getPeripheralCapability();
|
||||
return super.getCapability(cap, side);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateCaps() {
|
||||
super.invalidateCaps();
|
||||
computerBehaviour.removePeripheral();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,11 @@ package com.simibubi.create.content.contraptions.relays.gauge;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.compat.computercraft.AbstractComputerBehaviour;
|
||||
import com.simibubi.create.compat.computercraft.ComputerCraftProxy;
|
||||
import com.simibubi.create.content.contraptions.base.IRotate.StressImpact;
|
||||
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
||||
import com.simibubi.create.foundation.item.ItemDescription;
|
||||
|
@ -13,14 +18,19 @@ import com.simibubi.create.foundation.utility.LangBuilder;
|
|||
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
public class StressGaugeTileEntity extends GaugeTileEntity {
|
||||
|
||||
public AbstractComputerBehaviour computerBehaviour;
|
||||
|
||||
static BlockPos lastSent;
|
||||
|
||||
public StressGaugeTileEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||
|
@ -30,6 +40,7 @@ public class StressGaugeTileEntity extends GaugeTileEntity {
|
|||
@Override
|
||||
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||
super.addBehaviours(behaviours);
|
||||
behaviours.add(computerBehaviour = ComputerCraftProxy.behaviour(this));
|
||||
registerAwardables(behaviours, AllAdvancements.STRESSOMETER, AllAdvancements.STRESSOMETER_MAXED);
|
||||
}
|
||||
|
||||
|
@ -141,4 +152,18 @@ public class StressGaugeTileEntity extends GaugeTileEntity {
|
|||
award(AllAdvancements.STRESSOMETER_MAXED);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
|
||||
if (computerBehaviour.isPeripheralCap(cap))
|
||||
return computerBehaviour.getPeripheralCapability();
|
||||
return super.getCapability(cap, side);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateCaps() {
|
||||
super.invalidateCaps();
|
||||
computerBehaviour.removePeripheral();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ import java.util.Map;
|
|||
import javax.annotation.Nullable;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.compat.Mods;
|
||||
import com.simibubi.create.content.logistics.block.display.source.ComputerDisplaySource;
|
||||
import com.simibubi.create.content.logistics.block.display.source.DeathCounterDisplaySource;
|
||||
import com.simibubi.create.content.logistics.block.display.source.DisplaySource;
|
||||
import com.simibubi.create.content.logistics.block.display.source.EnchantPowerDisplaySource;
|
||||
|
@ -237,5 +239,14 @@ public class AllDisplayBehaviours {
|
|||
assignTile(register(Create.asResource("scoreboard_display_source"), new ScoreboardDisplaySource()), BlockEntityType.COMMAND_BLOCK);
|
||||
assignTile(register(Create.asResource("enchant_power_display_source"), new EnchantPowerDisplaySource()), BlockEntityType.ENCHANTING_TABLE);
|
||||
assignBlock(register(Create.asResource("redstone_power_display_source"), new RedstonePowerDisplaySource()), Blocks.TARGET);
|
||||
|
||||
Mods.COMPUTERCRAFT.executeIfInstalled(() -> () -> {
|
||||
DisplayBehaviour computerDisplaySource = register(Create.asResource("computer_display_source"), new ComputerDisplaySource());
|
||||
|
||||
assignTile(computerDisplaySource, new ResourceLocation(Mods.COMPUTERCRAFT.asId(), "wired_modem_full"));
|
||||
assignTile(computerDisplaySource, new ResourceLocation(Mods.COMPUTERCRAFT.asId(), "computer_normal"));
|
||||
assignTile(computerDisplaySource, new ResourceLocation(Mods.COMPUTERCRAFT.asId(), "computer_advanced"));
|
||||
assignTile(computerDisplaySource, new ResourceLocation(Mods.COMPUTERCRAFT.asId(), "computer_command"));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,11 @@ package com.simibubi.create.content.logistics.block.display;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.simibubi.create.compat.computercraft.AbstractComputerBehaviour;
|
||||
import com.simibubi.create.compat.computercraft.ComputerCraftProxy;
|
||||
import com.simibubi.create.content.logistics.block.display.source.DisplaySource;
|
||||
import com.simibubi.create.content.logistics.block.display.target.DisplayTarget;
|
||||
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
||||
|
@ -18,6 +23,8 @@ import net.minecraft.nbt.NbtUtils;
|
|||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
public class DisplayLinkTileEntity extends SmartTileEntity {
|
||||
|
||||
|
@ -31,9 +38,11 @@ public class DisplayLinkTileEntity extends SmartTileEntity {
|
|||
|
||||
public LerpedFloat glow;
|
||||
private boolean sendPulse;
|
||||
|
||||
|
||||
public int refreshTicks;
|
||||
|
||||
public AbstractComputerBehaviour computerBehaviour;
|
||||
|
||||
public DisplayLinkTileEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||
super(type, pos, state);
|
||||
targetOffset = BlockPos.ZERO;
|
||||
|
@ -44,10 +53,16 @@ public class DisplayLinkTileEntity extends SmartTileEntity {
|
|||
glow.chase(0, 0.5f, Chaser.EXP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||
behaviours.add(computerBehaviour = ComputerCraftProxy.behaviour(this));
|
||||
registerAwardables(behaviours, AllAdvancements.DISPLAY_LINK, AllAdvancements.DISPLAY_BOARD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
|
||||
if (isVirtual()) {
|
||||
glow.tickChaser();
|
||||
return;
|
||||
|
@ -59,9 +74,9 @@ public class DisplayLinkTileEntity extends SmartTileEntity {
|
|||
glow.tickChaser();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
refreshTicks++;
|
||||
if (refreshTicks < activeSource.getPassiveRefreshTicks())
|
||||
if (refreshTicks < activeSource.getPassiveRefreshTicks() || !activeSource.shouldPassiveReset())
|
||||
return;
|
||||
tickSource();
|
||||
}
|
||||
|
@ -114,13 +129,8 @@ public class DisplayLinkTileEntity extends SmartTileEntity {
|
|||
activeSource.transferData(context, activeTarget, targetLine);
|
||||
sendPulse = true;
|
||||
sendData();
|
||||
|
||||
award(AllAdvancements.DISPLAY_LINK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||
registerAwardables(behaviours, AllAdvancements.DISPLAY_LINK, AllAdvancements.DISPLAY_BOARD);
|
||||
award(AllAdvancements.DISPLAY_LINK);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -133,7 +143,7 @@ public class DisplayLinkTileEntity extends SmartTileEntity {
|
|||
protected void write(CompoundTag tag, boolean clientPacket) {
|
||||
super.write(tag, clientPacket);
|
||||
writeGatheredData(tag);
|
||||
if (clientPacket && activeTarget != null)
|
||||
if (clientPacket && activeTarget != null)
|
||||
tag.putString("TargetType", activeTarget.id.toString());
|
||||
if (clientPacket && sendPulse) {
|
||||
sendPulse = false;
|
||||
|
@ -173,6 +183,21 @@ public class DisplayLinkTileEntity extends SmartTileEntity {
|
|||
sourceConfig = data.copy();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
|
||||
if (computerBehaviour.isPeripheralCap(cap))
|
||||
return computerBehaviour.getPeripheralCapability();
|
||||
|
||||
return super.getCapability(cap, side);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateCaps() {
|
||||
super.invalidateCaps();
|
||||
computerBehaviour.removePeripheral();
|
||||
}
|
||||
|
||||
public void target(BlockPos targetPosition) {
|
||||
this.targetOffset = targetPosition.subtract(worldPosition);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package com.simibubi.create.content.logistics.block.display.source;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.content.logistics.block.display.DisplayLinkContext;
|
||||
import com.simibubi.create.content.logistics.block.display.target.DisplayTargetStats;
|
||||
import com.simibubi.create.foundation.utility.Components;
|
||||
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
|
||||
public class ComputerDisplaySource extends DisplaySource {
|
||||
|
||||
@Override
|
||||
public List<MutableComponent> provideText(DisplayLinkContext context, DisplayTargetStats stats) {
|
||||
List<MutableComponent> components = new ArrayList<>();
|
||||
ListTag tag = context.sourceConfig().getList("ComputerSourceList", Tag.TAG_STRING);
|
||||
|
||||
for (int i = 0; i < tag.size(); i++) {
|
||||
components.add(Components.literal(tag.getString(i)));
|
||||
}
|
||||
|
||||
return components;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldPassiveReset() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -49,6 +49,10 @@ public abstract class DisplaySource extends DisplayBehaviour {
|
|||
return 100;
|
||||
};
|
||||
|
||||
public boolean shouldPassiveReset() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected String getTranslationKey() {
|
||||
return id.getPath();
|
||||
}
|
||||
|
|
|
@ -15,8 +15,6 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||
import org.apache.commons.lang3.mutable.MutableObject;
|
||||
|
||||
|
@ -51,7 +49,7 @@ import com.simibubi.create.foundation.utility.Lang;
|
|||
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||
import com.simibubi.create.foundation.utility.Pair;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Direction.Axis;
|
||||
|
@ -67,6 +65,7 @@ import net.minecraft.world.item.ItemStack;
|
|||
import net.minecraft.world.level.Explosion.BlockInteraction;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import net.minecraftforge.common.ForgeHooks;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
|
@ -86,6 +85,7 @@ public class Train {
|
|||
public boolean honk = false;
|
||||
|
||||
public UUID id;
|
||||
@Nullable
|
||||
public UUID owner;
|
||||
public TrackGraph graph;
|
||||
public Navigation navigation;
|
||||
|
@ -124,7 +124,7 @@ public class Train {
|
|||
public int honkPitch;
|
||||
|
||||
public float accumulatedSteamRelease;
|
||||
|
||||
|
||||
int tickOffset;
|
||||
double[] stress;
|
||||
|
||||
|
@ -277,7 +277,7 @@ public class Train {
|
|||
int carriageCount = carriages.size();
|
||||
boolean stalled = false;
|
||||
double maxStress = 0;
|
||||
|
||||
|
||||
if (carriageWaitingForChunks != -1)
|
||||
distance = 0;
|
||||
|
||||
|
@ -317,7 +317,7 @@ public class Train {
|
|||
entries++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (entries > 0)
|
||||
actual = total / entries;
|
||||
|
@ -369,7 +369,7 @@ public class Train {
|
|||
.getLeadingPoint();
|
||||
|
||||
double totalStress = derailed ? 0 : leadingStress + trailingStress;
|
||||
|
||||
|
||||
boolean first = i == 0;
|
||||
boolean last = i == carriageCount - 1;
|
||||
int carriageType = first ? last ? Carriage.BOTH : Carriage.FIRST : last ? Carriage.LAST : Carriage.MIDDLE;
|
||||
|
@ -1087,7 +1087,8 @@ public class Train {
|
|||
public CompoundTag write(DimensionPalette dimensions) {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.putUUID("Id", id);
|
||||
tag.putUUID("Owner", owner);
|
||||
if (owner != null)
|
||||
tag.putUUID("Owner", owner);
|
||||
if (graph != null)
|
||||
tag.putUUID("Graph", graph.id);
|
||||
tag.put("Carriages", NBTHelper.writeCompoundList(carriages, c -> c.write(dimensions)));
|
||||
|
@ -1133,7 +1134,7 @@ public class Train {
|
|||
|
||||
public static Train read(CompoundTag tag, Map<UUID, TrackGraph> trackNetworks, DimensionPalette dimensions) {
|
||||
UUID id = tag.getUUID("Id");
|
||||
UUID owner = tag.getUUID("Owner");
|
||||
UUID owner = tag.contains("Owner") ? tag.getUUID("Owner") : null;
|
||||
UUID graphId = tag.contains("Graph") ? tag.getUUID("Graph") : null;
|
||||
TrackGraph graph = graphId == null ? null : trackNetworks.get(graphId);
|
||||
List<Carriage> carriages = new ArrayList<>();
|
||||
|
|
|
@ -12,7 +12,6 @@ import com.simibubi.create.foundation.networking.SimplePacketBase;
|
|||
import com.simibubi.create.foundation.utility.Couple;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
import com.simibubi.create.foundation.utility.RegisteredObjects;
|
||||
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
@ -37,7 +36,10 @@ public class TrainPacket extends SimplePacketBase {
|
|||
if (!add)
|
||||
return;
|
||||
|
||||
UUID owner = buffer.readUUID();
|
||||
UUID owner = null;
|
||||
if (buffer.readBoolean())
|
||||
owner = buffer.readUUID();
|
||||
|
||||
List<Carriage> carriages = new ArrayList<>();
|
||||
List<Integer> carriageSpacing = new ArrayList<>();
|
||||
|
||||
|
@ -73,7 +75,9 @@ public class TrainPacket extends SimplePacketBase {
|
|||
if (!add)
|
||||
return;
|
||||
|
||||
buffer.writeUUID(train.owner);
|
||||
buffer.writeBoolean(train.owner != null);
|
||||
if (train.owner != null)
|
||||
buffer.writeUUID(train.owner);
|
||||
|
||||
buffer.writeVarInt(train.carriages.size());
|
||||
for (Carriage carriage : train.carriages) {
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.jozufozu.flywheel.core.PartialModel;
|
|||
import com.jozufozu.flywheel.util.transform.TransformStack;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.compat.computercraft.ComputerScreen;
|
||||
import com.simibubi.create.content.logistics.trains.entity.Carriage;
|
||||
import com.simibubi.create.content.logistics.trains.entity.Train;
|
||||
import com.simibubi.create.content.logistics.trains.entity.TrainIconType;
|
||||
|
@ -15,6 +16,7 @@ import com.simibubi.create.foundation.gui.AllGuiTextures;
|
|||
import com.simibubi.create.foundation.gui.AllIcons;
|
||||
import com.simibubi.create.foundation.gui.element.GuiGameElement;
|
||||
import com.simibubi.create.foundation.gui.widget.IconButton;
|
||||
import com.simibubi.create.foundation.utility.Components;
|
||||
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
|
||||
|
@ -39,6 +41,10 @@ public abstract class AbstractStationScreen extends AbstractSimiScreen {
|
|||
|
||||
@Override
|
||||
protected void init() {
|
||||
if (te.computerBehaviour.hasAttachedComputer())
|
||||
minecraft.setScreen(new ComputerScreen(title, () -> Components.literal(station.name),
|
||||
this::renderAdditional, this, te.computerBehaviour::hasAttachedComputer));
|
||||
|
||||
setWindowSize(background.width, background.height);
|
||||
super.init();
|
||||
clearWidgets();
|
||||
|
@ -71,17 +77,29 @@ public abstract class AbstractStationScreen extends AbstractSimiScreen {
|
|||
return w;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
if (te.computerBehaviour.hasAttachedComputer())
|
||||
minecraft.setScreen(new ComputerScreen(title, () -> Components.literal(station.name),
|
||||
this::renderAdditional, this, te.computerBehaviour::hasAttachedComputer));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderWindow(PoseStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
int x = guiLeft;
|
||||
int y = guiTop;
|
||||
|
||||
background.render(ms, x, y, this);
|
||||
renderAdditional(ms, mouseX, mouseY, partialTicks, x, y, background);
|
||||
}
|
||||
|
||||
private void renderAdditional(PoseStack ms, int mouseX, int mouseY, float partialTicks, int guiLeft, int guiTop, AllGuiTextures background) {
|
||||
ms.pushPose();
|
||||
TransformStack msr = TransformStack.cast(ms);
|
||||
msr.pushPose()
|
||||
.translate(x + background.width + 4, y + background.height + 4, 100)
|
||||
.translate(guiLeft + background.width + 4, guiTop + background.height + 4, 100)
|
||||
.scale(40)
|
||||
.rotateX(-22)
|
||||
.rotateY(63);
|
||||
|
|
|
@ -1,19 +1,11 @@
|
|||
package com.simibubi.create.content.logistics.trains.management.edgePoint.station;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.logistics.trains.GraphLocation;
|
||||
import com.simibubi.create.content.logistics.trains.entity.Train;
|
||||
import com.simibubi.create.foundation.networking.TileEntityConfigurationPacket;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class StationEditPacket extends TileEntityConfigurationPacket<StationTileEntity> {
|
||||
|
||||
|
@ -92,18 +84,12 @@ public class StationEditPacket extends TileEntityConfigurationPacket<StationTile
|
|||
BlockState blockState = level.getBlockState(blockPos);
|
||||
|
||||
if (dropSchedule) {
|
||||
scheduleDropRequested(player, te);
|
||||
te.dropSchedule(player);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!name.isBlank()) {
|
||||
GlobalStation station = te.getStation();
|
||||
GraphLocation graphLocation = te.edgePoint.determineGraphLocation();
|
||||
if (station != null && graphLocation != null) {
|
||||
station.name = name;
|
||||
Create.RAILWAYS.sync.pointAdded(graphLocation.graph, station);
|
||||
Create.RAILWAYS.markTracksDirty();
|
||||
}
|
||||
te.updateName(name);
|
||||
}
|
||||
|
||||
if (!(blockState.getBlock() instanceof StationBlock))
|
||||
|
@ -120,89 +106,17 @@ public class StationEditPacket extends TileEntityConfigurationPacket<StationTile
|
|||
assemblyComplete = te.getStation() != null && te.getStation()
|
||||
.getPresentTrain() != null;
|
||||
} else {
|
||||
if (disassembleAndEnterMode(player, te))
|
||||
if (te.tryDisassembleTrain(player) && te.tryEnterAssemblyMode())
|
||||
te.refreshAssemblyInfo();
|
||||
}
|
||||
if (!assemblyComplete)
|
||||
return;
|
||||
}
|
||||
if (isAssemblyMode == assemblyMode)
|
||||
return;
|
||||
|
||||
BlockState newState = blockState.cycle(StationBlock.ASSEMBLING);
|
||||
Boolean nowAssembling = newState.getValue(StationBlock.ASSEMBLING);
|
||||
|
||||
if (nowAssembling) {
|
||||
if (!disassembleAndEnterMode(player, te))
|
||||
return;
|
||||
} else {
|
||||
te.cancelAssembly();
|
||||
}
|
||||
|
||||
level.setBlock(blockPos, newState, 3);
|
||||
te.refreshBlockState();
|
||||
|
||||
if (nowAssembling)
|
||||
te.refreshAssemblyInfo();
|
||||
|
||||
GlobalStation station = te.getStation();
|
||||
GraphLocation graphLocation = te.edgePoint.determineGraphLocation();
|
||||
if (station != null && graphLocation != null) {
|
||||
station.assembling = nowAssembling;
|
||||
Create.RAILWAYS.sync.pointAdded(graphLocation.graph, station);
|
||||
Create.RAILWAYS.markTracksDirty();
|
||||
|
||||
if (nowAssembling)
|
||||
for (Train train : Create.RAILWAYS.sided(level).trains.values()) {
|
||||
if (train.navigation.destination != station)
|
||||
continue;
|
||||
GlobalStation preferredDestination = train.runtime.startCurrentInstruction();
|
||||
if (preferredDestination != null)
|
||||
train.navigation.startNavigation(preferredDestination, Double.MAX_VALUE, false);
|
||||
else
|
||||
train.navigation.startNavigation(station, Double.MAX_VALUE, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void scheduleDropRequested(ServerPlayer sender, StationTileEntity te) {
|
||||
GlobalStation station = te.getStation();
|
||||
if (station == null)
|
||||
return;
|
||||
Train train = station.getPresentTrain();
|
||||
if (train == null)
|
||||
return;
|
||||
ItemStack schedule = train.runtime.returnSchedule();
|
||||
dropSchedule(sender, te, schedule);
|
||||
}
|
||||
|
||||
private boolean disassembleAndEnterMode(ServerPlayer sender, StationTileEntity te) {
|
||||
GlobalStation station = te.getStation();
|
||||
if (station != null) {
|
||||
Train train = station.getPresentTrain();
|
||||
BlockPos trackPosition = te.edgePoint.getGlobalPosition();
|
||||
ItemStack schedule = train == null ? ItemStack.EMPTY : train.runtime.returnSchedule();
|
||||
if (train != null && !train.disassemble(te.getAssemblyDirection(), trackPosition.above()))
|
||||
return false;
|
||||
dropSchedule(sender, te, schedule);
|
||||
}
|
||||
return te.tryEnterAssemblyMode();
|
||||
}
|
||||
|
||||
private void dropSchedule(ServerPlayer sender, StationTileEntity te, ItemStack schedule) {
|
||||
if (schedule.isEmpty())
|
||||
return;
|
||||
if (sender.getMainHandItem()
|
||||
.isEmpty()) {
|
||||
sender.getInventory()
|
||||
.placeItemBackInInventory(schedule);
|
||||
return;
|
||||
}
|
||||
Vec3 v = VecHelper.getCenterOf(te.getBlockPos());
|
||||
ItemEntity itemEntity = new ItemEntity(te.getLevel(), v.x, v.y, v.z, schedule);
|
||||
itemEntity.setDeltaMovement(Vec3.ZERO);
|
||||
te.getLevel()
|
||||
.addFreshEntity(itemEntity);
|
||||
if (assemblyMode)
|
||||
te.enterAssemblyMode(player);
|
||||
else
|
||||
te.exitAssemblyMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -343,6 +343,8 @@ public class StationScreen extends AbstractStationScreen {
|
|||
@Override
|
||||
public void removed() {
|
||||
super.removed();
|
||||
if (nameBox == null || trainNameBox == null)
|
||||
return;
|
||||
AllPackets.channel
|
||||
.sendToServer(StationEditPacket.configure(te.getBlockPos(), switchingToAssemblyMode, nameBox.getValue()));
|
||||
Train train = displayedTrain.get();
|
||||
|
|
|
@ -9,18 +9,24 @@ import java.util.Map;
|
|||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.AllSoundEvents;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.compat.computercraft.AbstractComputerBehaviour;
|
||||
import com.simibubi.create.compat.computercraft.ComputerCraftProxy;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
||||
import com.simibubi.create.content.logistics.block.depot.DepotBehaviour;
|
||||
import com.simibubi.create.content.logistics.block.display.DisplayLinkBlock;
|
||||
import com.simibubi.create.content.logistics.trains.GraphLocation;
|
||||
import com.simibubi.create.content.logistics.trains.IBogeyBlock;
|
||||
import com.simibubi.create.content.logistics.trains.ITrackBlock;
|
||||
import com.simibubi.create.content.logistics.trains.TrackEdge;
|
||||
|
@ -47,6 +53,7 @@ import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
|||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.foundation.utility.WorldAttached;
|
||||
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
|
||||
import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser;
|
||||
|
@ -60,9 +67,11 @@ import net.minecraft.core.particles.ParticleTypes;
|
|||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.SoundType;
|
||||
|
@ -85,6 +94,7 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable
|
|||
protected int failedCarriageIndex;
|
||||
protected AssemblyException lastException;
|
||||
protected DepotBehaviour depotBehaviour;
|
||||
public AbstractComputerBehaviour computerBehaviour;
|
||||
|
||||
// for display
|
||||
UUID imminentTrain;
|
||||
|
@ -116,6 +126,7 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable
|
|||
depotBehaviour.addSubBehaviours(behaviours);
|
||||
registerAwardables(behaviours, AllAdvancements.CONTRAPTION_ACTORS, AllAdvancements.TRAIN,
|
||||
AllAdvancements.LONG_TRAIN, AllAdvancements.CONDUCTOR);
|
||||
behaviours.add(computerBehaviour = ComputerCraftProxy.behaviour(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -314,6 +325,63 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable
|
|||
return true;
|
||||
}
|
||||
|
||||
public boolean enterAssemblyMode(@Nullable ServerPlayer sender) {
|
||||
if (isAssembling())
|
||||
return false;
|
||||
|
||||
tryDisassembleTrain(sender);
|
||||
if (!tryEnterAssemblyMode())
|
||||
return false;
|
||||
|
||||
BlockState newState = getBlockState().setValue(StationBlock.ASSEMBLING, true);
|
||||
level.setBlock(getBlockPos(), newState, 3);
|
||||
refreshBlockState();
|
||||
refreshAssemblyInfo();
|
||||
|
||||
updateStationState(station -> station.assembling = true);
|
||||
GlobalStation station = getStation();
|
||||
if (station != null) {
|
||||
for (Train train : Create.RAILWAYS.sided(level).trains.values()) {
|
||||
if (train.navigation.destination != station)
|
||||
continue;
|
||||
|
||||
GlobalStation preferredDestination = train.runtime.startCurrentInstruction();
|
||||
train.navigation.startNavigation(preferredDestination != null ? preferredDestination : station, Double.MAX_VALUE, false);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean exitAssemblyMode() {
|
||||
if (!isAssembling())
|
||||
return false;
|
||||
|
||||
cancelAssembly();
|
||||
BlockState newState = getBlockState().setValue(StationBlock.ASSEMBLING, false);
|
||||
level.setBlock(getBlockPos(), newState, 3);
|
||||
refreshBlockState();
|
||||
|
||||
return updateStationState(station -> station.assembling = false);
|
||||
}
|
||||
|
||||
public boolean tryDisassembleTrain(@Nullable ServerPlayer sender) {
|
||||
GlobalStation station = getStation();
|
||||
if (station == null)
|
||||
return false;
|
||||
|
||||
Train train = station.getPresentTrain();
|
||||
if (train == null)
|
||||
return false;
|
||||
|
||||
BlockPos trackPosition = edgePoint.getGlobalPosition();
|
||||
if (!train.disassemble(getAssemblyDirection(), trackPosition.above()))
|
||||
return false;
|
||||
|
||||
dropSchedule(sender);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isAssembling() {
|
||||
BlockState state = getBlockState();
|
||||
return state.hasProperty(StationBlock.ASSEMBLING) && state.getValue(StationBlock.ASSEMBLING);
|
||||
|
@ -341,6 +409,42 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable
|
|||
return true;
|
||||
}
|
||||
|
||||
public void dropSchedule(@Nullable ServerPlayer sender) {
|
||||
GlobalStation station = getStation();
|
||||
if (station == null)
|
||||
return;
|
||||
|
||||
Train train = station.getPresentTrain();
|
||||
if (train == null)
|
||||
return;
|
||||
|
||||
ItemStack schedule = train.runtime.returnSchedule();
|
||||
if (schedule.isEmpty())
|
||||
return;
|
||||
if (sender != null && sender.getMainHandItem().isEmpty()) {
|
||||
sender.getInventory()
|
||||
.placeItemBackInInventory(schedule);
|
||||
return;
|
||||
}
|
||||
|
||||
Vec3 v = VecHelper.getCenterOf(getBlockPos());
|
||||
ItemEntity itemEntity = new ItemEntity(getLevel(), v.x, v.y, v.z, schedule);
|
||||
itemEntity.setDeltaMovement(Vec3.ZERO);
|
||||
getLevel().addFreshEntity(itemEntity);
|
||||
}
|
||||
|
||||
private boolean updateStationState(Consumer<GlobalStation> updateState) {
|
||||
GlobalStation station = getStation();
|
||||
GraphLocation graphLocation = edgePoint.determineGraphLocation();
|
||||
if (station == null || graphLocation == null)
|
||||
return false;
|
||||
|
||||
updateState.accept(station);
|
||||
Create.RAILWAYS.sync.pointAdded(graphLocation.graph, station);
|
||||
Create.RAILWAYS.markTracksDirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void refreshAssemblyInfo() {
|
||||
if (!edgePoint.hasValidTrack())
|
||||
return;
|
||||
|
@ -409,6 +513,14 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable
|
|||
map.put(worldPosition, BoundingBox.fromCorners(startPosition, trackEnd));
|
||||
}
|
||||
|
||||
public boolean updateName(String name) {
|
||||
if (!updateStationState(station -> station.name = name))
|
||||
return false;
|
||||
notifyUpdate();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isValidBogeyOffset(int i) {
|
||||
if ((i < 3 || bogeyCount == 0) && i != 0)
|
||||
return false;
|
||||
|
@ -699,12 +811,20 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
|
||||
public <T> @NotNull LazyOptional<T> getCapability(@NotNull Capability<T> cap, Direction side) {
|
||||
if (isItemHandlerCap(cap))
|
||||
return depotBehaviour.getItemCapability(cap, side);
|
||||
if (computerBehaviour.isPeripheralCap(cap))
|
||||
return computerBehaviour.getPeripheralCapability();
|
||||
return super.getCapability(cap, side);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateCaps() {
|
||||
super.invalidateCaps();
|
||||
computerBehaviour.removePeripheral();
|
||||
}
|
||||
|
||||
private void applyAutoSchedule() {
|
||||
ItemStack stack = getAutoSchedule();
|
||||
if (!AllItems.SCHEDULE.isIn(stack))
|
||||
|
|
|
@ -25,6 +25,8 @@ public interface IScheduleInput {
|
|||
|
||||
public abstract CompoundTag getData();
|
||||
|
||||
public abstract void setData(CompoundTag data);
|
||||
|
||||
public default int slotsTargeted() {
|
||||
return 0;
|
||||
}
|
||||
|
@ -40,7 +42,7 @@ public interface IScheduleInput {
|
|||
}
|
||||
|
||||
public default void setItem(int slot, ItemStack stack) {}
|
||||
|
||||
|
||||
public default ItemStack getItem(int slot) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
@ -58,4 +60,4 @@ public interface IScheduleInput {
|
|||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,33 +3,39 @@ package com.simibubi.create.content.logistics.trains.management.schedule;
|
|||
import net.minecraft.nbt.CompoundTag;
|
||||
|
||||
public abstract class ScheduleDataEntry implements IScheduleInput {
|
||||
|
||||
|
||||
protected CompoundTag data;
|
||||
|
||||
|
||||
public ScheduleDataEntry() {
|
||||
data = new CompoundTag();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CompoundTag getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setData(CompoundTag data) {
|
||||
this.data = data;
|
||||
readAdditional(data);
|
||||
}
|
||||
|
||||
protected void writeAdditional(CompoundTag tag) {};
|
||||
|
||||
protected void readAdditional(CompoundTag tag) {};
|
||||
|
||||
|
||||
protected <T> T enumData(String key, Class<T> enumClass) {
|
||||
T[] enumConstants = enumClass.getEnumConstants();
|
||||
return enumConstants[data.getInt(key) % enumConstants.length];
|
||||
}
|
||||
|
||||
|
||||
protected String textData(String key) {
|
||||
return data.getString(key);
|
||||
}
|
||||
|
||||
|
||||
protected int intData(String key) {
|
||||
return data.getInt(key);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -68,7 +68,8 @@ public class FluidThresholdCondition extends CargoThresholdCondition {
|
|||
@Override
|
||||
protected void readAdditional(CompoundTag tag) {
|
||||
super.readAdditional(tag);
|
||||
compareStack = ItemStack.of(tag.getCompound("Bucket"));
|
||||
if (tag.contains("Bucket"))
|
||||
compareStack = ItemStack.of(tag.getCompound("Bucket"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -139,4 +140,4 @@ public class FluidThresholdCondition extends CargoThresholdCondition {
|
|||
Math.max(0, getThreshold() + offset), Lang.translateDirect("schedule.condition.threshold.buckets"));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,7 +69,8 @@ public class ItemThresholdCondition extends CargoThresholdCondition {
|
|||
@Override
|
||||
protected void readAdditional(CompoundTag tag) {
|
||||
super.readAdditional(tag);
|
||||
stack = ItemStack.of(tag.getCompound("Item"));
|
||||
if (tag.contains("Item"))
|
||||
stack = ItemStack.of(tag.getCompound("Item"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -131,4 +132,4 @@ public class ItemThresholdCondition extends CargoThresholdCondition {
|
|||
Math.max(0, getThreshold() + offset),
|
||||
Lang.translateDirect("schedule.condition.threshold." + (inStacks() ? "stacks" : "items")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,7 +107,8 @@ public class RedstoneLinkCondition extends ScheduleWaitCondition {
|
|||
|
||||
@Override
|
||||
protected void readAdditional(CompoundTag tag) {
|
||||
freq = Couple.deserializeEach(tag.getList("Frequency", Tag.TAG_COMPOUND), c -> Frequency.of(ItemStack.of(c)));
|
||||
if (tag.contains("Frequency"))
|
||||
freq = Couple.deserializeEach(tag.getList("Frequency", Tag.TAG_COMPOUND), c -> Frequency.of(ItemStack.of(c)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -118,7 +119,7 @@ public class RedstoneLinkCondition extends ScheduleWaitCondition {
|
|||
.titled(Lang.translateDirect("schedule.condition.redstone_link.frequency_state")),
|
||||
"Inverted");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public MutableComponent getWaitingStatus(Level level, Train train, CompoundTag tag) {
|
||||
return Lang.translateDirect("schedule.condition.redstone_link.status");
|
||||
|
|
|
@ -16,16 +16,17 @@ import net.minecraft.world.level.Level;
|
|||
public abstract class ScheduleWaitCondition extends ScheduleDataEntry {
|
||||
|
||||
public abstract boolean tickCompletion(Level level, Train train, CompoundTag context);
|
||||
|
||||
|
||||
protected void requestStatusToUpdate(CompoundTag context) {
|
||||
context.putInt("StatusVersion", context.getInt("StatusVersion") + 1);
|
||||
}
|
||||
|
||||
|
||||
public final CompoundTag write() {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
CompoundTag dataCopy = data.copy();
|
||||
writeAdditional(dataCopy);
|
||||
tag.putString("Id", getId().toString());
|
||||
tag.put("Data", data.copy());
|
||||
writeAdditional(tag);
|
||||
tag.put("Data", dataCopy);
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
@ -43,11 +44,14 @@ public abstract class ScheduleWaitCondition extends ScheduleDataEntry {
|
|||
}
|
||||
|
||||
ScheduleWaitCondition condition = supplier.get();
|
||||
condition.data = tag.getCompound("Data");
|
||||
// Left around for migration purposes. Data added in writeAdditional has moved into the "Data" tag
|
||||
condition.readAdditional(tag);
|
||||
CompoundTag data = tag.getCompound("Data");
|
||||
condition.readAdditional(data);
|
||||
condition.data = data;
|
||||
return condition;
|
||||
}
|
||||
|
||||
public abstract MutableComponent getWaitingStatus(Level level, Train train, CompoundTag tag);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,9 +16,10 @@ public abstract class ScheduleInstruction extends ScheduleDataEntry {
|
|||
|
||||
public final CompoundTag write() {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
CompoundTag dataCopy = data.copy();
|
||||
writeAdditional(dataCopy);
|
||||
tag.putString("Id", getId().toString());
|
||||
tag.put("Data", data.copy());
|
||||
writeAdditional(tag);
|
||||
tag.put("Data", dataCopy);
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
@ -36,9 +37,12 @@ public abstract class ScheduleInstruction extends ScheduleDataEntry {
|
|||
}
|
||||
|
||||
ScheduleInstruction scheduleDestination = supplier.get();
|
||||
scheduleDestination.data = tag.getCompound("Data");
|
||||
// Left around for migration purposes. Data added in writeAdditional has moved into the "Data" tag
|
||||
scheduleDestination.readAdditional(tag);
|
||||
CompoundTag data = tag.getCompound("Data");
|
||||
scheduleDestination.readAdditional(data);
|
||||
scheduleDestination.data = data;
|
||||
return scheduleDestination;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -163,7 +163,7 @@ public enum AllGuiTextures implements ScreenElement {
|
|||
|
||||
SPEECH_TOOLTIP_BACKGROUND("widgets", 0, 24, 8, 8),
|
||||
SPEECH_TOOLTIP_COLOR("widgets", 8, 24, 8, 8),
|
||||
|
||||
|
||||
TRAIN_HUD_SPEED_BG("widgets", 0, 190, 182, 5),
|
||||
TRAIN_HUD_SPEED("widgets", 0, 185, 182, 5),
|
||||
TRAIN_HUD_THROTTLE("widgets", 0, 195, 182, 5),
|
||||
|
@ -175,7 +175,10 @@ public enum AllGuiTextures implements ScreenElement {
|
|||
TRAIN_PROMPT("widgets", 0, 230, 256, 16),
|
||||
|
||||
// PlacementIndicator
|
||||
PLACEMENT_INDICATOR_SHEET("placement_indicator", 0, 0, 16, 256);
|
||||
PLACEMENT_INDICATOR_SHEET("placement_indicator", 0, 0, 16, 256),
|
||||
|
||||
// ComputerCraft
|
||||
COMPUTER("computer", 200, 102);
|
||||
|
||||
;
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.simibubi.create.foundation.ponder.content;
|
|||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.compat.Mods;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.ponder.PonderRegistrationHelper;
|
||||
import com.simibubi.create.foundation.ponder.PonderRegistry;
|
||||
|
@ -20,8 +21,11 @@ import com.simibubi.create.foundation.ponder.content.trains.TrainScenes;
|
|||
import com.simibubi.create.foundation.ponder.content.trains.TrainSignalScenes;
|
||||
import com.simibubi.create.foundation.ponder.content.trains.TrainStationScenes;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.DyeColor;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
public class PonderIndex {
|
||||
|
||||
|
@ -548,6 +552,12 @@ public class PonderIndex {
|
|||
.add(Blocks.COMMAND_BLOCK)
|
||||
.add(Blocks.TARGET);
|
||||
|
||||
Mods.COMPUTERCRAFT.executeIfInstalled(() -> () -> {
|
||||
Block computer = ForgeRegistries.BLOCKS.getValue(new ResourceLocation(Mods.COMPUTERCRAFT.asId(), "computer_advanced"));
|
||||
if (computer != null)
|
||||
PonderRegistry.TAGS.forTag(PonderTag.DISPLAY_SOURCES).add(computer);
|
||||
});
|
||||
|
||||
PonderRegistry.TAGS.forTag(PonderTag.DISPLAY_TARGETS)
|
||||
.add(AllBlocks.ORANGE_NIXIE_TUBE)
|
||||
.add(AllBlocks.DISPLAY_BOARD)
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package com.simibubi.create.foundation.utility;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class StringHelper {
|
||||
|
||||
public static String snakeCaseToCamelCase(String text) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(text.substring(0, 1).toUpperCase(Locale.ROOT));
|
||||
|
||||
for (int i = 1; i < text.length(); i++) {
|
||||
int j = text.indexOf('_', i);
|
||||
|
||||
if (j == -1) {
|
||||
builder.append(text.substring(i));
|
||||
break;
|
||||
}
|
||||
|
||||
builder.append(text.substring(i, j).toLowerCase(Locale.ROOT));
|
||||
builder.append(text.substring(j + 1, j + 2).toUpperCase(Locale.ROOT));
|
||||
|
||||
i = j + 1;
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static String camelCaseToSnakeCase(String text) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
for (char c : text.toCharArray()) {
|
||||
if (Character.isUpperCase(c)) {
|
||||
builder.append('_');
|
||||
builder.append(Character.toLowerCase(c));
|
||||
} else {
|
||||
builder.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
if (builder.length() > 0 && builder.charAt(0) == '_')
|
||||
builder.deleteCharAt(0);
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
BIN
src/main/resources/assets/create/textures/gui/computer.png
Normal file
BIN
src/main/resources/assets/create/textures/gui/computer.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1,016 B |
88
wiki/Lua-Display-Link.md
Normal file
88
wiki/Lua-Display-Link.md
Normal file
|
@ -0,0 +1,88 @@
|
|||
| Method | Description |
|
||||
|---------------------------------------|------------------------------------------------------|
|
||||
| [`setCursorPos(x, y)`](#setCursorPos) | Sets the cursor position |
|
||||
| [`getCursorPos()`](#getCursorPos) | Gets the current cursor position |
|
||||
| [`getSize()`](#getSize) | Gets the display size of the connected target |
|
||||
| [`isColor()`](#isColor) | Whether the connected display target supports color |
|
||||
| [`isColour()`](#isColour) | Whether the connected display target supports colour |
|
||||
| [`write(text)`](#writetext) | Writes text at the current cursor position |
|
||||
| [`clearLine()`](#clearLine) | Clears the line at the current cursor position |
|
||||
| [`clear()`](#clear) | Clears the whole display |
|
||||
| [`update()`](#update) | Pushes an update to the display target |
|
||||
|
||||
---
|
||||
### `setCursorPos(x, y)`
|
||||
Sets the cursor position. Can be outside the bounds of the connected display.
|
||||
|
||||
**Parameters**
|
||||
- _x:_ `number` The cursor x position.
|
||||
- _y:_ `number` The cursor y position.
|
||||
|
||||
---
|
||||
### `getCursorPos()`
|
||||
Gets the current cursor position.
|
||||
|
||||
**Returns**
|
||||
- `number` The cursor x position.
|
||||
- `number` The cursor y position.
|
||||
|
||||
---
|
||||
### `getSize()`
|
||||
Gets the size of the connected display target.
|
||||
|
||||
**Returns**
|
||||
- `number` The width of the display.
|
||||
- `number` The height of the display.
|
||||
|
||||
---
|
||||
### `isColor()`
|
||||
Checks whether the connected display target supports color.
|
||||
|
||||
**Returns**
|
||||
- `boolean` Whether the display supports color.
|
||||
|
||||
---
|
||||
### `isColour()`
|
||||
Checks whether the connected display target supports colour.
|
||||
|
||||
**Returns**
|
||||
- `boolean` Whether the display supports colour.
|
||||
|
||||
---
|
||||
### `write(text)`
|
||||
Writes text at the current cursor position, moving the cursor to the end of the text.
|
||||
This only writes to an internal buffer. For the changes to show up on the display [`update()`](#update) must be used.
|
||||
If the cursor is outside the bounds of the connected display, the text will not show up on the display.
|
||||
|
||||
This will overwrite any text currently at the cursor position.
|
||||
|
||||
**Parameters**
|
||||
- _text:_ `string` The text to write.
|
||||
|
||||
**See also**
|
||||
- [`update()`](#update) To push the changes to the display target.
|
||||
|
||||
---
|
||||
### `clearLine()`
|
||||
Clears the line at the current cursor position.
|
||||
|
||||
**See also**
|
||||
- [`update()`](#update) To push the changes to the display target.
|
||||
|
||||
---
|
||||
### `clear()`
|
||||
Clears the whole display.
|
||||
|
||||
**See also**
|
||||
- [`update()`](#update) To push the changes to the display target.
|
||||
|
||||
---
|
||||
### `update()`
|
||||
Pushes any changes to the connected display target.
|
||||
Any changes made are only made to an internal buffer.
|
||||
For them to show up on the display they must be pushed to the display using this function.
|
||||
This allows for this peripheral to be better multithreaded and for users to be able to change multiple lines at once by
|
||||
using multiple [`write(text)`](#writetext) calls and then one [`update()`](#update) call.
|
||||
|
||||
**See also**
|
||||
- [`write(text)`](#writetext) To write text to the display target.
|
18
wiki/Lua-Rotation-Speed-Controller.md
Normal file
18
wiki/Lua-Rotation-Speed-Controller.md
Normal file
|
@ -0,0 +1,18 @@
|
|||
| Method | Description |
|
||||
|-------------------------------------------------|----------------------------------------|
|
||||
| [`setTargetSpeed(speed)`](#setTargetSpeedspeed) | Sets the target rotation speed |
|
||||
| [`getTargetSpeed()`](#getTargetSpeed) | Gets the current target rotation speed |
|
||||
|
||||
---
|
||||
### `setTargetSpeed(speed)`
|
||||
Sets the rotation speed controller's target speed.
|
||||
|
||||
**Parameters**
|
||||
- _speed:_ `number` The target speed in RPM. Must be an integer within the range of [-256..256]. Values outside of this range will be clamped.
|
||||
|
||||
---
|
||||
### `getTargetSpeed()`
|
||||
Gets the rotation speed controller's current target speed.
|
||||
|
||||
**Returns**
|
||||
- `number` The current target rotation speed in RPM.
|
28
wiki/Lua-Sequenced-Gearshift.md
Normal file
28
wiki/Lua-Sequenced-Gearshift.md
Normal file
|
@ -0,0 +1,28 @@
|
|||
| Method | Description |
|
||||
|--------------------------------------------------------|--------------------------------------------------------------|
|
||||
| [`rotate(angle, [modifier])`](#rotateangle-modifier) | Rotates shaft by a set angle |
|
||||
| [`move(distance, [modifier])`](#movedistance-modifier) | Rotates shaft to move Piston/Pulley/Gantry by a set distance |
|
||||
| [`isRunning()`](#isRunning) | Whether the gearshift is currently spinning |
|
||||
|
||||
---
|
||||
### `rotate(angle, [modifier])`
|
||||
Rotates connected components by a set angle.
|
||||
|
||||
**Parameters**
|
||||
- _angle:_ `number` Angle to rotate the shaft by in degrees. Must be a positive integer. To do backwards rotation, set _modifier_ to a negative value.
|
||||
- _modifier?:_ `number = 1` Speed modifier which can be used to reverse rotation. Must be an integer within the range of [-2..2]. Values out of this range are ignored and the default of 1 is used.
|
||||
|
||||
---
|
||||
### `move(distance, [modifier])`
|
||||
Rotates connected components to move connected piston, pulley or gantry contractions by a set distance.
|
||||
|
||||
**Parameters**
|
||||
- _distance:_ `number` Distance to move connected piston, pulley or gantry contraptions by. Must be a positive integer. To do backwards movement, set _modifier_ to a negative value.
|
||||
- _modifier?:_ `number = 1` Speed modifier which can be used to reverse direction. Must be an integer within the range of [-2..2]. Values out of this range are ignored and the default of 1 is used.
|
||||
|
||||
---
|
||||
### `isRunning()`
|
||||
Checks if the sequenced gearshift is currently spinning.
|
||||
|
||||
**Returns**
|
||||
- `boolean` Whether the sequenced gearshift is currently spinning.
|
10
wiki/Lua-Speedometer.md
Normal file
10
wiki/Lua-Speedometer.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
| Method | Description |
|
||||
|---------------------------|---------------------------------|
|
||||
| [`getSpeed()`](#getSpeed) | Gets the current rotation speed |
|
||||
|
||||
---
|
||||
### `getSpeed()`
|
||||
Gets the current rotation speed of the attached components.
|
||||
|
||||
**Returns**
|
||||
- `number` The current rotation speed in RPM.
|
18
wiki/Lua-Stressometer.md
Normal file
18
wiki/Lua-Stressometer.md
Normal file
|
@ -0,0 +1,18 @@
|
|||
| Method | Description |
|
||||
|---------------------------------------------|--------------------------------|
|
||||
| [`getStress()`](#getStress) | Gets the current stress level |
|
||||
| [`getStressCapacity()`](#getStressCapacity) | Gets the total stress capacity |
|
||||
|
||||
---
|
||||
### `getStress()`
|
||||
Gets the connected network's current stress level.
|
||||
|
||||
**Returns**
|
||||
- `number` The current stress level in SU.
|
||||
|
||||
---
|
||||
### `getStressCapacity()`
|
||||
Gets the connected network's total stress capacity.
|
||||
|
||||
**Returns**
|
||||
- `number` The total stress capacity in SU.
|
195
wiki/Lua-Train-Schedule.md
Normal file
195
wiki/Lua-Train-Schedule.md
Normal file
|
@ -0,0 +1,195 @@
|
|||
Train schedules are represented by a table in Lua. The table contains a list of entries where each entry has a single instruction and multiple conditions.
|
||||
Each instruction and condition has a `data` table that stores specific data about the instruction or condition.
|
||||
|
||||
```lua
|
||||
schedule = {
|
||||
cyclic = true, -- Does the schedule repeat itself after the end has been reached?
|
||||
entries = { -- List of entries, each entry contains a single instruction and multiple conditions.
|
||||
{
|
||||
instruction = {
|
||||
id = "create:destination", -- The different instructions are described below.
|
||||
data = { -- Data that is stored about the instruction. Different for each instruction type.
|
||||
text = "Station 1",
|
||||
},
|
||||
},
|
||||
conditions = { -- List of lists of conditions. The outer list is the "OR" list
|
||||
{ -- and the inner lists are "AND" lists.
|
||||
{
|
||||
id = "create:delay", -- The different conditions are described below.
|
||||
data = { -- Data that is stored about the condition. Different for each condition type.
|
||||
value = 5,
|
||||
time_unit = 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
id = "create:powered",
|
||||
data = {},
|
||||
},
|
||||
},
|
||||
{
|
||||
{
|
||||
id = "create:time_of_day",
|
||||
data = {
|
||||
rotation = 0,
|
||||
hour = 14,
|
||||
minute = 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
---
|
||||
## Instructions
|
||||
| ID | Description |
|
||||
|----------------------------------------------|---------------------------------|
|
||||
| [`"create:destination"`](#createdestination) | Move to a certain train station |
|
||||
| [`"create:rename"`](#createrename) | Change the schedule title |
|
||||
| [`"create:throttle"`](#createthrottle) | Change the train's throttle |
|
||||
|
||||
---
|
||||
### `"create:destination"`
|
||||
Moves the train to the chosen train station. This instruction must have at least one condition.
|
||||
|
||||
**Data**
|
||||
- _text:_ `string` The name of the station to travel to. Can include * as a wildcard.
|
||||
|
||||
---
|
||||
### `"create:rename"`
|
||||
Renames the schedule. This name shows up on display link targets. This instruction cannot have conditions.
|
||||
|
||||
**Data**
|
||||
- _text:_ `string` The name to rename the schedule to.
|
||||
|
||||
---
|
||||
### `"create:throttle"`
|
||||
Changes the throttle of the train. This instruction cannot have conditions.
|
||||
|
||||
**Data**
|
||||
- _value:_ `number` The throttle to set the train to. Must be an integer within the range of [5..100].
|
||||
|
||||
---
|
||||
## Conditions
|
||||
Conditions are stored in a list of lists of conditions. The inner lists contain conditions that get `AND`'ed together. They must all be met for that group to be true.
|
||||
The outer list contains the `AND`'ed groups of conditions that get `OR`'ed together. Only one of the groups needs to be true for the schedule to move onto the next instruction.
|
||||
|
||||
| ID | Description |
|
||||
|-----------------------------------------------------|-----------------------------------------------------|
|
||||
| [`"create:delay"`](#createdelay) | Wait for a certain delay |
|
||||
| [`"create:time_of_day"`](#createtimeofday) | Wait for a specific time of day |
|
||||
| [`"create:fluid_threshold"`](#createfluidthreshold) | Wait for a certain amount of fluid to be on board |
|
||||
| [`"create:item_threshold"`](#createitemthreshold) | Wait for a certain amount of items to be on board |
|
||||
| [`"create:redstone_link"`](#createredstonelink) | Wait for a redstone link to be powered |
|
||||
| [`"create:player_count"`](#createplayercount) | Wait for a certain amount of players to be on board |
|
||||
| [`"create:idle"`](#createidle) | Wait for cargo loading inactivity |
|
||||
| [`"create:unloaded"`](#createunloaded) | Wait for the current chunk to be unloaded |
|
||||
| [`"create:powered"`](#createpowered) | Wait for the station to be powered |
|
||||
|
||||
---
|
||||
### `"create:delay"`
|
||||
Wait for a set delay. Can be measured in ticks, seconds or minutes.
|
||||
|
||||
**Data**
|
||||
- _value:_ `number` The amount of time to wait for.
|
||||
- _time_unit:_ `number` The unit of time. 0 for ticks, 1 for seconds and 2 for minutes.
|
||||
|
||||
---
|
||||
### `"create:time_of_day"`
|
||||
Wait for a time of day, then repeat at a specified interval.
|
||||
|
||||
**Data**
|
||||
- _hour:_ `number` The hour of the day to wait for in a 24-hour format. Must be an integer within the range of [0..23].
|
||||
- _minute:_ `number` The minute of the hour to wait for. Must be an integer within the range of [0..59].
|
||||
- _rotation:_ `number` The interval to repeat at after the time of day has been met. Check the rotation table below for valid values. Must be an integer within the range of [0..9].
|
||||
|
||||
**Rotation**
|
||||
|
||||
| Rotation | Time Interval |
|
||||
|----------|------------------|
|
||||
| 0 | Every Day |
|
||||
| 1 | Every 12 Hours |
|
||||
| 2 | Every 6 Hours |
|
||||
| 3 | Every 4 Hours |
|
||||
| 4 | Every 3 Hours |
|
||||
| 5 | Every 2 Hours |
|
||||
| 6 | Every Hour |
|
||||
| 7 | Every 45 Minutes |
|
||||
| 8 | Every 30 Minutes |
|
||||
| 9 | Every 15 Minutes |
|
||||
|
||||
---
|
||||
### `"create:fluid_threshold"`
|
||||
Wait for a certain amount of a specific fluid to be loaded onto the train.
|
||||
|
||||
**Data**
|
||||
- _bucket:_ `table` The bucket item of the fluid.
|
||||
- _threshold:_ `number` The threshold in number of buckets of fluid. Must be a positive integer.
|
||||
- _operator:_ `number` Whether the condition should wait for the train to be loaded above the threshold, below the threshold or exactly at the threshold. 0 for greater than, 1 for less than, 2 for equal to.
|
||||
- _measure:_ `number` The unit to measure the fluid in. This condition supports buckets as the only unit. Set to 0.
|
||||
|
||||
**See also**
|
||||
- [Items](#items) How items are represented in Lua.
|
||||
|
||||
---
|
||||
### `"create:item_threshold"`
|
||||
Wait for a certain amount of a specific item to be loaded onto the train.
|
||||
|
||||
**Data**
|
||||
- _item:_ `table` The item.
|
||||
- _threshold:_ `number` The threshold of items. Must be a positive integer.
|
||||
- _operator:_ `number` Whether the condition should wait for the train to be loaded above the threshold, below the threshold or exactly at the threshold. 0 for greater than, 1 for less than, 2 for equal to.
|
||||
- _measure:_ `number` The unit to measure the items in. 0 for items. 1 for stacks of items.
|
||||
|
||||
**See also**
|
||||
- [Items](#items) How items are represented in Lua.
|
||||
|
||||
---
|
||||
### `"create:redstone_link"`
|
||||
Wait for a redstone link to be powered.
|
||||
|
||||
**Data**
|
||||
- _frequency:_ `{ table... }` A list of the two items making up the redstone link frequency.
|
||||
- _inverted:_ `number` Whether the redstone link should be powered or not to meet the condition. 0 for powered. 1 for not powered.
|
||||
|
||||
**See also**
|
||||
- [Items](#items) How items are represented in Lua.
|
||||
|
||||
---
|
||||
### `"create:player_count"`
|
||||
Wait for a certain amount of players to be seated on the train.
|
||||
|
||||
**Data**
|
||||
- _count:_ `number` The number of players to be seated on the train. Must be a positive integer.
|
||||
- _exact:_ `number` Whether the seated player count has to be exact to meet the condition. 0 for the exact amount of players seated, 1 for a greater than or equal amount of seated players.
|
||||
|
||||
---
|
||||
### `"create:idle"`
|
||||
Wait for a period of inactivity in loading or unloading the train. Can be measured in ticks, seconds or minutes.
|
||||
|
||||
**Data**
|
||||
- _value:_ `number` The amount of idle time to meet the condition. Must be a positive integer.
|
||||
- _time_unit:_ `number` The unit of time. 0 for ticks, 1 for seconds and 2 for minutes.
|
||||
|
||||
---
|
||||
### `"create:unloaded"`
|
||||
Wait for the chunk the train is in to be unloaded.
|
||||
|
||||
---
|
||||
### `"create:powered"`
|
||||
Wait for the station to be powered with a redstone signal.
|
||||
|
||||
---
|
||||
## Items
|
||||
In Lua, items are represented with an ID and a count.
|
||||
|
||||
```lua
|
||||
item = {
|
||||
id = "minecraft:stone",
|
||||
count = 1,
|
||||
}
|
||||
```
|
||||
|
||||
- _id:_ `string` The ID of the item.
|
||||
- _count:_ `number` The amount of items in the stack. For the purposes of working with train schedules the count should always be 1. Must be an integer.
|
179
wiki/Lua-Train-Station.md
Normal file
179
wiki/Lua-Train-Station.md
Normal file
|
@ -0,0 +1,179 @@
|
|||
| Method | Description |
|
||||
|-----------------------------------------------------------------|----------------------------------------------------|
|
||||
| [`assemble()`](#assemble) | Assembles a new train at the station |
|
||||
| [`disassemble()`](#disassemble) | Disassembles the currently present train |
|
||||
| [`setAssemblyMode(assemblyMode)`](#setAssemblyModeassemblyMode) | Sets the station's assembly mode |
|
||||
| [`isInAssemblyMode()`](#isInAssemblyMode) | Whether the station is in assembly mode |
|
||||
| [`getStationName()`](#getStationName) | Gets the station's current name |
|
||||
| [`setStationName(name)`](#setStationNamename) | Sets the station's name |
|
||||
| [`isTrainPresent()`](#isTrainPresent) | Whether a train is present at the station |
|
||||
| [`isTrainImminent()`](#isTrainImminent) | Whether a train is imminent to the station |
|
||||
| [`isTrainEnroute()`](#isTrainEnroute) | Whether a train is enroute to the station |
|
||||
| [`getTrainName()`](#getTrainName) | Gets the currently present train's name |
|
||||
| [`setTrainName(name)`](#setTrainNamename) | Sets the currently present train's name |
|
||||
| [`hasSchedule()`](#hasSchedule) | Whether the currently present train has a schedule |
|
||||
| [`getSchedule()`](#getSchedule) | Gets the currently present train's schedule |
|
||||
| [`setSchedule(schedule)`](#setScheduleschedule) | Sets the currently present train's schedule |
|
||||
|
||||
---
|
||||
### `assemble()`
|
||||
Assembles a new train at the station. The station must be in assembly mode prior to calling this function.
|
||||
This function also causes the station to exit assembly mode after the train is done assembing.
|
||||
|
||||
**Throws**
|
||||
- If the station is not in assembly mode.
|
||||
- If the station is not connected to a track.
|
||||
- If the train failed to assemble.
|
||||
- If the station failed to exit assembly mode.
|
||||
|
||||
**See also**
|
||||
- [`setAssemblyMode(assemblyMode)`](#setAssemblyModeassemblyMode) To set the assembly mode of the station.
|
||||
|
||||
---
|
||||
### `disassemble()`
|
||||
Disassembles the station's currently present train. The station must not be in assembly mode.
|
||||
|
||||
**Throws**
|
||||
- If the station is in assembly mode.
|
||||
- If the station is not connected to a track.
|
||||
- If there is currently no train present at the station.
|
||||
- If the train failed to disassemble.
|
||||
|
||||
**See also**
|
||||
- [`setAssemblyMode(assemblyMode)`](#setAssemblyModeassemblyMode) To set the assembly mode of the station.
|
||||
|
||||
---
|
||||
### `setAssemblyMode(assemblyMode)`
|
||||
Sets the station's assembly mode.
|
||||
|
||||
**Parameters**
|
||||
- _assemblyMode:_ `boolean` Whether the station should be in assembly mode.
|
||||
|
||||
**Throws**
|
||||
- If the station fails to enter or exit assembly mode.
|
||||
- If the station is not connected to a track.
|
||||
|
||||
---
|
||||
### `isInAssemblyMode()`
|
||||
Checks whether the station is in assembly mode.
|
||||
|
||||
**Returns**
|
||||
- `boolean` Whether the station is in assembly mode.
|
||||
|
||||
---
|
||||
### `getStationName()`
|
||||
Gets the station's current name.
|
||||
|
||||
**Returns**
|
||||
- `string` The station's current name.
|
||||
|
||||
**Throws**
|
||||
- If the station is not connected to a track.
|
||||
|
||||
---
|
||||
### `setStationName(name)`
|
||||
Sets the station's name.
|
||||
|
||||
**Parameters**
|
||||
- _name:_ `string` What to set the station's name to.
|
||||
|
||||
**Throws**
|
||||
- If the station name fails to be set.
|
||||
- If the station is not connected to a track.
|
||||
|
||||
---
|
||||
### `isTrainPresent()`
|
||||
Checks whether a train is currently present at the station.
|
||||
|
||||
**Returns**
|
||||
- `boolean` Whether a train is present at the station.
|
||||
|
||||
**Throws**
|
||||
- If the station is not connected to a track.
|
||||
|
||||
---
|
||||
### `isTrainImminent()`
|
||||
Checks whether a train is imminently arriving at the station.
|
||||
Imminent is defined as being within 30 blocks of the station.
|
||||
This will not be true if the train has arrived and stopped at the station.
|
||||
|
||||
**Returns**
|
||||
- `boolean` Whether a train is imminent to the station.
|
||||
|
||||
**Throws**
|
||||
- If the station is not connected to a track.
|
||||
|
||||
**See also**
|
||||
- [`isTrainPresent()`](#isTrainPresent) To check if a train is present at the station.
|
||||
|
||||
---
|
||||
### `isTrainEnroute()`
|
||||
Checks whether a train is enroute and navigating to the station.
|
||||
|
||||
**Returns**
|
||||
- `boolean` Whether a train is enroute to the station.
|
||||
|
||||
**Throws**
|
||||
- If the station is not connected to a track.
|
||||
|
||||
---
|
||||
### `getTrainName()`
|
||||
Gets the currently present train's name.
|
||||
|
||||
**Returns**
|
||||
- `string` The currently present train's name.
|
||||
|
||||
**Throws**
|
||||
- If the station is not connected to a track.
|
||||
- If there is currently no train present at the station.
|
||||
|
||||
---
|
||||
### `setTrainName(name)`
|
||||
Sets the currently present train's name.
|
||||
|
||||
**Parameters**
|
||||
- _name:_ `string` What to set the currently present train's name to.
|
||||
|
||||
**Throws**
|
||||
- If the station is not connected to a track.
|
||||
- If there is currently no train present at the station.
|
||||
|
||||
---
|
||||
### `hasSchedule()`
|
||||
Checks whether the currently present train has a schedule.
|
||||
|
||||
**Returns**
|
||||
- `boolean` Whether the currently present train has a schedule.
|
||||
|
||||
**Throws**
|
||||
- If the station is not connected to a track.
|
||||
- If there is currently no train present at the station.
|
||||
|
||||
---
|
||||
### `getSchedule()`
|
||||
Gets the currently present train's schedule.
|
||||
|
||||
**Returns**
|
||||
- `table` The train's schedule
|
||||
|
||||
**Throws**
|
||||
- If the station is not connected to a track.
|
||||
- If there is currently no train present at the station.
|
||||
- If the present train doesn't have a schedule.
|
||||
|
||||
**See also**
|
||||
- [Lua Train Schedules](#Lua-Train-Schedules) How train schedules are represented in Lua.
|
||||
|
||||
---
|
||||
### `setSchedule(schedule)`
|
||||
Sets the currently present train's schedule. This will overwrite the currently set schedule.
|
||||
|
||||
**Parameters**
|
||||
- _schedule:_ `table` The schedule to set the present train to.
|
||||
|
||||
**Throws**
|
||||
- If the station is not connected to a track.
|
||||
- If there is currently no train present at the station.
|
||||
|
||||
**See also**
|
||||
- [Lua Train Schedules](#Lua-Train-Schedules) How train schedules are represented in Lua.
|
2
wiki/README.md
Normal file
2
wiki/README.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
Just before this PR is about to be merged this /wiki folder will be removed from the PR and the pages will be added to
|
||||
the wiki section of the Create GitHub under API Reference
|
Loading…
Reference in a new issue