mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-10 12:33:57 +01:00
Added Train Station as peripheral
- Train station can set a new auto-schedule for the train currently at the station - Added CreateLuaTable to add helper functions for working with lua tables - Added StringHelper util class to convert snake case to camel case
This commit is contained in:
parent
1091f3227c
commit
ab18034b98
@ -0,0 +1,89 @@
|
|||||||
|
package com.simibubi.create.compat.computercraft;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import dan200.computercraft.api.lua.LuaException;
|
||||||
|
import dan200.computercraft.api.lua.LuaValues;
|
||||||
|
import dan200.computercraft.api.lua.ObjectLuaTable;
|
||||||
|
|
||||||
|
public class CreateLuaTable extends ObjectLuaTable {
|
||||||
|
|
||||||
|
public CreateLuaTable(Map<?, ?> map) {
|
||||||
|
super(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,130 @@
|
|||||||
|
package com.simibubi.create.compat.computercraft;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
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.schedule.Schedule;
|
||||||
|
import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleEntry;
|
||||||
|
import com.simibubi.create.content.logistics.trains.management.schedule.condition.ScheduleWaitCondition;
|
||||||
|
import com.simibubi.create.content.logistics.trains.management.schedule.destination.ScheduleInstruction;
|
||||||
|
import com.simibubi.create.foundation.utility.Pair;
|
||||||
|
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.CompoundTag;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
|
public class StationPeripheral extends PeripheralBase<StationTileEntity> {
|
||||||
|
|
||||||
|
public StationPeripheral(StationTileEntity tile) {
|
||||||
|
super(tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
@LuaFunction(mainThread = true)
|
||||||
|
public void setSchedule(IArguments arguments) throws LuaException {
|
||||||
|
GlobalStation station = tile.getStation();
|
||||||
|
if (station == null)
|
||||||
|
throw new LuaException("train station does not exist");
|
||||||
|
|
||||||
|
Train train = station.getPresentTrain();
|
||||||
|
if (train == null)
|
||||||
|
throw new LuaException("there is no train present");
|
||||||
|
|
||||||
|
Schedule schedule = parseSchedule(arguments);
|
||||||
|
train.runtime.setSchedule(schedule, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Schedule parseSchedule(IArguments arguments) throws LuaException {
|
||||||
|
CreateLuaTable scheduleTable = new CreateLuaTable(arguments.getTable(0));
|
||||||
|
Schedule schedule = new Schedule();
|
||||||
|
|
||||||
|
schedule.cyclic = scheduleTable.getOptBoolean("cyclic").orElse(true);
|
||||||
|
CreateLuaTable entriesTable = scheduleTable.getTable("entries");
|
||||||
|
|
||||||
|
for (CreateLuaTable entryTable : entriesTable.tableValues()) {
|
||||||
|
ScheduleEntry entry = new ScheduleEntry();
|
||||||
|
|
||||||
|
entry.instruction = getInstruction(entryTable);
|
||||||
|
|
||||||
|
// Add conditions
|
||||||
|
if (entry.instruction.supportsConditions()) {
|
||||||
|
for (CreateLuaTable conditionsListTable : entryTable.getTable("conditions").tableValues()) {
|
||||||
|
List<ScheduleWaitCondition> conditionsList = new ArrayList<>();
|
||||||
|
|
||||||
|
for (CreateLuaTable conditionTable : conditionsListTable.tableValues()) {
|
||||||
|
conditionsList.add(getCondition(conditionTable));
|
||||||
|
}
|
||||||
|
|
||||||
|
entry.conditions.add(conditionsList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
schedule.entries.add(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
return schedule;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ScheduleInstruction getInstruction(CreateLuaTable entry) throws LuaException {
|
||||||
|
ResourceLocation location = new ResourceLocation(entry.getString("instruction"));
|
||||||
|
|
||||||
|
for (Pair<ResourceLocation, Supplier<? extends ScheduleInstruction>> pair : Schedule.INSTRUCTION_TYPES)
|
||||||
|
if (pair.getFirst().equals(location)) {
|
||||||
|
ScheduleInstruction instruction = pair.getSecond().get();
|
||||||
|
instruction.setData(getEntryData(entry.getTable("data")));
|
||||||
|
|
||||||
|
return instruction;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new LuaException("instruction " + location + " is not a valid instruction type");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ScheduleWaitCondition getCondition(CreateLuaTable entry) throws LuaException {
|
||||||
|
ResourceLocation location = new ResourceLocation(entry.getString("condition"));
|
||||||
|
|
||||||
|
for (Pair<ResourceLocation, Supplier<? extends ScheduleWaitCondition>> pair : Schedule.CONDITION_TYPES)
|
||||||
|
if (pair.getFirst().equals(location)) {
|
||||||
|
ScheduleWaitCondition condition = pair.getSecond().get();
|
||||||
|
condition.setData(getEntryData(entry.getTable("data")));
|
||||||
|
|
||||||
|
return condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new LuaException("condition " + location + " is not a valid condition type");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CompoundTag getEntryData(CreateLuaTable data) throws LuaException {
|
||||||
|
CompoundTag tag = new CompoundTag();
|
||||||
|
|
||||||
|
for (String key : data.stringKeySet()) {
|
||||||
|
String tagKey = StringHelper.snakeCaseToCamelCase(key);
|
||||||
|
Object value = data.get(key);
|
||||||
|
|
||||||
|
if (value instanceof Boolean)
|
||||||
|
tag.putBoolean(tagKey, (Boolean) value);
|
||||||
|
else if (value instanceof Number)
|
||||||
|
tag.putDouble(tagKey, ((Number) value).doubleValue());
|
||||||
|
else if (value instanceof String)
|
||||||
|
tag.putString(tagKey, (String) value);
|
||||||
|
else
|
||||||
|
throw new LuaException("");
|
||||||
|
}
|
||||||
|
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return "Create_Station";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -12,10 +12,14 @@ import java.util.UUID;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.AllItems;
|
import com.simibubi.create.AllItems;
|
||||||
import com.simibubi.create.AllSoundEvents;
|
import com.simibubi.create.AllSoundEvents;
|
||||||
import com.simibubi.create.Create;
|
import com.simibubi.create.Create;
|
||||||
|
import com.simibubi.create.compat.computercraft.ComputerControllable;
|
||||||
|
import com.simibubi.create.compat.computercraft.StationPeripheral;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
|
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.ITransformableTE;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
||||||
@ -51,6 +55,7 @@ import com.simibubi.create.foundation.utility.WorldAttached;
|
|||||||
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
|
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
|
||||||
import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser;
|
import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser;
|
||||||
|
|
||||||
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.BlockPos.MutableBlockPos;
|
import net.minecraft.core.BlockPos.MutableBlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
@ -77,7 +82,7 @@ import net.minecraftforge.common.capabilities.Capability;
|
|||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
import net.minecraftforge.network.PacketDistributor;
|
import net.minecraftforge.network.PacketDistributor;
|
||||||
|
|
||||||
public class StationTileEntity extends SmartTileEntity implements ITransformableTE {
|
public class StationTileEntity extends SmartTileEntity implements ITransformableTE, ComputerControllable {
|
||||||
|
|
||||||
public TrackTargetingBehaviour<GlobalStation> edgePoint;
|
public TrackTargetingBehaviour<GlobalStation> edgePoint;
|
||||||
public LerpedFloat flag;
|
public LerpedFloat flag;
|
||||||
@ -98,6 +103,7 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable
|
|||||||
boolean flagFlipped;
|
boolean flagFlipped;
|
||||||
|
|
||||||
public Component lastDisassembledTrainName;
|
public Component lastDisassembledTrainName;
|
||||||
|
private LazyOptional<IPeripheral> peripheral;
|
||||||
|
|
||||||
public StationTileEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
public StationTileEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||||
super(type, pos, state);
|
super(type, pos, state);
|
||||||
@ -699,10 +705,19 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
|
public <T> @NotNull LazyOptional<T> getCapability(@NotNull Capability<T> cap, Direction side) {
|
||||||
|
LazyOptional<T> peripheralCap = getPeripheralCapability(cap);
|
||||||
|
|
||||||
if (isItemHandlerCap(cap))
|
if (isItemHandlerCap(cap))
|
||||||
return depotBehaviour.getItemCapability(cap, side);
|
return depotBehaviour.getItemCapability(cap, side);
|
||||||
return super.getCapability(cap, side);
|
|
||||||
|
return peripheralCap.isPresent() ? peripheralCap : super.getCapability(cap, side);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invalidateCaps() {
|
||||||
|
super.invalidateCaps();
|
||||||
|
removePeripheral();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyAutoSchedule() {
|
private void applyAutoSchedule() {
|
||||||
@ -766,4 +781,19 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable
|
|||||||
edgePoint.transform(transform);
|
edgePoint.transform(transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPeripheral createPeripheral() {
|
||||||
|
return new StationPeripheral(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPeripheral(LazyOptional<IPeripheral> peripheral) {
|
||||||
|
this.peripheral = peripheral;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LazyOptional<IPeripheral> getPeripheral() {
|
||||||
|
return peripheral;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,8 @@ public interface IScheduleInput {
|
|||||||
|
|
||||||
public abstract CompoundTag getData();
|
public abstract CompoundTag getData();
|
||||||
|
|
||||||
|
public abstract void setData(CompoundTag data);
|
||||||
|
|
||||||
public default int slotsTargeted() {
|
public default int slotsTargeted() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -40,7 +42,7 @@ public interface IScheduleInput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public default void setItem(int slot, ItemStack stack) {}
|
public default void setItem(int slot, ItemStack stack) {}
|
||||||
|
|
||||||
public default ItemStack getItem(int slot) {
|
public default ItemStack getItem(int slot) {
|
||||||
return ItemStack.EMPTY;
|
return ItemStack.EMPTY;
|
||||||
}
|
}
|
||||||
@ -58,4 +60,4 @@ public interface IScheduleInput {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,33 +3,38 @@ package com.simibubi.create.content.logistics.trains.management.schedule;
|
|||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
|
||||||
public abstract class ScheduleDataEntry implements IScheduleInput {
|
public abstract class ScheduleDataEntry implements IScheduleInput {
|
||||||
|
|
||||||
protected CompoundTag data;
|
protected CompoundTag data;
|
||||||
|
|
||||||
public ScheduleDataEntry() {
|
public ScheduleDataEntry() {
|
||||||
data = new CompoundTag();
|
data = new CompoundTag();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundTag getData() {
|
public CompoundTag getData() {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setData(CompoundTag data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
protected void writeAdditional(CompoundTag tag) {};
|
protected void writeAdditional(CompoundTag tag) {};
|
||||||
|
|
||||||
protected void readAdditional(CompoundTag tag) {};
|
protected void readAdditional(CompoundTag tag) {};
|
||||||
|
|
||||||
protected <T> T enumData(String key, Class<T> enumClass) {
|
protected <T> T enumData(String key, Class<T> enumClass) {
|
||||||
T[] enumConstants = enumClass.getEnumConstants();
|
T[] enumConstants = enumClass.getEnumConstants();
|
||||||
return enumConstants[data.getInt(key) % enumConstants.length];
|
return enumConstants[data.getInt(key) % enumConstants.length];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String textData(String key) {
|
protected String textData(String key) {
|
||||||
return data.getString(key);
|
return data.getString(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int intData(String key) {
|
protected int intData(String key) {
|
||||||
return data.getInt(key);
|
return data.getInt(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user