mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-17 03:05:30 -04:00
added command block, note block and rim carriage controller drivers (moved from oc core)
This commit is contained in:
parent
d39cdd40a4
commit
338f898a85
@ -6,6 +6,7 @@ import li.cil.oc.driver.Registry;
|
||||
import li.cil.oc.driver.buildcraft.HandlerBuildCraft;
|
||||
import li.cil.oc.driver.enderstorage.HandlerEnderStorage;
|
||||
import li.cil.oc.driver.ic2.HandlerIndustrialCraft2;
|
||||
import li.cil.oc.driver.redstoneinmotion.HandlerRedstoneInMotion;
|
||||
import li.cil.oc.driver.thermalexpansion.HandlerThermalExpansion;
|
||||
import li.cil.oc.driver.vanilla.HandlerVanilla;
|
||||
|
||||
@ -19,6 +20,7 @@ public class OpenComponents {
|
||||
Registry.add(new HandlerBuildCraft());
|
||||
Registry.add(new HandlerEnderStorage());
|
||||
Registry.add(new HandlerIndustrialCraft2());
|
||||
Registry.add(new HandlerRedstoneInMotion());
|
||||
Registry.add(new HandlerThermalExpansion());
|
||||
Registry.add(new HandlerVanilla());
|
||||
}
|
||||
|
@ -8,7 +8,13 @@ public abstract class TileEntityDriver implements li.cil.oc.api.driver.Block {
|
||||
|
||||
@Override
|
||||
public boolean worksWith(final World world, final int x, final int y, final int z) {
|
||||
final Class<?> filter = getFilterClass();
|
||||
if (filter == null) {
|
||||
// This can happen if filter classes are deduced by reflection and
|
||||
// the class in question is not present.
|
||||
return false;
|
||||
}
|
||||
final TileEntity tileEntity = world.getBlockTileEntity(x, y, z);
|
||||
return tileEntity != null && getFilterClass().isAssignableFrom(tileEntity.getClass());
|
||||
return tileEntity != null && filter.isAssignableFrom(tileEntity.getClass());
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ public final class DriverFrequencyOwner extends TileEntityDriver {
|
||||
}
|
||||
final String owner = (String) Reflection.get(tileEntity, "owner");
|
||||
if (owner == null || owner.isEmpty() || "global".equals(owner)) {
|
||||
Reflection.invoke(tileEntity, "setFreq", frequency);
|
||||
Reflection.tryInvoke(tileEntity, "setFreq", frequency);
|
||||
} else {
|
||||
return new Object[]{false, "cannot change frequency of owned storage"};
|
||||
}
|
||||
|
@ -0,0 +1,184 @@
|
||||
package li.cil.oc.driver.redstoneinmotion;
|
||||
|
||||
import li.cil.oc.api.network.Arguments;
|
||||
import li.cil.oc.api.network.Callback;
|
||||
import li.cil.oc.api.network.Context;
|
||||
import li.cil.oc.api.network.ManagedEnvironment;
|
||||
import li.cil.oc.driver.ManagedTileEntityEnvironment;
|
||||
import li.cil.oc.driver.TileEntityDriver;
|
||||
import li.cil.oc.util.Reflection;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class DriverCarriageController extends TileEntityDriver {
|
||||
private static final Class<?> CarriageControllerEntity = Reflection.getClass("JAKJ.RedstoneInMotion.CarriageControllerEntity");
|
||||
private static final Class<?> CarriageObstructionException = Reflection.getClass("JAKJ.RedstoneInMotion.CarriageObstructionException");
|
||||
private static final Class<?> Directions = Reflection.getClass("JAKJ.RedstoneInMotion.Directions");
|
||||
|
||||
@Override
|
||||
public Class<?> getFilterClass() {
|
||||
return CarriageControllerEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManagedEnvironment createEnvironment(final World world, final int x, final int y, final int z) {
|
||||
return new Environment(world.getBlockTileEntity(x, y, z));
|
||||
}
|
||||
|
||||
public static final class Environment extends ManagedTileEntityEnvironment<TileEntity> {
|
||||
private boolean isAnchored;
|
||||
|
||||
// Arguments for an actual move, stored here until we hit the next
|
||||
// call to update(). See below for more information as to why.
|
||||
private boolean shouldMove;
|
||||
private boolean isSimulating;
|
||||
private int direction;
|
||||
|
||||
// Used to check whether we should send a success signal after loading.
|
||||
private boolean isMoving;
|
||||
|
||||
// Used to delay success signals after a move to make sure the computer
|
||||
// that triggered the move is reachable again.
|
||||
private int signalDelay = 10;
|
||||
|
||||
public Environment(final TileEntity tileEntity) {
|
||||
super(tileEntity, "carriage");
|
||||
}
|
||||
|
||||
@Callback(direct = true)
|
||||
public Object[] getAnchored(final Context context, final Arguments args) {
|
||||
return new Object[]{isAnchored};
|
||||
}
|
||||
|
||||
@Callback
|
||||
public Object[] setAnchored(final Context context, final Arguments args) {
|
||||
isAnchored = args.checkBoolean(0);
|
||||
return new Object[]{isAnchored};
|
||||
}
|
||||
|
||||
@Callback
|
||||
public Object[] move(final Context context, final Arguments args) {
|
||||
// We execute moves in the update() call to the environment instead
|
||||
// of in here, because the move may cause the calling computer to
|
||||
// be persisted - which is not possible while it has an active call
|
||||
// (namely to this function).
|
||||
direction = checkDirection(args);
|
||||
isSimulating = args.count() > 1 && args.checkBoolean(1);
|
||||
shouldMove = true;
|
||||
context.pause(0.1);
|
||||
return new Object[]{true};
|
||||
}
|
||||
|
||||
@Callback
|
||||
public Object[] simulate(final Context context, final Arguments args) {
|
||||
// IMPORTANT: we have to do the simulation asynchronously, too,
|
||||
// because that may also try to persist the computer that called us,
|
||||
// and it must not be running when we do that.
|
||||
direction = checkDirection(args);
|
||||
isSimulating = true;
|
||||
shouldMove = true;
|
||||
context.pause(0.1);
|
||||
return new Object[]{true};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canUpdate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
if (node != null && node.network() != null && isMoving) {
|
||||
--signalDelay;
|
||||
if (signalDelay <= 0) {
|
||||
isMoving = false;
|
||||
node.sendToReachable("computer.signal", "carriage_moved", true);
|
||||
}
|
||||
}
|
||||
if (shouldMove) {
|
||||
shouldMove = false;
|
||||
isMoving = true;
|
||||
try {
|
||||
Reflection.invoke(tileEntity, "SetupMotion", Directions.getEnumConstants()[direction], isSimulating, isAnchored);
|
||||
Reflection.invoke(tileEntity, "Move");
|
||||
if (isSimulating) {
|
||||
node.sendToReachable("computer.signal", "carriage_moved", true);
|
||||
}
|
||||
} catch (final Throwable e) {
|
||||
if (CarriageObstructionException != null && CarriageObstructionException.isAssignableFrom(e.getClass())) {
|
||||
try {
|
||||
final int x = (Integer) Reflection.get(e, "X");
|
||||
final int y = (Integer) Reflection.get(e, "Y");
|
||||
final int z = (Integer) Reflection.get(e, "Z");
|
||||
node.sendToReachable("computer.signal", "carriage_moved", false, e.getMessage() != null ? e.getMessage() : e.toString(), x, y, z);
|
||||
} catch (Throwable e2) {
|
||||
node.sendToReachable("computer.signal", "carriage_moved", false, e2.getMessage() != null ? e2.getMessage() : e2.toString());
|
||||
}
|
||||
} else {
|
||||
node.sendToReachable("computer.signal", "carriage_moved", false, e.getMessage() != null ? e.getMessage() : e.toString());
|
||||
}
|
||||
} finally {
|
||||
// At this point we have already been saved if the move was
|
||||
// successful, so we can safely always revert this to false.
|
||||
isMoving = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(final NBTTagCompound nbt) {
|
||||
super.load(nbt);
|
||||
isMoving = nbt.getBoolean("moving");
|
||||
isAnchored = nbt.getBoolean("anchored");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(final NBTTagCompound nbt) {
|
||||
super.save(nbt);
|
||||
nbt.setBoolean("moving", isMoving);
|
||||
nbt.setBoolean("anchored", isAnchored);
|
||||
}
|
||||
|
||||
private int checkDirection(final Arguments args) {
|
||||
if (shouldMove || isMoving) {
|
||||
throw new RuntimeException("already moving");
|
||||
}
|
||||
if (args.isString(0)) {
|
||||
final String name = args.checkString(0).toLowerCase();
|
||||
if (!sideNames.containsKey(name)) {
|
||||
throw new IllegalArgumentException("invalid direction");
|
||||
}
|
||||
return sideNames.get(name);
|
||||
} else {
|
||||
final int index = args.checkInteger(0);
|
||||
if (index < 0 || index > 5) {
|
||||
throw new IllegalArgumentException("invalid direction");
|
||||
}
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
private static final Map<String, Integer> sideNames;
|
||||
|
||||
static {
|
||||
sideNames = new HashMap<String, Integer>();
|
||||
sideNames.put("negy", 0);
|
||||
sideNames.put("posy", 1);
|
||||
sideNames.put("negz", 2);
|
||||
sideNames.put("posz", 3);
|
||||
sideNames.put("negx", 4);
|
||||
sideNames.put("posx", 5);
|
||||
|
||||
sideNames.put("down", 0);
|
||||
sideNames.put("up", 1);
|
||||
sideNames.put("north", 2);
|
||||
sideNames.put("south", 3);
|
||||
sideNames.put("west", 4);
|
||||
sideNames.put("east", 5);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package li.cil.oc.driver.redstoneinmotion;
|
||||
|
||||
import li.cil.oc.api.Driver;
|
||||
import li.cil.oc.driver.IModHandler;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public final class HandlerRedstoneInMotion implements IModHandler {
|
||||
@Override
|
||||
public String getModId() {
|
||||
return "JAKJ_RedstoneInMotion";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
Driver.add(new DriverCarriageController());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populate(Map<String, Object> map, ItemStack stack) {
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package li.cil.oc.driver.vanilla;
|
||||
|
||||
import li.cil.oc.api.network.Arguments;
|
||||
import li.cil.oc.api.network.Callback;
|
||||
import li.cil.oc.api.network.Context;
|
||||
import li.cil.oc.api.network.ManagedEnvironment;
|
||||
import li.cil.oc.driver.ManagedTileEntityEnvironment;
|
||||
import li.cil.oc.driver.TileEntityDriver;
|
||||
import net.minecraft.tileentity.TileEntityCommandBlock;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public final class DriverCommandBlock extends TileEntityDriver {
|
||||
@Override
|
||||
public Class<?> getFilterClass() {
|
||||
return TileEntityCommandBlock.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManagedEnvironment createEnvironment(final World world, final int x, final int y, final int z) {
|
||||
return new Environment((TileEntityCommandBlock) world.getBlockTileEntity(x, y, z));
|
||||
}
|
||||
|
||||
public static final class Environment extends ManagedTileEntityEnvironment<TileEntityCommandBlock> {
|
||||
public Environment(final TileEntityCommandBlock tileEntity) {
|
||||
super(tileEntity, "command_block");
|
||||
}
|
||||
|
||||
@Callback(direct = true)
|
||||
public Object[] getCommand(final Context context, final Arguments args) {
|
||||
return new Object[]{tileEntity.getCommand()};
|
||||
}
|
||||
|
||||
@Callback
|
||||
public Object[] setCommand(final Context context, final Arguments args) {
|
||||
tileEntity.setCommand(args.checkString(0));
|
||||
tileEntity.getWorldObj().markBlockForUpdate(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord);
|
||||
return new Object[]{true};
|
||||
}
|
||||
|
||||
@Callback
|
||||
public Object[] executeCommand(final Context context, final Arguments args) {
|
||||
context.pause(0.1); // Make sure the command block has time to do its thing.
|
||||
return new Object[]{tileEntity.executeCommandOnPowered(tileEntity.getWorldObj())};
|
||||
}
|
||||
}
|
||||
}
|
65
src/main/java/li/cil/oc/driver/vanilla/DriverNoteBlock.java
Normal file
65
src/main/java/li/cil/oc/driver/vanilla/DriverNoteBlock.java
Normal file
@ -0,0 +1,65 @@
|
||||
package li.cil.oc.driver.vanilla;
|
||||
|
||||
import li.cil.oc.api.network.Arguments;
|
||||
import li.cil.oc.api.network.Callback;
|
||||
import li.cil.oc.api.network.Context;
|
||||
import li.cil.oc.api.network.ManagedEnvironment;
|
||||
import li.cil.oc.driver.ManagedTileEntityEnvironment;
|
||||
import li.cil.oc.driver.TileEntityDriver;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.tileentity.TileEntityNote;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public final class DriverNoteBlock extends TileEntityDriver {
|
||||
@Override
|
||||
public Class<?> getFilterClass() {
|
||||
return TileEntityNote.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManagedEnvironment createEnvironment(final World world, final int x, final int y, final int z) {
|
||||
return new Environment((TileEntityNote) world.getBlockTileEntity(x, y, z));
|
||||
}
|
||||
|
||||
public static final class Environment extends ManagedTileEntityEnvironment<TileEntityNote> {
|
||||
public Environment(final TileEntityNote tileEntity) {
|
||||
super(tileEntity, "note_block");
|
||||
}
|
||||
|
||||
@Callback(direct = true)
|
||||
public Object[] getPitch(final Context context, final Arguments args) {
|
||||
return new Object[]{tileEntity.note + 1};
|
||||
}
|
||||
|
||||
@Callback
|
||||
public Object[] setPitch(final Context context, final Arguments args) {
|
||||
setPitch(args.checkInteger(0));
|
||||
return new Object[]{true};
|
||||
}
|
||||
|
||||
@Callback
|
||||
public Object[] trigger(final Context context, final Arguments args) {
|
||||
if (args.count() > 0 && args.checkAny(0) != null) {
|
||||
setPitch(args.checkInteger(0));
|
||||
}
|
||||
|
||||
final World world = tileEntity.getWorldObj();
|
||||
final int x = tileEntity.xCoord;
|
||||
final int y = tileEntity.yCoord;
|
||||
final int z = tileEntity.zCoord;
|
||||
final Material material = world.getBlockMaterial(x, y + 1, z);
|
||||
final boolean canTrigger = material == Material.air;
|
||||
|
||||
tileEntity.triggerNote(world, x, y, z);
|
||||
return new Object[]{canTrigger};
|
||||
}
|
||||
|
||||
private void setPitch(final int value) {
|
||||
if (value < 1 || value > 25) {
|
||||
throw new IllegalArgumentException("invalid pitch");
|
||||
}
|
||||
tileEntity.note = (byte) (value - 1);
|
||||
tileEntity.onInventoryChanged();
|
||||
}
|
||||
}
|
||||
}
|
@ -16,12 +16,14 @@ public final class HandlerVanilla implements IModHandler {
|
||||
public void initialize() {
|
||||
Driver.add(new DriverBeacon());
|
||||
Driver.add(new DriverBrewingStand());
|
||||
Driver.add(new DriverCommandBlock());
|
||||
Driver.add(new DriverComparator());
|
||||
Driver.add(new DriverFluidHandler());
|
||||
Driver.add(new DriverFluidTank());
|
||||
Driver.add(new DriverFurnace());
|
||||
Driver.add(new DriverInventory());
|
||||
Driver.add(new DriverMobSpawner());
|
||||
Driver.add(new DriverNoteBlock());
|
||||
Driver.add(new DriverRecordPlayer());
|
||||
Driver.add(new DriverSign());
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ public final class Reflection {
|
||||
}
|
||||
}
|
||||
|
||||
public static Object invoke(final Object instance, final String methodName, final Object... args) {
|
||||
public static Object invoke(final Object instance, final String methodName, final Object... args) throws Throwable {
|
||||
try {
|
||||
outer:
|
||||
for (Method method : instance.getClass().getMethods()) {
|
||||
@ -63,9 +63,17 @@ public final class Reflection {
|
||||
}
|
||||
return null;
|
||||
} catch (InvocationTargetException e) {
|
||||
return null;
|
||||
throw e.getCause();
|
||||
} catch (IllegalAccessException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Object tryInvoke(final Object instance, final String methodName, final Object... args) {
|
||||
try {
|
||||
return invoke(instance, methodName, args);
|
||||
} catch (Throwable ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user