Added Computer interface upgrades

This commit is contained in:
Unknown 2019-01-04 19:09:11 +01:00 committed by unknown
parent f33c1d3a54
commit 0c1a0bfdd0
20 changed files with 169 additions and 31 deletions

View file

@ -2,6 +2,9 @@ package cr0s.warpdrive.api.computer;
public interface IInterfaced {
// return true if it supports the interface
boolean isInterfaceEnabled();
// return true if it supports the interface
Object[] isInterfaced();

View file

@ -42,6 +42,6 @@ public abstract class TileEntityAbstractEnergyCoreOrController extends TileEntit
getClass().getSimpleName(),
name,
Commons.format(world, pos),
connectedComputers == null ? "~NULL~" : connectedComputers );
CC_connectedComputers == null ? "~NULL~" : CC_connectedComputers);
}
}

View file

@ -5,6 +5,7 @@ import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.api.FunctionGet;
import cr0s.warpdrive.api.FunctionSetVector;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.data.EnumComponentType;
import cr0s.warpdrive.data.Vector3;
import cr0s.warpdrive.data.VectorI;
import dan200.computercraft.api.ComputerCraftAPI;
@ -48,6 +49,7 @@ public abstract class TileEntityAbstractInterfaced extends TileEntityAbstractBas
// Common computer properties
protected String peripheralName = null;
private String[] methodsArray = {};
private boolean isAlwaysInterfaced = true;
// String returned to LUA script in case of error
public static final String COMPUTER_ERROR_TAG = "!ERROR!";
@ -59,12 +61,11 @@ public abstract class TileEntityAbstractInterfaced extends TileEntityAbstractBas
protected volatile List<String> CC_scripts = null;
// OpenComputer specific properties
protected boolean OC_enable = true;
protected Node OC_node = null;
protected boolean OC_addedToNetwork = false;
// ComputerCraft specific properties
protected final HashMap<Integer, IComputerAccess> connectedComputers = new HashMap<>();
protected final HashMap<Integer, IComputerAccess> CC_connectedComputers = new HashMap<>();
public TileEntityAbstractInterfaced() {
super();
@ -79,6 +80,46 @@ public abstract class TileEntityAbstractInterfaced extends TileEntityAbstractBas
}
// WarpDrive abstraction layer
protected void doRequireUpgradeToInterface() {
assert isAlwaysInterfaced;
isAlwaysInterfaced = false;
setUpgradeMaxCount(EnumComponentType.COMPUTER_INTERFACE, 1);
}
@Override
public boolean mountUpgrade(final Object upgrade) {
final boolean isSuccess = super.mountUpgrade(upgrade);
if (isSuccess) {
if (WarpDriveConfig.isComputerCraftLoaded) {
CC_mount();
}
if (WarpDriveConfig.isOpenComputersLoaded) {
OC_constructor();
}
}
return isSuccess;
}
@Override
public boolean dismountUpgrade(final Object upgrade) {
final boolean isSuccess = super.dismountUpgrade(upgrade);
if (isSuccess) {
if (WarpDriveConfig.isComputerCraftLoaded) {
CC_unmount();
}
if (WarpDriveConfig.isOpenComputersLoaded) {
OC_destructor();
}
}
return isSuccess;
}
@Override
public boolean isInterfaceEnabled() {
return isAlwaysInterfaced || getUpgradeCount(EnumComponentType.COMPUTER_INTERFACE) > 0;
}
protected void addMethods(final String[] methodsToAdd) {
if (methodsArray == null) {
methodsArray = methodsToAdd;
@ -97,12 +138,13 @@ public abstract class TileEntityAbstractInterfaced extends TileEntityAbstractBas
return (url != null);
}
// TileEntity overrides
@Override
public void update() {
super.update();
if (WarpDriveConfig.isOpenComputersLoaded) {
if (!OC_addedToNetwork && OC_enable) {
if (!OC_addedToNetwork && isInterfaceEnabled()) {
OC_addedToNetwork = true;
Network.joinOrCreateNetwork(this);
}
@ -117,7 +159,7 @@ public abstract class TileEntityAbstractInterfaced extends TileEntityAbstractBas
}
// deferred constructor so the derived class can finish it's initialization first
if (WarpDriveConfig.isOpenComputersLoaded && OC_node == null) {
if (WarpDriveConfig.isOpenComputersLoaded && OC_node == null && isInterfaceEnabled()) {
OC_constructor();
}
super.validate();
@ -126,10 +168,7 @@ public abstract class TileEntityAbstractInterfaced extends TileEntityAbstractBas
@Override
public void invalidate() {
if (WarpDriveConfig.isOpenComputersLoaded) {
if (OC_node != null) {
OC_node.remove();
OC_node = null;
}
OC_destructor();
}
super.invalidate();
}
@ -137,10 +176,7 @@ public abstract class TileEntityAbstractInterfaced extends TileEntityAbstractBas
@Override
public void onChunkUnload() {
if (WarpDriveConfig.isOpenComputersLoaded) {
if (OC_node != null) {
OC_node.remove();
OC_node = null;
}
OC_destructor();
}
super.onChunkUnload();
}
@ -149,7 +185,8 @@ public abstract class TileEntityAbstractInterfaced extends TileEntityAbstractBas
public void readFromNBT(final NBTTagCompound tagCompound) {
super.readFromNBT(tagCompound);
if ( WarpDriveConfig.isOpenComputersLoaded
&& FMLCommonHandler.instance().getEffectiveSide().isServer() ) {
&& FMLCommonHandler.instance().getEffectiveSide().isServer()
&& isInterfaceEnabled() ) {
if (OC_node == null) {
OC_constructor();
}
@ -200,7 +237,11 @@ public abstract class TileEntityAbstractInterfaced extends TileEntityAbstractBas
return (((((super.hashCode() + (world == null ? 0 : world.provider.getDimension()) << 4) + pos.getX()) << 4) + pos.getY()) << 4) + pos.getZ();
}
// Dirty cheap conversion methods
// Interface proxies are used to
// - convert arguments,
// - log LUA calls,
// - block connection when missing the Computer interface upgrade
// note: direct API calls remains possible without upgrade, as it's lore dependant
@Optional.Method(modid = "opencomputers")
protected Object[] OC_convertArgumentsAndLogCall(final Context context, final Arguments args) {
final Object[] arguments = new Object[args.count()];
@ -219,6 +260,9 @@ public abstract class TileEntityAbstractInterfaced extends TileEntityAbstractBas
Commons.format(world, pos),
peripheralName, context, methodName, Commons.format(arguments)));
}
if (!isInterfaceEnabled()) {
throw new RuntimeException("Missing Computer interface upgrade.");
}
return arguments;
}
@ -230,13 +274,20 @@ public abstract class TileEntityAbstractInterfaced extends TileEntityAbstractBas
Commons.format(world, pos),
peripheralName, methodName, Commons.format(arguments)));
}
if (!isInterfaceEnabled() && !methodName.equals("isInterfaced")) {
throw new RuntimeException("Missing Computer interface upgrade.");
}
return methodName;
}
// Common OC/CC methods
@Override
public Object[] isInterfaced() {
return new Object[] { true, "I'm a WarpDrive computer interfaced tile entity." };
if (isInterfaceEnabled()) {
return new Object[] { true, "I'm a WarpDrive computer interfaced tile entity." };
} else {
return new Object[] { false, "Missing Computer interface upgrade." };
}
}
@Override
@ -377,9 +428,23 @@ public abstract class TileEntityAbstractInterfaced extends TileEntityAbstractBas
@Override
@Optional.Method(modid = "computercraft")
public void attach(@Nonnull final IComputerAccess computer) {
final int id = computer.getID();
connectedComputers.put(id, computer);
public void attach(@Nonnull final IComputerAccess computerAccess) {
final int id = computerAccess.getID();
CC_connectedComputers.put(id, computerAccess);
if (isInterfaceEnabled()) {
CC_mount(computerAccess);
}
}
@Optional.Method(modid = "computercraft")
private void CC_mount() {
for (final IComputerAccess computerAccess : CC_connectedComputers.values()) {
CC_mount(computerAccess);
}
}
@Optional.Method(modid = "computercraft")
private void CC_mount(@Nonnull final IComputerAccess computer) {
if (CC_hasResource && WarpDriveConfig.G_LUA_SCRIPTS != WarpDriveConfig.LUA_SCRIPTS_NONE) {
try {
final String modid = WarpDrive.MODID.toLowerCase();
@ -402,11 +467,45 @@ public abstract class TileEntityAbstractInterfaced extends TileEntityAbstractBas
}
}
@Optional.Method(modid = "computercraft")
private void CC_unmount() {
for (final IComputerAccess computerAccess : CC_connectedComputers.values()) {
CC_unmount(computerAccess);
}
}
@Optional.Method(modid = "computercraft")
private void CC_unmount(@Nonnull final IComputerAccess computer) {
if (CC_hasResource && WarpDriveConfig.G_LUA_SCRIPTS != WarpDriveConfig.LUA_SCRIPTS_NONE) {
try {
final String modid = WarpDrive.MODID.toLowerCase();
final String folderPeripheral = peripheralName.replace(modid, modid + "/");
computer.unmount("/" + modid );
computer.unmount("/" + folderPeripheral);
computer.unmount("/warpupdater" );
if (WarpDriveConfig.G_LUA_SCRIPTS == WarpDriveConfig.LUA_SCRIPTS_ALL) {
for (final String script : CC_scripts) {
computer.unmount("/" + script);
}
}
} catch (final Exception exception) {
exception.printStackTrace();
WarpDrive.logger.error(String.format("Failed to unmount ComputerCraft scripts for %s %s, isFirstTick %s",
peripheralName,
Commons.format(world, pos),
isFirstTick()));
}
}
}
@Override
@Optional.Method(modid = "computercraft")
public void detach(@Nonnull final IComputerAccess computer) {
if (isInterfaceEnabled()) {
CC_unmount(computer);
}
final int id = computer.getID();
connectedComputers.remove(id);
CC_connectedComputers.remove(id);
}
@Override
@ -417,13 +516,16 @@ public abstract class TileEntityAbstractInterfaced extends TileEntityAbstractBas
// Computer abstraction methods
protected void sendEvent(final String eventName, final Object... arguments) {
if (!isInterfaceEnabled()) {
return;
}
if (WarpDriveConfig.LOGGING_LUA) {
WarpDrive.logger.info(this + " Sending event '" + eventName + "'");
}
if (WarpDriveConfig.isComputerCraftLoaded) {
for (final Map.Entry<Integer, IComputerAccess> integerIComputerAccessEntry : connectedComputers.entrySet()) {
final IComputerAccess comp = integerIComputerAccessEntry.getValue();
comp.queueEvent(eventName, arguments);
for (final Map.Entry<Integer, IComputerAccess> integerIComputerAccessEntry : CC_connectedComputers.entrySet()) {
final IComputerAccess computerAccess = integerIComputerAccessEntry.getValue();
computerAccess.queueEvent(eventName, arguments);
}
}
if (WarpDriveConfig.isOpenComputersLoaded) {
@ -485,6 +587,20 @@ public abstract class TileEntityAbstractInterfaced extends TileEntityAbstractBas
OC_fileSystem = FileSystem.asManagedEnvironment(FileSystem.fromClass(getClass(), WarpDrive.MODID.toLowerCase(), "lua.OpenComputers/" + peripheralName), peripheralName);
((Component) OC_fileSystem.node()).setVisibility(Visibility.Network);
}
// note: we can't join the network right away, it's postponed to next tick
}
@Optional.Method(modid = "opencomputers")
private void OC_destructor() {
if (OC_node != null) {
if (OC_fileSystem != null) {
OC_fileSystem.node().remove();
OC_fileSystem = null;
}
OC_node.remove();
OC_node = null;
OC_addedToNetwork = false;
}
}
@Override

View file

@ -43,6 +43,7 @@ public class TileEntityChunkLoader extends TileEntityAbstractChunkLoading {
"bounds",
"radius",
});
doRequireUpgradeToInterface();
setUpgradeMaxCount(EnumComponentType.SUPERCONDUCTOR, 5);
setUpgradeMaxCount(EnumComponentType.EMERALD_CRYSTAL, WarpDriveConfig.CHUNK_LOADER_MAX_RADIUS);

View file

@ -83,6 +83,8 @@ public class TileEntityLaser extends TileEntityAbstractLaser implements IBeamFre
"beamFrequency",
"getScanResult"
});
doRequireUpgradeToInterface();
laserMedium_maxCount = WarpDriveConfig.LASER_CANNON_MAX_MEDIUMS_COUNT;
}

