diff --git a/src/main/java/cr0s/warpdrive/api/FunctionGet.java b/src/main/java/cr0s/warpdrive/api/FunctionGet.java new file mode 100644 index 00000000..9d073f40 --- /dev/null +++ b/src/main/java/cr0s/warpdrive/api/FunctionGet.java @@ -0,0 +1,6 @@ +package cr0s.warpdrive.api; + +public interface FunctionGet { + + Return apply(); +} diff --git a/src/main/java/cr0s/warpdrive/api/FunctionSetVector.java b/src/main/java/cr0s/warpdrive/api/FunctionSetVector.java new file mode 100644 index 00000000..26abb45e --- /dev/null +++ b/src/main/java/cr0s/warpdrive/api/FunctionSetVector.java @@ -0,0 +1,6 @@ +package cr0s.warpdrive.api; + +public interface FunctionSetVector { + + void apply(Component x, Component y, Component z); +} diff --git a/src/main/java/cr0s/warpdrive/api/computer/IInterfaced.java b/src/main/java/cr0s/warpdrive/api/computer/IInterfaced.java index 23ccf621..fe943e19 100644 --- a/src/main/java/cr0s/warpdrive/api/computer/IInterfaced.java +++ b/src/main/java/cr0s/warpdrive/api/computer/IInterfaced.java @@ -2,12 +2,18 @@ package cr0s.warpdrive.api.computer; public interface IInterfaced { - // Declare type - Object[] interfaced(); + // return true if it supports the interface + Object[] isInterfaced(); - // Return block coordinates - Object[] position(); + // return local block coordinates + Object[] getLocalPosition(); - // Return version - Object[] version(); + // return tier index and name + Object[] getTier(); + + // return upgradability and status + Object[] getUpgrades(); + + // return the mod version + Integer[] getVersion(); } diff --git a/src/main/java/cr0s/warpdrive/block/TileEntityAbstractInterfaced.java b/src/main/java/cr0s/warpdrive/block/TileEntityAbstractInterfaced.java index ce357a74..16184174 100644 --- a/src/main/java/cr0s/warpdrive/block/TileEntityAbstractInterfaced.java +++ b/src/main/java/cr0s/warpdrive/block/TileEntityAbstractInterfaced.java @@ -2,8 +2,10 @@ package cr0s.warpdrive.block; import cr0s.warpdrive.Commons; import cr0s.warpdrive.WarpDrive; +import cr0s.warpdrive.api.FunctionGet; +import cr0s.warpdrive.api.FunctionSetVector; import cr0s.warpdrive.config.WarpDriveConfig; -import cr0s.warpdrive.data.EnumTier; +import cr0s.warpdrive.data.Vector3; import cr0s.warpdrive.data.VectorI; import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.lua.ILuaContext; @@ -68,9 +70,11 @@ public abstract class TileEntityAbstractInterfaced extends TileEntityAbstractBas super(); addMethods(new String[] { - "interfaced", - "position", - "version" + "isInterfaced", + "getLocalPosition", + "getTier", + "getUpgrades", + "getVersion", }); } @@ -229,21 +233,28 @@ public abstract class TileEntityAbstractInterfaced extends TileEntityAbstractBas return methodName; } - // Declare type + // Common OC/CC methods @Override - public Object[] interfaced() { - return new String[] { "I'm a WarpDrive computer interfaced tile entity." }; + public Object[] isInterfaced() { + return new Object[] { true, "I'm a WarpDrive computer interfaced tile entity." }; } - // Return block coordinates @Override - public Object[] position() { - return new Object[] { pos.getX(), pos.getY(), pos.getZ(), "?", pos.getX(), pos.getY(), pos.getZ() }; + public Object[] getLocalPosition() { + return new Object[] { pos.getX(), pos.getY(), pos.getZ() }; } - // Return version @Override - public Object[] version() { + public Object[] getTier() { + return new Object[] { enumTier.getIndex(), enumTier.getName() }; + } + + public Object[] getUpgrades() { + return new Object[] { isUpgradeable(), getUpgradesAsString() }; + } + + @Override + public Integer[] getVersion() { if (WarpDriveConfig.LOGGING_LUA) { WarpDrive.logger.info(String.format("Version is %s isDev %s", WarpDrive.VERSION, WarpDrive.isDev)); } @@ -257,7 +268,7 @@ public abstract class TileEntityAbstractInterfaced extends TileEntityAbstractBas for (final String string : strings) { integers.add(Integer.parseInt(string)); } - return integers.toArray(); + return integers.toArray(new Integer[0]); } // ComputerCraft IPeripheral methods @@ -289,6 +300,39 @@ public abstract class TileEntityAbstractInterfaced extends TileEntityAbstractBas return vDefault; } + protected Object[] computer_getOrSetVector3(final FunctionGet getVector, final FunctionSetVector setVector, final Object[] arguments) { + if ( arguments != null + && arguments.length > 0 + && arguments[0] != null ) { + try { + if (arguments.length == 1) { + final float value = Commons.toFloat(arguments[0]); + setVector.apply(value, value, value); + } else if (arguments.length == 2) { + final float valueXZ = Commons.toFloat(arguments[0]); + final float valueY = Commons.toFloat(arguments[1]); + setVector.apply(valueXZ, valueY, valueXZ); + } else if (arguments.length == 3) { + final float valueX = Commons.toFloat(arguments[0]); + final float valueY = Commons.toFloat(arguments[1]); + final float valueZ = Commons.toFloat(arguments[2]); + setVector.apply(valueX, valueY, valueZ); + } + } catch (final Exception exception) { + final String message = String.format("Float expected for all arguments %s", + Arrays.toString(arguments)); + if (WarpDriveConfig.LOGGING_LUA) { + WarpDrive.logger.error(String.format("%s LUA error on %s: %s", + this, setVector, message)); + } + final Vector3 v3Actual = getVector.apply(); + return new Object[] { v3Actual.x, v3Actual.y, v3Actual.z, message }; + } + } + final Vector3 v3Actual = getVector.apply(); + return new Double[] { v3Actual.x, v3Actual.y, v3Actual.z }; + } + protected UUID computer_getUUID(final UUID uuidDefault, final Object[] arguments) { try { if (arguments.length == 1 && arguments[0] != null) { @@ -311,14 +355,20 @@ public abstract class TileEntityAbstractInterfaced extends TileEntityAbstractBas final String methodName = CC_getMethodNameAndLogCall(method, arguments); switch (methodName) { - case "interfaced": - return interfaced(); + case "isInterfaced": + return isInterfaced(); - case "position": - return position(); + case "getLocalPosition": + return getLocalPosition(); - case "version": - return version(); + case "getTier": + return getTier(); + + case "getUpgrades": + return getUpgrades(); + + case "getVersion": + return getVersion(); } return null; @@ -396,20 +446,32 @@ public abstract class TileEntityAbstractInterfaced extends TileEntityAbstractBas // OpenComputers methods @Callback @Optional.Method(modid = "opencomputers") - public Object[] position(final Context context, final Arguments arguments) { - return position(); + public Object[] isInterfaced(final Context context, final Arguments arguments) { + return isInterfaced(); } @Callback @Optional.Method(modid = "opencomputers") - public Object[] version(final Context context, final Arguments arguments) { - return version(); + public Object[] getLocalPosition(final Context context, final Arguments arguments) { + return getLocalPosition(); } @Callback @Optional.Method(modid = "opencomputers") - public Object[] interfaced(final Context context, final Arguments arguments) { - return interfaced(); + public Object[] getUpgrades(final Context context, final Arguments arguments) { + return getUpgrades(); + } + + @Callback + @Optional.Method(modid = "opencomputers") + public Object[] getTier(final Context context, final Arguments arguments) { + return getTier(); + } + + @Callback + @Optional.Method(modid = "opencomputers") + public Object[] getVersion(final Context context, final Arguments arguments) { + return getVersion(); } @Optional.Method(modid = "opencomputers") diff --git a/src/main/java/cr0s/warpdrive/block/TileEntityChunkLoader.java b/src/main/java/cr0s/warpdrive/block/TileEntityChunkLoader.java index 79994eef..ea1f74e0 100644 --- a/src/main/java/cr0s/warpdrive/block/TileEntityChunkLoader.java +++ b/src/main/java/cr0s/warpdrive/block/TileEntityChunkLoader.java @@ -44,7 +44,6 @@ public class TileEntityChunkLoader extends TileEntityAbstractChunkLoading { "enable", "bounds", "radius", - "upgrades", "getEnergyRequired" }); @@ -203,10 +202,6 @@ public class TileEntityChunkLoader extends TileEntityAbstractChunkLoading { return new Object[] { radiusXneg, radiusXpos, radiusZneg, radiusZpos }; } - public Object[] upgrades() { - return new Object[] { getUpgradesAsString() }; - } - public Object[] getEnergyRequired() { return new Object[] { chunkloading_getEnergyRequired() }; } @@ -230,12 +225,6 @@ public class TileEntityChunkLoader extends TileEntityAbstractChunkLoading { return radius(OC_convertArgumentsAndLogCall(context, arguments)); } - @Callback - @Optional.Method(modid = "opencomputers") - public Object[] upgrades(final Context context, final Arguments arguments) { - return upgrades(); - } - @Callback @Optional.Method(modid = "opencomputers") public Object[] getEnergyRequired(final Context context, final Arguments arguments) { @@ -258,9 +247,6 @@ public class TileEntityChunkLoader extends TileEntityAbstractChunkLoading { case "enable": return enable(arguments); - case "upgrades": - return upgrades(); - case "getEnergyRequired": return getEnergyRequired(); } diff --git a/src/main/java/cr0s/warpdrive/block/detection/TileEntityRadar.java b/src/main/java/cr0s/warpdrive/block/detection/TileEntityRadar.java index fb656d1b..f567bd4d 100644 --- a/src/main/java/cr0s/warpdrive/block/detection/TileEntityRadar.java +++ b/src/main/java/cr0s/warpdrive/block/detection/TileEntityRadar.java @@ -42,6 +42,7 @@ public class TileEntityRadar extends TileEntityAbstractEnergy { peripheralName = "warpdriveRadar"; addMethods(new String[] { + "getGlobalPosition", "radius", "getEnergyRequired", "start", @@ -107,14 +108,14 @@ public class TileEntityRadar extends TileEntityAbstractEnergy { } // Common OC/CC methods - @Override - public Object[] position() { + public Object[] getGlobalPosition() { final CelestialObject celestialObject = CelestialObjectManager.get(world, pos.getX(), pos.getZ()); if (celestialObject != null) { + final String galaxyName = StarMapRegistry.getGalaxyName(celestialObject, pos.getX(), pos.getY(), pos.getZ()); final Vector3 vec3Position = StarMapRegistry.getUniversalCoordinates(celestialObject, pos.getX(), pos.getY(), pos.getZ()); - return new Object[] { pos.getX(), pos.getY(), pos.getZ(), celestialObject.getDisplayName(), vec3Position.x, vec3Position.y, vec3Position.z }; + return new Object[] { galaxyName, celestialObject.getDisplayName(), vec3Position.x, vec3Position.y, vec3Position.z }; } else { - return new Object[] { pos.getX(), pos.getY(), pos.getZ(), Commons.format(world), pos.getX(), pos.getY(), pos.getZ() }; + return new Object[] { StarMapRegistry.GALAXY_UNDEFINED, Commons.format(world), pos.getX(), pos.getY(), pos.getZ() }; } } @@ -227,14 +228,14 @@ public class TileEntityRadar extends TileEntityAbstractEnergy { // OpenComputer callback methods @Callback @Optional.Method(modid = "opencomputers") - public Object[] radius(final Context context, final Arguments arguments) { - return radius(OC_convertArgumentsAndLogCall(context, arguments)); + public Object[] getGlobalPosition(final Context context, final Arguments arguments) { + return getGlobalPosition(); } @Callback @Optional.Method(modid = "opencomputers") - public Object[] getEnergyRequired(final Context context, final Arguments arguments) { - return getEnergyRequired(OC_convertArgumentsAndLogCall(context, arguments)); + public Object[] radius(final Context context, final Arguments arguments) { + return radius(OC_convertArgumentsAndLogCall(context, arguments)); } @Callback @@ -292,6 +293,9 @@ public class TileEntityRadar extends TileEntityAbstractEnergy { final String methodName = CC_getMethodNameAndLogCall(method, arguments); switch (methodName) { + case "getGlobalPosition": + return getGlobalPosition(); + case "radius": return radius(arguments); diff --git a/src/main/java/cr0s/warpdrive/block/forcefield/TileEntityForceFieldProjector.java b/src/main/java/cr0s/warpdrive/block/forcefield/TileEntityForceFieldProjector.java index dfa471da..e4b44bc4 100644 --- a/src/main/java/cr0s/warpdrive/block/forcefield/TileEntityForceFieldProjector.java +++ b/src/main/java/cr0s/warpdrive/block/forcefield/TileEntityForceFieldProjector.java @@ -1175,6 +1175,61 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField return bResult; } + // Common OC/CC methods + @Override + public Object[] getEnergyRequired() { + return new Object[0]; // @TODO getEnergyRequired for projector + } + + private Object[] state() { // isConnected, isPowered, shape + final int energy = energy_getEnergyStored(); + final String status = getStatusHeaderInPureText(); + return new Object[] { status, isEnabled, isConnected, isPowered, getShape().name(), energy }; + } + + public Object[] min(final Object[] arguments) { + return computer_getOrSetVector3(this::getMin, this::setMin, arguments); + } + + public Object[] max(final Object[] arguments) { + return computer_getOrSetVector3(this::getMax, this::setMax, arguments); + } + + public Object[] rotation(final Object[] arguments) { + if ( arguments != null + && arguments.length > 0 + && arguments[0] != null ) { + try { + if (arguments.length == 1) { + final float value = Commons.toFloat(arguments[0]); + setRotation(value, 0, 0); + } else if (arguments.length == 2) { + final float value1 = Commons.toFloat(arguments[0]); + final float value2 = Commons.toFloat(arguments[1]); + setRotation(value1, value2, 0); + } else if (arguments.length == 3) { + final float value1 = Commons.toFloat(arguments[0]); + final float value2 = Commons.toFloat(arguments[1]); + final float value3 = Commons.toFloat(arguments[2]); + setRotation(value1, value2, value3); + } + } catch (final Exception exception) { + final String message = String.format("Float expected for all arguments %s", + Arrays.toString(arguments)); + if (WarpDriveConfig.LOGGING_LUA) { + WarpDrive.logger.error(String.format("%s LUA error on rotation(): %s", + this, message)); + } + return new Object[] { rotationYaw, rotationPitch, rotationRoll, message }; + } + } + return new Float[] { rotationYaw, rotationPitch, rotationRoll }; + } + + public Object[] translation(final Object[] arguments) { + return computer_getOrSetVector3(this::getTranslation, this::setTranslation, arguments); + } + // OpenComputer callback methods @Callback @Optional.Method(modid = "opencomputers") @@ -1185,60 +1240,25 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField @Callback @Optional.Method(modid = "opencomputers") public Object[] min(final Context context, final Arguments arguments) { - if (arguments.count() == 1) { - setMin((float)arguments.checkDouble(0), (float)arguments.checkDouble(0), (float)arguments.checkDouble(0)); - } else if (arguments.count() == 2) { - setMin((float)arguments.checkDouble(0), (float)arguments.checkDouble(1), (float)arguments.checkDouble(0)); - } else if (arguments.count() == 3) { - setMin((float)arguments.checkDouble(0), (float)arguments.checkDouble(1), (float)arguments.checkDouble(2)); - } - return new Double[] { v3Min.x, v3Min.y, v3Min.z }; + return min(OC_convertArgumentsAndLogCall(context, arguments)); } @Callback @Optional.Method(modid = "opencomputers") public Object[] max(final Context context, final Arguments arguments) { - if (arguments.count() == 1) { - setMax((float)arguments.checkDouble(0), (float)arguments.checkDouble(0), (float)arguments.checkDouble(0)); - } else if (arguments.count() == 2) { - setMax((float)arguments.checkDouble(0), (float)arguments.checkDouble(1), (float)arguments.checkDouble(0)); - } else if (arguments.count() == 3) { - setMax((float)arguments.checkDouble(0), (float)arguments.checkDouble(1), (float)arguments.checkDouble(2)); - } - return new Double[] { v3Max.x, v3Max.y, v3Max.z }; + return max(OC_convertArgumentsAndLogCall(context, arguments)); } @Callback @Optional.Method(modid = "opencomputers") public Object[] rotation(final Context context, final Arguments arguments) { - if (arguments.count() == 1) { - setRotation((float)arguments.checkDouble(0), rotationPitch, rotationRoll); - } else if (arguments.count() == 2) { - setRotation((float)arguments.checkDouble(0), (float)arguments.checkDouble(1), rotationRoll); - } else if (arguments.count() == 3) { - setRotation((float)arguments.checkDouble(0), (float)arguments.checkDouble(1), (float)arguments.checkDouble(2)); - } - return new Float[] { rotationYaw, rotationPitch, rotationRoll }; - } - - // Common OC/CC methods - private Object[] state() { // isConnected, isPowered, shape - final int energy = energy_getEnergyStored(); - final String status = getStatusHeaderInPureText(); - return new Object[] { status, isEnabled, isConnected, isPowered, getShape().name(), energy }; + return rotation(OC_convertArgumentsAndLogCall(context, arguments)); } @Callback @Optional.Method(modid = "opencomputers") public Object[] translation(final Context context, final Arguments arguments) { - if (arguments.count() == 1) { - setTranslation((float)arguments.checkDouble(0), (float)arguments.checkDouble(0), (float)arguments.checkDouble(0)); - } else if (arguments.count() == 2) { - setTranslation((float)arguments.checkDouble(0), (float)arguments.checkDouble(1), (float)arguments.checkDouble(0)); - } else if (arguments.count() == 3) { - setTranslation((float)arguments.checkDouble(0), (float)arguments.checkDouble(1), (float)arguments.checkDouble(2)); - } - return new Double[] { v3Translation.x, v3Translation.y, v3Translation.z }; + return translation(OC_convertArgumentsAndLogCall(context, arguments)); } // ComputerCraft IPeripheral methods implementation @@ -1249,47 +1269,19 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField switch (methodName) { case "min": - if (arguments.length == 1 && arguments[0] != null) { - setMin(Commons.toFloat(arguments[0]), Commons.toFloat(arguments[0]), Commons.toFloat(arguments[0])); - } else if (arguments.length == 2) { - setMin(Commons.toFloat(arguments[0]), Commons.toFloat(arguments[1]), Commons.toFloat(arguments[0])); - } else if (arguments.length == 3) { - setMin(Commons.toFloat(arguments[0]), Commons.toFloat(arguments[1]), Commons.toFloat(arguments[2])); - } - return new Double[] { v3Min.x, v3Min.y, v3Min.z }; + return min(arguments); case "max": - if (arguments.length == 1 && arguments[0] != null) { - setMax(Commons.toFloat(arguments[0]), Commons.toFloat(arguments[0]), Commons.toFloat(arguments[0])); - } else if (arguments.length == 2) { - setMax(Commons.toFloat(arguments[0]), Commons.toFloat(arguments[1]), Commons.toFloat(arguments[0])); - } else if (arguments.length == 3) { - setMax(Commons.toFloat(arguments[0]), Commons.toFloat(arguments[1]), Commons.toFloat(arguments[2])); - } - return new Double[] { v3Max.x, v3Max.y, v3Max.z }; + return max(arguments); case "rotation": - if (arguments.length == 1 && arguments[0] != null) { - setRotation(Commons.toFloat(arguments[0]), rotationPitch, rotationRoll); - } else if (arguments.length == 2) { - setRotation(Commons.toFloat(arguments[0]), Commons.toFloat(arguments[1]), rotationRoll); - } else if (arguments.length == 3) { - setRotation(Commons.toFloat(arguments[0]), Commons.toFloat(arguments[1]), Commons.toFloat(arguments[2])); - } - return new Float[] { rotationYaw, rotationPitch, rotationRoll }; + return rotation(arguments); case "state": return state(); case "translation": - if (arguments.length == 1 && arguments[0] != null) { - setTranslation(Commons.toFloat(arguments[0]), Commons.toFloat(arguments[0]), Commons.toFloat(arguments[0])); - } else if (arguments.length == 2) { - setTranslation(Commons.toFloat(arguments[0]), Commons.toFloat(arguments[1]), Commons.toFloat(arguments[0])); - } else if (arguments.length == 3) { - setTranslation(Commons.toFloat(arguments[0]), Commons.toFloat(arguments[1]), Commons.toFloat(arguments[2])); - } - return new Double[] { v3Translation.x, v3Translation.y, v3Translation.z }; + return translation(arguments); } return super.callMethod(computer, context, method, arguments); diff --git a/src/main/java/cr0s/warpdrive/block/movement/TileEntityShipController.java b/src/main/java/cr0s/warpdrive/block/movement/TileEntityShipController.java index eb5809e5..7d2e65e2 100644 --- a/src/main/java/cr0s/warpdrive/block/movement/TileEntityShipController.java +++ b/src/main/java/cr0s/warpdrive/block/movement/TileEntityShipController.java @@ -145,12 +145,12 @@ public class TileEntityShipController extends TileEntityAbstractShipController { // Common OC/CC methods @Override - public Object[] position() { + public Object[] getLocalPosition() { final TileEntityShipCore tileEntityShipCore = tileEntityShipCoreWeakReference == null ? null : tileEntityShipCoreWeakReference.get(); if (tileEntityShipCore == null) { return null; } - return tileEntityShipCore.position(); + return tileEntityShipCore.getLocalPosition(); } @Override diff --git a/src/main/java/cr0s/warpdrive/data/StarMapRegistry.java b/src/main/java/cr0s/warpdrive/data/StarMapRegistry.java index e30b7113..53b8eefe 100644 --- a/src/main/java/cr0s/warpdrive/data/StarMapRegistry.java +++ b/src/main/java/cr0s/warpdrive/data/StarMapRegistry.java @@ -383,6 +383,21 @@ public class StarMapRegistry { return arrayListRadarEchos; } + public static String GALAXY_UNDEFINED = "???"; + public static String getGalaxyName(final CelestialObject celestialObject, final double x, final double y, final double z) { + if (celestialObject == null) { + // not a registered area + return GALAXY_UNDEFINED; + } + CelestialObject celestialObjectNode = celestialObject; + boolean hasHyperspace = celestialObjectNode.isHyperspace(); + while (celestialObjectNode.parent != null) { + celestialObjectNode = celestialObjectNode.parent; + hasHyperspace |= celestialObjectNode.isHyperspace(); + } + return hasHyperspace ? celestialObjectNode.getDisplayName() : GALAXY_UNDEFINED; + } + public static Vector3 getUniversalCoordinates(final CelestialObject celestialObject, final double x, final double y, final double z) { if (celestialObject == null) { // not a registered area