View file

@ -21,7 +21,7 @@ public class TileEntityLaserMedium extends TileEntityAbstractEnergy {
super();
peripheralName = "warpdriveLaserMedium";
OC_enable = false;
doRequireUpgradeToInterface();
}
@Override

View file

@ -29,6 +29,7 @@ public class TileEntityAirGeneratorTiered extends TileEntityAbstractEnergyConsum
peripheralName = "warpdriveAirGenerator";
// addMethods(new String[] {
// });
doRequireUpgradeToInterface();
}
@Override

View file

@ -102,8 +102,10 @@ public class TileEntityLaserTreeFarm extends TileEntityAbstractMiner {
"silktouch",
"tapTrees"
});
laserMedium_maxCount = WarpDriveConfig.TREE_FARM_MAX_MEDIUMS_COUNT;
CC_scripts = Arrays.asList("farm", "stop");
doRequireUpgradeToInterface();
laserMedium_maxCount = WarpDriveConfig.TREE_FARM_MAX_MEDIUMS_COUNT;
}
@Override
@ -125,14 +127,14 @@ public class TileEntityLaserTreeFarm extends TileEntityAbstractMiner {
return;
}
IBlockState blockState = world.getBlockState(pos);
final IBlockState blockState = world.getBlockState(pos);
if (currentState == STATE_IDLE) {
delayTicks = 0;
delayTargetTicks = TREE_FARM_WARMUP_DELAY_TICKS;
updateBlockState(blockState, BlockLaserTreeFarm.MODE, EnumLaserTreeFarmMode.INACTIVE);
// force start if no computer control is available
if (!WarpDriveConfig.isComputerCraftLoaded && !WarpDriveConfig.isOpenComputersLoaded) {
if (!isInterfaceEnabled()) {
breakLeaves = true;
enableSilktouch = false;
tapTrees = true;

View file

@ -73,6 +73,8 @@ public class TileEntityMiningLaser extends TileEntityAbstractMiner {
"silktouch"
});
CC_scripts = Arrays.asList("mine", "stop");
doRequireUpgradeToInterface();
laserMedium_maxCount = WarpDriveConfig.MINING_LASER_MAX_MEDIUMS_COUNT;
}
@ -97,7 +99,7 @@ public class TileEntityMiningLaser extends TileEntityAbstractMiner {
updateBlockState(blockState, BlockMiningLaser.MODE, EnumMiningLaserMode.INACTIVE);
// force start if no computer control is available
if (!WarpDriveConfig.isComputerCraftLoaded && !WarpDriveConfig.isOpenComputersLoaded) {
if (!isInterfaceEnabled()) {
enableSilktouch = false;
layerOffset = 1;
mineAllBlocks = true;

View file

@ -38,6 +38,7 @@ public class TileEntityCamera extends TileEntityAbstractMachine implements IVide
addMethods(new String[] {
"videoChannel"
});
doRequireUpgradeToInterface();
}
@Override

View file

@ -34,6 +34,7 @@ public class TileEntityMonitor extends TileEntityAbstractMachine implements IVid
addMethods(new String[] {
"videoChannel"
});
doRequireUpgradeToInterface();
}
@Override

View file

@ -271,8 +271,8 @@ public class TileEntityRadar extends TileEntityAbstractEnergyConsumer {
// ComputerCraft IPeripheral methods
@Override
@Optional.Method(modid = "computercraft")
public void attach(@Nonnull final IComputerAccess computer) {
super.attach(computer);
public void attach(@Nonnull final IComputerAccess computerAccess) {
super.attach(computerAccess);
if (getBlockMetadata() == 0) {
updateBlockState(null, BlockRadar.MODE, EnumRadarMode.ACTIVE);
}
@ -282,7 +282,7 @@ public class TileEntityRadar extends TileEntityAbstractEnergyConsumer {
@Optional.Method(modid = "computercraft")
public void detach(@Nonnull final IComputerAccess computer) {
super.detach(computer);
if (connectedComputers.isEmpty()) {
if (CC_connectedComputers.isEmpty()) {
updateBlockState(null, BlockRadar.MODE, EnumRadarMode.INACTIVE);
}
}

View file

@ -31,6 +31,8 @@ public class TileEntitySiren extends TileEntityAbstractMachine {
public TileEntitySiren() {
super();
doRequireUpgradeToInterface();
}
@Override

View file

@ -33,6 +33,7 @@ public class TileEntityCapacitor extends TileEntityAbstractEnergy {
super();
peripheralName = "warpdriveCapacitor";
doRequireUpgradeToInterface();
setUpgradeMaxCount(EnumComponentType.SUPERCONDUCTOR, WarpDriveConfig.CAPACITOR_EFFICIENCY_PER_UPGRADE.length - 1);
}

View file

@ -40,6 +40,7 @@ public class TileEntityIC2reactorLaserMonitor extends TileEntityAbstractLaser {
laserMedium_maxCount = 1;
peripheralName = "warpdriveIC2reactorLaserCooler";
doRequireUpgradeToInterface();
}
// returns IReactor tile entities

View file

@ -133,6 +133,7 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField
"translation"
});
CC_scripts = Arrays.asList("enable", "disable");
doRequireUpgradeToInterface();
for (final EnumForceFieldUpgrade enumForceFieldUpgrade : EnumForceFieldUpgrade.values()) {
if (enumForceFieldUpgrade.maxCountOnProjector > 0) {

View file

@ -24,6 +24,7 @@ public class TileEntityForceFieldRelay extends TileEntityAbstractForceField impl
super();
peripheralName = "warpdriveForceFieldRelay";
doRequireUpgradeToInterface();
}
// onFirstUpdateTick

View file

@ -53,6 +53,7 @@ public class TileEntityLift extends TileEntityAbstractEnergyConsumer implements
"mode",
"state"
});
doRequireUpgradeToInterface();
}
@Override

View file

@ -49,6 +49,7 @@ public class TileEntityTransporterBeacon extends TileEntityAbstractEnergyConsume
addMethods(new String[] {
"isActive"
});
doRequireUpgradeToInterface();
}
@Override

View file

@ -38,6 +38,7 @@ public class TileEntityLaserCamera extends TileEntityLaser implements IVideoChan
addMethods(new String[] {
"videoChannel"
});
// done by ancestor: doRequireUpgradeToInterface();
}
@Override