Refactored laser power computations

Fixed free laserTreeFarm leaf harvesting
This commit is contained in:
LemADEC 2015-09-05 21:17:48 +02:00
parent cf34abbfff
commit a145d9b2d7
5 changed files with 342 additions and 331 deletions

View file

@ -1,9 +1,196 @@
package cr0s.warpdrive.block;
import java.util.LinkedList;
import java.util.List;
import li.cil.oc.api.machine.Arguments;
import li.cil.oc.api.machine.Callback;
import li.cil.oc.api.machine.Context;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Optional;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.config.WarpDriveConfig;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.peripheral.IComputerAccess;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
public abstract class TileEntityAbstractLaser extends TileEntityAbstractEnergy
{
// Abstract class to manage laser mediums
public abstract class TileEntityAbstractLaser extends TileEntityAbstractInterfaced {
// direction of the laser medium stack
protected ForgeDirection directionLaserMedium = ForgeDirection.UNKNOWN;
protected ForgeDirection[] directionsValidLaserMedium = ForgeDirection.VALID_DIRECTIONS;
protected int countMaxLaserMediums = 0;
private final int updateInterval_ticks = 20 * WarpDriveConfig.SHIP_CONTROLLER_UPDATE_INTERVAL_SECONDS;
private int updateTicks = updateInterval_ticks;
private int bootTicks = 20;
public TileEntityAbstractLaser() {
super();
addMethods(new String[] {
"energy",
"laserMediumDirection"
});
}
@Override
public void updateEntity() {
super.updateEntity();
if (FMLCommonHandler.instance().getEffectiveSide().isClient()) {
return;
}
// accelerate update ticks during boot
if (bootTicks > 0) {
bootTicks--;
if (directionLaserMedium == ForgeDirection.UNKNOWN) {
updateTicks = 1;
}
}
updateTicks--;
if (updateTicks <= 0) {
updateTicks = updateInterval_ticks;
updateLaserMediumDirection();
}
}
private void updateLaserMediumDirection() {
for(ForgeDirection direction : directionsValidLaserMedium) {
TileEntity tileEntity = worldObj.getTileEntity(xCoord + direction.offsetX, yCoord + direction.offsetY, zCoord + direction.offsetZ);
if (tileEntity != null && tileEntity instanceof TileEntityLaserMedium) {
directionLaserMedium = direction;
return;
}
}
directionLaserMedium = ForgeDirection.UNKNOWN;
return;
}
protected int getEnergyStored() {
return consumeCappedEnergyFromLaserMediums(Integer.MAX_VALUE, true);
}
protected boolean consumeEnergyFromLaserMediums(final int amount, final boolean simulate) {
return amount <= consumeCappedEnergyFromLaserMediums(amount, simulate);
}
protected int consumeCappedEnergyFromLaserMediums(final int amount, final boolean simulate) {
if (directionLaserMedium == ForgeDirection.UNKNOWN) {
return 0;
}
// Primary scan of all laser mediums
int totalEnergy = 0;
int count = 1;
List<TileEntityLaserMedium> laserMediums = new LinkedList();
for (; count <= countMaxLaserMediums; count++) {
TileEntity tileEntity = worldObj.getTileEntity(
xCoord + count * directionLaserMedium.offsetX,
yCoord + count * directionLaserMedium.offsetY,
zCoord + count * directionLaserMedium.offsetZ);
if (!(tileEntity instanceof TileEntityLaserMedium)) {
break;
}
laserMediums.add((TileEntityLaserMedium) tileEntity);
totalEnergy += ((TileEntityLaserMedium) tileEntity).getEnergyStored();
}
count--;
if (count == 0) {
return 0;
}
if (simulate) {
return totalEnergy;
}
// Compute average energy to get per laser medium, capped at its capacity
int energyAverage = amount / count;
int energyLeftOver = amount - energyAverage * count;
if (energyAverage >= WarpDriveConfig.LASER_MEDIUM_MAX_ENERGY_STORED) {
energyAverage = WarpDriveConfig.LASER_MEDIUM_MAX_ENERGY_STORED;
energyLeftOver = 0;
}
WarpDrive.logger.info(this + " !!!capped amount " + amount + " count " + count + " totalEnergy " + totalEnergy + " energyAverage " + energyAverage + " energyLeftOver " + energyLeftOver);
// Secondary scan for laser medium below the required average
for (TileEntityLaserMedium laserMedium : laserMediums) {
int energyStored = laserMedium.getEnergyStored();
if (energyStored < energyAverage) {
energyLeftOver += energyAverage - energyStored;
}
}
WarpDrive.logger.info(this + " !!! energyLeftOver2 " + energyLeftOver);
// Third and final pass for energy consumption
int energyTotalConsumed = 0;
for (TileEntityLaserMedium laserMedium : laserMediums) {
int energyStored = laserMedium.getEnergyStored();
int energyToConsume = Math.min(energyStored, energyAverage + energyLeftOver);
energyLeftOver -= Math.max(0, energyToConsume - energyAverage);
laserMedium.consumeEnergy(energyToConsume, simulate);
energyTotalConsumed += energyToConsume;
}
WarpDrive.logger.info(this + " !!! energyTotalConsumed " + energyTotalConsumed + " energyLeftOver " + energyLeftOver);
return energyTotalConsumed;
}
protected Object[] energy() {
if (directionLaserMedium == ForgeDirection.UNKNOWN) {
return new Object[] { 0, 0 };
} else {
int energyStored = 0;
int energyStoredMax = 0;
int count = 1;
List<TileEntityLaserMedium> laserMediums = new LinkedList();
for (; count <= countMaxLaserMediums; count++) {
TileEntity tileEntity = worldObj.getTileEntity(
xCoord + count * directionLaserMedium.offsetX,
yCoord + count * directionLaserMedium.offsetY,
zCoord + count * directionLaserMedium.offsetZ);
if (!(tileEntity instanceof TileEntityLaserMedium)) {
break;
}
laserMediums.add((TileEntityLaserMedium) tileEntity);
energyStored += ((TileEntityLaserMedium) tileEntity).getEnergyStored();
energyStoredMax += ((TileEntityLaserMedium) tileEntity).getMaxEnergyStored();
}
return new Object[] { energyStored, energyStoredMax };
}
}
protected Object[] laserMediumDirection() {
return new Object[] { directionLaserMedium.name(), directionLaserMedium.offsetX, directionLaserMedium.offsetY, directionLaserMedium.offsetZ };
}
// OpenComputers callback methods
@Callback
@Optional.Method(modid = "OpenComputers")
public Object[] energy(Context context, Arguments arguments) {
return energy();
}
@Callback
@Optional.Method(modid = "OpenComputers")
public Object[] laserMediumDirection(Context context, Arguments arguments) {
return laserMediumDirection();
}
// ComputerCraft methods
@Override
@Optional.Method(modid = "ComputerCraft")
public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments) {
String methodName = getMethodName(method);
if (methodName.equals("energy")) {
return energy();
} else if (methodName.equals("laserMediumDirection")) {
return laserMediumDirection();
}
return super.callMethod(computer, context, method, arguments);
}
}

View file

@ -14,7 +14,6 @@ import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.DamageSource;
import net.minecraft.util.MathHelper;
@ -26,19 +25,19 @@ import cpw.mods.fml.common.Optional;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.data.Vector3;
import cr0s.warpdrive.data.VectorI;
import cr0s.warpdrive.network.PacketHandler;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.peripheral.IComputerAccess;
public class TileEntityLaser extends TileEntityAbstractInterfaced {
public class TileEntityLaser extends TileEntityAbstractLaser {
private final int BEAM_FREQUENCY_SCANNING = 1420;
private final int BEAM_FREQUENCY_MAX = 65000;
private int dx, dz, dy;
private float yaw, pitch; // laser direction
private int beamFrequency = -1;
private int cameraFrequency = -1;
private int videoChannel = -1;
private float r, g, b; // beam color (corresponds to frequency)
public boolean isEmitting = false;
@ -46,10 +45,20 @@ public class TileEntityLaser extends TileEntityAbstractInterfaced {
private int delayTicks = 0;
private int energyFromOtherBeams = 0;
private MovingObjectPosition firstHit_position = null;
private Block firstHit_block;
private int firstHit_blockMeta = 0;
private float firstHit_blockResistance = -2;
public static enum ScanResultType {
IDLE("IDLE"), BLOCK("BLOCK"), NONE("NONE");
public String name;
private ScanResultType(String name) {
this.name = name;
}
}
private ScanResultType scanResult_type = ScanResultType.IDLE;
private VectorI scanResult_position = null;
private String scanResult_blockUnlocalizedName;
private int scanResult_blockMetadata = 0;
private float scanResult_blockResistance = -2;
private final static int REGISTRY_UPDATE_INTERVAL_TICKS = 15 * 20;
private final static int PACKET_SEND_INTERVAL_TICKS = 60 * 20;
@ -59,15 +68,15 @@ public class TileEntityLaser extends TileEntityAbstractInterfaced {
public TileEntityLaser() {
super();
peripheralName = "warpdriveLaser";
methodsArray = new String[] {
"emitBeam", // 0
"pos", // 1
"freq", // 2
"getFirstHit", // 3
"getBoosterDXDZ", // 4
"camFreq" // 5
};
addMethods(new String[] {
"emitBeam",
"beamFrequency",
"getScanResult",
"videoChannel"
});
countMaxLaserMediums = WarpDriveConfig.LASER_CANNON_MAX_MEDIUMS_COUNT;
}
@Override
@ -80,13 +89,13 @@ public class TileEntityLaser extends TileEntityAbstractInterfaced {
packetSendTicks--;
if (packetSendTicks <= 0) {
packetSendTicks = PACKET_SEND_INTERVAL_TICKS;
PacketHandler.sendFreqPacket(worldObj.provider.dimensionId, xCoord, yCoord, zCoord, cameraFrequency);
PacketHandler.sendFreqPacket(worldObj.provider.dimensionId, xCoord, yCoord, zCoord, videoChannel);
}
} else {
registryUpdateTicks--;
if (registryUpdateTicks <= 0) {
registryUpdateTicks = REGISTRY_UPDATE_INTERVAL_TICKS;
WarpDrive.instance.cameras.updateInRegistry(worldObj, new ChunkPosition(xCoord, yCoord, zCoord), cameraFrequency, 1);
WarpDrive.instance.cameras.updateInRegistry(worldObj, new ChunkPosition(xCoord, yCoord, zCoord), videoChannel, 1);
}
}
}
@ -103,7 +112,7 @@ public class TileEntityLaser extends TileEntityAbstractInterfaced {
delayTicks = 0;
isEmitting = false;
int beamEnergy = Math.min(
this.consumeEnergyFromBoosters() + MathHelper.floor_double(energyFromOtherBeams * WarpDriveConfig.LASER_CANNON_BOOSTER_BEAM_ENERGY_EFFICIENCY),
consumeCappedEnergyFromLaserMediums(Integer.MAX_VALUE, false) + MathHelper.floor_double(energyFromOtherBeams * WarpDriveConfig.LASER_CANNON_BOOSTER_BEAM_ENERGY_EFFICIENCY),
WarpDriveConfig.LASER_CANNON_MAX_LASER_ENERGY);
emitBeam(beamEnergy);
energyFromOtherBeams = 0;
@ -131,30 +140,8 @@ public class TileEntityLaser extends TileEntityAbstractInterfaced {
}
}
private int consumeEnergyFromBoosters() {
int energyCollected = 0;
if (findFirstBooster() != null) {
int newX, newY, newZ;
TileEntity te;
for (int shift = 1; shift <= WarpDriveConfig.LASER_CANNON_MAX_MEDIUMS_COUNT; shift++) {
newX = xCoord + (dx * shift);
newY = yCoord + (dy * shift);
newZ = zCoord + (dz * shift);
te = worldObj.getTileEntity(newX, newY, newZ);
if (te != null && te instanceof TileEntityLaserMedium) {
energyCollected += ((TileEntityLaserMedium) te).consumeAllEnergy();
} else {
break;
}
}
}
return energyCollected;
}
private void emitBeam(int beamEnergy) {
int energy = beamEnergy; // FIXME Beam power calculations
int energy = beamEnergy;
int beamLengthBlocks = clamp(0, WarpDriveConfig.LASER_CANNON_RANGE_MAX,
energy / WarpDriveConfig.LASER_CANNON_RANGE_ENERGY_PER_BLOCK);
@ -185,23 +172,30 @@ public class TileEntityLaser extends TileEntityAbstractInterfaced {
// This is a scanning beam, do not deal damage to block nor entity
if (beamFrequency == BEAM_FREQUENCY_SCANNING) {
firstHit_position = worldObj.rayTraceBlocks(vSource.toVec3(), vReachPoint.toVec3());
MovingObjectPosition mopResult = worldObj.rayTraceBlocks(vSource.toVec3(), vReachPoint.toVec3());
if (firstHit_position != null) {
firstHit_block = worldObj.getBlock(firstHit_position.blockX, firstHit_position.blockY, firstHit_position.blockZ);
firstHit_blockMeta = worldObj.getBlockMetadata(firstHit_position.blockX, firstHit_position.blockY, firstHit_position.blockZ);
firstHit_blockResistance = -2;
if (firstHit_block != null) {
firstHit_blockResistance = firstHit_block.getExplosionResistance(null); // TODO: what entity should be used?
scanResult_blockUnlocalizedName = null;
scanResult_blockMetadata = 0;
scanResult_blockResistance = -2;
if (mopResult != null) {
scanResult_type = ScanResultType.BLOCK;
scanResult_position = new VectorI(mopResult.blockX, mopResult.blockY, mopResult.blockZ);
Block block = worldObj.getBlock(scanResult_position.x, scanResult_position.y, scanResult_position.z);
if (block != null) {
scanResult_blockUnlocalizedName = block.getUnlocalizedName();
scanResult_blockMetadata = worldObj.getBlockMetadata(scanResult_position.x, scanResult_position.y, scanResult_position.z);
scanResult_blockResistance = block.getExplosionResistance(null);
}
PacketHandler.sendBeamPacket(worldObj, vSource, new Vector3(firstHit_position.hitVec), r, g, b, 50, energy, 200);
PacketHandler.sendBeamPacket(worldObj, vSource, new Vector3(mopResult.hitVec), r, g, b, 50, energy, 200);
} else {
firstHit_block = null;
firstHit_blockMeta = 0;
firstHit_blockResistance = -2;
scanResult_type = ScanResultType.NONE;
scanResult_position = new VectorI(vReachPoint.intX(), vReachPoint.intY(), vReachPoint.intZ());
PacketHandler.sendBeamPacket(worldObj, vSource, vReachPoint, r, g, b, 50, energy, 200);
}
sendEvent("laserScanning", new Object[] {
scanResult_type.name, scanResult_position.x, scanResult_position.y, scanResult_position.z,
scanResult_blockUnlocalizedName, scanResult_blockMetadata, scanResult_blockResistance });
return;
}
@ -274,7 +268,7 @@ public class TileEntityLaser extends TileEntityAbstractInterfaced {
Block block = worldObj.getBlock(blockHit.blockX, blockHit.blockY, blockHit.blockZ);
// int blockMeta = worldObj.getBlockMetadata(hit.blockX, hit.blockY, hit.blockZ);
float resistance = block.getExplosionResistance(null); // TODO: choose entity
float resistance = block.getExplosionResistance(null);
if (block.isAssociatedBlock(Blocks.bedrock)) {
vHitPoint = new Vector3(blockHit.hitVec);
@ -386,7 +380,7 @@ public class TileEntityLaser extends TileEntityAbstractInterfaced {
public void setBeamFrequency(int parBeamFrequency) {
if (beamFrequency != parBeamFrequency && (parBeamFrequency <= BEAM_FREQUENCY_MAX) && (parBeamFrequency > 0)) {
if (WarpDriveConfig.LOGGING_FREQUENCY) {
if (WarpDriveConfig.LOGGING_VIDEO_CHANNEL) {
WarpDrive.logger.info(this + " Beam frequency set from " + beamFrequency + " to " + parBeamFrequency);
}
beamFrequency = parBeamFrequency;
@ -394,76 +388,22 @@ public class TileEntityLaser extends TileEntityAbstractInterfaced {
updateColor();
}
public int getCameraFrequency() {
return cameraFrequency;
public int getVideoChannel() {
return videoChannel;
}
public void setCameraFrequency(int parCameraFrequency) {
if (cameraFrequency != parCameraFrequency) {
if (WarpDriveConfig.LOGGING_FREQUENCY) {
WarpDrive.logger.info(this + " Camera frequency set from " + cameraFrequency + " to " + parCameraFrequency);
public void setVideoChannel(int parVideoChannel) {
if (videoChannel != parVideoChannel) {
if (WarpDriveConfig.LOGGING_VIDEO_CHANNEL) {
WarpDrive.logger.info(this + " Video channel updated from " + videoChannel + " to " + parVideoChannel);
}
cameraFrequency = parCameraFrequency;
// force update through main thread since CC runs on server as
// 'client'
videoChannel = parVideoChannel;
// force update through main thread since CC runs on server as 'client'
packetSendTicks = 0;
registryUpdateTicks = 0;
}
}
private TileEntityLaserMedium findFirstBooster() {
TileEntity result;
result = worldObj.getTileEntity(xCoord + 1, yCoord, zCoord);
if (result != null && result instanceof TileEntityLaserMedium) {
dx = 1;
dy = 0;
dz = 0;
return (TileEntityLaserMedium) result;
}
result = worldObj.getTileEntity(xCoord - 1, yCoord, zCoord);
if (result != null && result instanceof TileEntityLaserMedium) {
dx = -1;
dy = 0;
dz = 0;
return (TileEntityLaserMedium) result;
}
result = worldObj.getTileEntity(xCoord, yCoord, zCoord + 1);
if (result != null && result instanceof TileEntityLaserMedium) {
dx = 0;
dy = 0;
dz = 1;
return (TileEntityLaserMedium) result;
}
result = worldObj.getTileEntity(xCoord, yCoord, zCoord - 1);
if (result != null && result instanceof TileEntityLaserMedium) {
dx = 0;
dy = 0;
dz = -1;
return (TileEntityLaserMedium) result;
}
result = worldObj.getTileEntity(xCoord, yCoord + 1, zCoord);
if (result != null && result instanceof TileEntityLaserMedium) {
dx = 0;
dy = 1;
dz = 0;
return (TileEntityLaserMedium) result;
}
result = worldObj.getTileEntity(xCoord, yCoord - 1, zCoord);
if (result != null && result instanceof TileEntityLaserMedium) {
dx = 0;
dy = -1;
dz = 0;
return (TileEntityLaserMedium) result;
}
return null;
}
private void playSoundCorrespondsEnergy(int energy) {
if (energy <= 500000) {
worldObj.playSoundEffect(xCoord + 0.5f, yCoord - 0.5f, zCoord + 0.5f, "warpdrive:lowlaser", 4F, 1F);
@ -519,14 +459,14 @@ public class TileEntityLaser extends TileEntityAbstractInterfaced {
public void readFromNBT(NBTTagCompound tag) {
super.readFromNBT(tag);
setBeamFrequency(tag.getInteger("beamFrequency"));
setCameraFrequency(tag.getInteger("cameraFrequency"));
setVideoChannel(tag.getInteger("cameraFrequency") + tag.getInteger("videoChannel"));
}
@Override
public void writeToNBT(NBTTagCompound tag) {
super.writeToNBT(tag);
tag.setInteger("beamFrequency", beamFrequency);
tag.setInteger("cameraFrequency", cameraFrequency);
tag.setInteger("videoChannel", videoChannel);
}
@Override
@ -550,13 +490,7 @@ public class TileEntityLaser extends TileEntityAbstractInterfaced {
@Callback
@Optional.Method(modid = "OpenComputers")
public Object[] pos(Context context, Arguments arguments) {
return new Integer[] { xCoord, yCoord, zCoord };
}
@Callback
@Optional.Method(modid = "OpenComputers")
public Object[] freq(Context context, Arguments arguments) {
public Object[] beamFrequency(Context context, Arguments arguments) {
if (arguments.count() == 1) {
setBeamFrequency(arguments.checkInteger(0));
}
@ -565,25 +499,18 @@ public class TileEntityLaser extends TileEntityAbstractInterfaced {
@Callback
@Optional.Method(modid = "OpenComputers")
public Object[] getFirstHit(Context context, Arguments arguments) {
return getFirstHit();
public Object[] getScanResult(Context context, Arguments arguments) {
return getScanResult();
}
@Callback
@Optional.Method(modid = "OpenComputers")
public Object[] getBoosterDXDZ(Context context, Arguments arguments) {
findFirstBooster();
return new Integer[] { dx, dz };
}
@Callback
@Optional.Method(modid = "OpenComputers")
public Object[] CamFreq(Context context, Arguments arguments) {
public Object[] videoChannel(Context context, Arguments arguments) {
if (isWithCamera()) {
if (arguments.count() == 1) {
setCameraFrequency(arguments.checkInteger(0));
setVideoChannel(arguments.checkInteger(0));
}
return new Integer[] { cameraFrequency };
return new Integer[] { videoChannel };
}
return null;
}
@ -611,22 +538,24 @@ public class TileEntityLaser extends TileEntityAbstractInterfaced {
return new Object[] { true };
}
private Object[] getFirstHit() {
if (firstHit_position != null) {
private Object[] getScanResult() {
if (scanResult_type != ScanResultType.IDLE) {
try {
Object[] info = { firstHit_position.blockX, firstHit_position.blockY, firstHit_position.blockZ, firstHit_block, firstHit_blockMeta,
firstHit_blockResistance };
firstHit_position = null;
firstHit_block = null;
firstHit_blockMeta = 0;
firstHit_blockResistance = -2;
Object[] info = { scanResult_type.name,
scanResult_position.x, scanResult_position.y, scanResult_position.z,
scanResult_blockUnlocalizedName, scanResult_blockMetadata, scanResult_blockResistance };
scanResult_type = ScanResultType.IDLE;
scanResult_position = null;
scanResult_blockUnlocalizedName = null;
scanResult_blockMetadata = 0;
scanResult_blockResistance = -2;
return info;
} catch (Exception e) {
e.printStackTrace();
return new Integer[] { 0, 0, 0, 0, 0, -3 };
} catch (Exception exception) {
exception.printStackTrace();
return new Object[] { COMPUTER_ERROR_TAG, 0, 0, 0, null, 0, -3 };
}
} else {
return new Integer[] { 0, 0, 0, 0, 0, -1 };
return new Object[] { scanResult_type.name, 0, 0, 0, null, 0, -1 };
}
}
@ -634,39 +563,40 @@ public class TileEntityLaser extends TileEntityAbstractInterfaced {
@Override
@Optional.Method(modid = "ComputerCraft")
public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments) {
String methodName = methodsArray[method];
if (methodName.equals("emitBeam")) { // emitBeam(yaw, pitch) or
// emitBeam(deltaX, deltaY,
// deltaZ)
String methodName = getMethodName(method);
if (methodName.equals("emitBeam")) { // emitBeam(yaw, pitch) or emitBeam(deltaX, deltaY, deltaZ)
return emitBeam(arguments);
} else if (methodName.equals("pos")) {
} else if (methodName.equals("position")) {
return new Integer[] { xCoord, yCoord, zCoord };
} else if (methodName.equals("freq")) {
} else if (methodName.equals("beamFrequency")) {
if (arguments.length == 1) {
setBeamFrequency(toInt(arguments[0]));
}
return new Integer[] { beamFrequency };
} else if (methodName.equals("getFirstHit")) {
return getFirstHit();
} else if (methodName.equals("getBoosterDXDZ")) {
findFirstBooster();
return new Integer[] { dx, dz };
} else if (methodName.equals("camFreq")) { // camFreq (only for lasers
// with cam)
} else if (methodName.equals("getScanResult")) {
return getScanResult();
} else if (methodName.equals("videoChannel")) {
// Only valid for lasers with camera
if (isWithCamera()) {
if (arguments.length == 1) {
setCameraFrequency(toInt(arguments[0]));
setVideoChannel(toInt(arguments[0]));
}
return new Integer[] { cameraFrequency };
return new Integer[] { videoChannel };
}
return null;
}
return null;
return super.callMethod(computer, context, method, arguments);
}
@Override
public String toString() {
return String.format("%s Beam \'%d\' Camera \'%d\' @ \'%s\' %d, %d, %d", new Object[] { getClass().getSimpleName(),
beamFrequency, cameraFrequency, worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(), xCoord, yCoord, zCoord });
beamFrequency, videoChannel, worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(), xCoord, yCoord, zCoord });
}
}

View file

@ -12,9 +12,7 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.IFluidBlock;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.block.TileEntityAbstractLaser;
import cr0s.warpdrive.block.TileEntityLaserMedium;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.data.Vector3;
import cr0s.warpdrive.data.VectorI;
@ -26,7 +24,6 @@ public abstract class TileEntityAbstractMiner extends TileEntityAbstractLaser
private boolean silkTouch = false;
private int fortuneLevel = 0;
private TileEntityLaserMedium booster = null;
private Vector3 laserOutput;
abstract boolean canSilkTouch();
@ -124,21 +121,6 @@ public abstract class TileEntityAbstractMiner extends TileEntityAbstractLaser
return fortune();
}
protected TileEntityLaserMedium booster()
{
if (booster == null)
findFirstBooster();
return booster;
}
protected int energy() {
TileEntityLaserMedium te = booster();
if (te != null) {
return te.getEnergyStored();
}
return 0;
}
//DATA RET
protected int calculateLayerCost()
@ -286,36 +268,6 @@ public abstract class TileEntityAbstractMiner extends TileEntityAbstractLaser
return transferred;
}
protected boolean consumeEnergyFromBooster(int requiredEnergy, boolean simulate)
{
TileEntityLaserMedium te = booster();
if (te != null) {
return te.consumeEnergy(requiredEnergy, simulate);
}
return false;
}
private TileEntityLaserMedium findFirstBooster()
{
TileEntity result;
int[] xPos = {1,-1,0,0,0,0};
int[] yPos = {0,0,-1,1,0,0};
int[] zPos = {0,0,0,0,-1,1};
for(int i=0;i<6;i++)
{
result = worldObj.getTileEntity(xCoord + xPos[i], yCoord + yPos[i], zCoord + zPos[i]);
if (result != null && result instanceof TileEntityLaserMedium)
{
booster = (TileEntityLaserMedium) result;
return (TileEntityLaserMedium) result;
}
}
booster = null;
return null;
}
private static ItemStack copyWithSize(ItemStack itemStack, int newSize)
{
ItemStack ret = itemStack.copy();

View file

@ -38,10 +38,8 @@ public class TileEntityLaserTreeFarm extends TileEntityAbstractMiner {
public TileEntityLaserTreeFarm() {
super();
laserOutputSide = ForgeDirection.UP;
IC2_sinkTier = 2;
IC2_sourceTier = 2;
peripheralName = "warpdriveLaserTreefarm";
methodsArray = new String[] {
addMethods(new String[] {
"start",
"stop",
"radius",
@ -50,7 +48,7 @@ public class TileEntityLaserTreeFarm extends TileEntityAbstractMiner {
"silkTouchLeaves",
"treetap",
"state"
};
});
}
@Override
@ -70,21 +68,21 @@ public class TileEntityLaserTreeFarm extends TileEntityAbstractMiner {
} else {
if (scan >= mineWait * delayMul) {
scan = 0;
if (logIndex >= logs.size()) {
mode = 0;
return;
}
VectorI pos = logs.get(logIndex);
Block block = worldObj.getBlock(pos.x, pos.y, pos.z);
if (mode == 1) {
int cost = calculateBlockCost(block);
if (consumeEnergyFromBooster(cost, true)) {
if (consumeEnergyFromLaserMediums(cost, true)) {
if (isLog(block) || (doLeaves && isLeaf(block))) {
delayMul = 1;
if (isRoomForHarvest()) {
if (consumeEnergyFromBooster(cost, false)) {
if (consumeEnergyFromLaserMediums(cost, false)) {
if (isLog(block)) {
delayMul = 4;
totalHarvested++;
@ -101,7 +99,7 @@ public class TileEntityLaserTreeFarm extends TileEntityAbstractMiner {
}
} else if(mode == 2) {
int cost = calculateBlockCost(block);
if (consumeEnergyFromBooster(cost, true)) {
if (consumeEnergyFromLaserMediums(cost, true)) {
if (isRoomForHarvest()) {
if (block.isAssociatedBlock(WarpDriveConfig.IC2_rubberWood)) {
int metadata = worldObj.getBlockMetadata(pos.x, pos.y, pos.z);
@ -109,7 +107,7 @@ public class TileEntityLaserTreeFarm extends TileEntityAbstractMiner {
if (WarpDriveConfig.LOGGING_COLLECTION) {
WarpDrive.logger.info("wetspot found");
}
if (consumeEnergyFromBooster(cost, false)) {
if (consumeEnergyFromLaserMediums(cost, false)) {
ItemStack resin = WarpDriveConfig.IC2_Resin.copy();
resin.stackSize = (int) Math.round(Math.random() * 4);
dumpToInv(resin);
@ -124,7 +122,7 @@ public class TileEntityLaserTreeFarm extends TileEntityAbstractMiner {
delayMul = 1;
}
} else if (isLog(block)) {
if (consumeEnergyFromBooster(cost, false)) {
if (consumeEnergyFromLaserMediums(cost, false)) {
delayMul = 4;
totalHarvested++;
harvestBlock(pos);
@ -132,7 +130,7 @@ public class TileEntityLaserTreeFarm extends TileEntityAbstractMiner {
return;
}
} else if (isLeaf(block)) {
if (consumeEnergyFromBooster(cost, true)) {
if (consumeEnergyFromLaserMediums(cost, false)) {
delayMul = 1;
harvestBlock(pos);
} else {
@ -246,7 +244,8 @@ public class TileEntityLaserTreeFarm extends TileEntityAbstractMiner {
@Override
@Optional.Method(modid = "ComputerCraft")
public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments) {
String methodName = methodsArray[method];
String methodName = getMethodName(method);
if (methodName.equals("start")) {
if (!active) {
mode = 0;
@ -279,7 +278,7 @@ public class TileEntityLaserTreeFarm extends TileEntityAbstractMiner {
doLeaves = toBool(arguments[0]);
}
} catch(Exception e) {
}
return new Boolean[] { doLeaves };
@ -315,7 +314,8 @@ public class TileEntityLaserTreeFarm extends TileEntityAbstractMiner {
String state = active ? (mode==0?"scanning" : (mode == 1 ? "harvesting" : "tapping")) : "inactive";
return new Object[] { state, radiusX, radiusZ, energy(), totalHarvested };
}
return null;
return super.callMethod(computer, context, method, arguments);
}
//ABSTRACT LASER IMPLEMENTATION

View file

@ -19,8 +19,7 @@ import net.minecraftforge.fluids.FluidRegistry;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Optional;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.block.TileEntityAbstractInterfaced;
import cr0s.warpdrive.block.TileEntityLaserMedium;
import cr0s.warpdrive.block.TileEntityAbstractLaser;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.data.Vector3;
import cr0s.warpdrive.data.VectorI;
@ -28,10 +27,8 @@ import cr0s.warpdrive.network.PacketHandler;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.peripheral.IComputerAccess;
public class TileEntityMiningLaser extends TileEntityAbstractInterfaced {
// particle booster relative position
private int dx, dz, dy;
public class TileEntityMiningLaser extends TileEntityAbstractLaser {
private boolean isMining() {
return currentState != STATE_IDLE;
}
@ -58,8 +55,16 @@ public class TileEntityMiningLaser extends TileEntityAbstractInterfaced {
public TileEntityMiningLaser() {
super();
peripheralName = "warpdriveMiningLaser";
methodsArray = new String[] { "mine", "stop", "isMining", "quarry", "state", "offset" };
addMethods(new String[] {
"mine",
"stop",
"isMining",
"quarry",
"state",
"offset"
});
CC_scripts = Arrays.asList("mine", "stop");
countMaxLaserMediums = WarpDriveConfig.MINING_LASER_MAX_MEDIUMS_COUNT;
}
@Override
@ -95,7 +100,7 @@ public class TileEntityMiningLaser extends TileEntityAbstractInterfaced {
delayTicksScan++;
if (delayTicksScan == 1) {
// check power level
enoughPower = consumeEnergyPacketFromBooster(isOnEarth ? WarpDriveConfig.MINING_LASER_PLANET_ENERGY_PER_LAYER : WarpDriveConfig.MINING_LASER_SPACE_ENERGY_PER_LAYER, true);
enoughPower = consumeEnergyFromLaserMediums(isOnEarth ? WarpDriveConfig.MINING_LASER_PLANET_ENERGY_PER_LAYER : WarpDriveConfig.MINING_LASER_SPACE_ENERGY_PER_LAYER, true);
if (!enoughPower) {
updateMetadata(BlockMiningLaser.ICON_SCANNINGLOWPOWER);
delayTicksScan = 0;
@ -103,6 +108,7 @@ public class TileEntityMiningLaser extends TileEntityAbstractInterfaced {
} else {
updateMetadata(BlockMiningLaser.ICON_SCANNINGPOWERED);
}
// show current layer
int age = Math.max(40, 5 * WarpDriveConfig.MINING_LASER_SCAN_DELAY_TICKS);
double xmax = xCoord + WarpDriveConfig.MINING_LASER_RADIUS_BLOCKS + 1.0D;
@ -114,20 +120,23 @@ public class TileEntityMiningLaser extends TileEntityAbstractInterfaced {
PacketHandler.sendBeamPacket(worldObj, new Vector3(xmax, y, zmin), new Vector3(xmax, y, zmax), 0.3F, 0.0F, 1.0F, age, 0, 50);
PacketHandler.sendBeamPacket(worldObj, new Vector3(xmax, y, zmax), new Vector3(xmin, y, zmax), 0.3F, 0.0F, 1.0F, age, 0, 50);
PacketHandler.sendBeamPacket(worldObj, new Vector3(xmin, y, zmax), new Vector3(xmin, y, zmin), 0.3F, 0.0F, 1.0F, age, 0, 50);
} else if (delayTicksScan >= WarpDriveConfig.MINING_LASER_SCAN_DELAY_TICKS) {
delayTicksScan = 0;
if (currentLayer <= 0) {
stop();
return;
}
// consume power
enoughPower = consumeEnergyPacketFromBooster(isOnEarth ? WarpDriveConfig.MINING_LASER_PLANET_ENERGY_PER_LAYER : WarpDriveConfig.MINING_LASER_SPACE_ENERGY_PER_LAYER, false);
enoughPower = consumeEnergyFromLaserMediums(isOnEarth ? WarpDriveConfig.MINING_LASER_PLANET_ENERGY_PER_LAYER : WarpDriveConfig.MINING_LASER_SPACE_ENERGY_PER_LAYER, false);
if (!enoughPower) {
updateMetadata(BlockMiningLaser.ICON_SCANNINGLOWPOWER);
return;
} else {
updateMetadata(BlockMiningLaser.ICON_SCANNINGPOWERED);
}
// scan
scanLayer();
if (valuablesInLayer.size() > 0) {
@ -148,6 +157,7 @@ public class TileEntityMiningLaser extends TileEntityAbstractInterfaced {
currentState = STATE_MINING;
updateMetadata(BlockMiningLaser.ICON_MININGPOWERED);
return;
} else {
worldObj.playSoundEffect(xCoord + 0.5f, yCoord, zCoord + 0.5f, "warpdrive:lowlaser", 4F, 1F);
currentLayer--;
@ -157,11 +167,12 @@ public class TileEntityMiningLaser extends TileEntityAbstractInterfaced {
delayTicksMine++;
if (delayTicksMine >= WarpDriveConfig.MINING_LASER_MINE_DELAY_TICKS) {
delayTicksMine = 0;
if (valuableIndex >= valuablesInLayer.size()) {
delayTicksScan = 0;
currentState = STATE_SCANNING;
updateMetadata(BlockMiningLaser.ICON_SCANNINGPOWERED);
// rescan same layer
scanLayer();
if (valuablesInLayer.size() <= 0) {
@ -169,23 +180,24 @@ public class TileEntityMiningLaser extends TileEntityAbstractInterfaced {
}
return;
}
// consume power
enoughPower = consumeEnergyPacketFromBooster(isOnEarth ? WarpDriveConfig.MINING_LASER_PLANET_ENERGY_PER_BLOCK : WarpDriveConfig.MINING_LASER_SPACE_ENERGY_PER_BLOCK, false);
enoughPower = consumeEnergyFromLaserMediums(isOnEarth ? WarpDriveConfig.MINING_LASER_PLANET_ENERGY_PER_BLOCK : WarpDriveConfig.MINING_LASER_SPACE_ENERGY_PER_BLOCK, false);
if (!enoughPower) {
updateMetadata(BlockMiningLaser.ICON_MININGLOWPOWER);
return;
} else {
updateMetadata(BlockMiningLaser.ICON_MININGPOWERED);
}
// System.out.println("[ML] Mining: " + (valuableIndex + 1) + "/" + valuablesInLayer.size());
VectorI valuable = valuablesInLayer.get(valuableIndex);
valuableIndex++;
// Mine valuable ore
Block block = worldObj.getBlock(valuable.x, valuable.y, valuable.z);
// Skip if block is too hard or its empty block (check again in
// case it changed)
// Skip if block is too hard or its empty block (check again in case it changed)
if (!canDig(block, valuable.x, valuable.y, valuable.z)) {
delayTicksMine = Math.round(WarpDriveConfig.MINING_LASER_MINE_DELAY_TICKS * 0.8F);
}
@ -478,74 +490,6 @@ public class TileEntityMiningLaser extends TileEntityAbstractInterfaced {
}
}
private int getEnergyLevel() {
TileEntityLaserMedium booster = findFirstBooster();
if (booster != null) {
return booster.getEnergyStored();
} else {
return 0;
}
}
private boolean consumeEnergyPacketFromBooster(int amount, boolean simulate) {
TileEntityLaserMedium booster = findFirstBooster();
if (booster != null) {
return booster.consumeEnergy(amount, simulate);
} else {
return false;
}
}
private TileEntityLaserMedium findFirstBooster() {// FIXME: merge me...
TileEntity result;
result = worldObj.getTileEntity(xCoord + 1, yCoord, zCoord);
if (result != null && result instanceof TileEntityLaserMedium) {
dx = 1;
dz = 0;
dy = 0;
return (TileEntityLaserMedium) result;
}
result = worldObj.getTileEntity(xCoord - 1, yCoord, zCoord);
if (result != null && result instanceof TileEntityLaserMedium) {
dx = -1;
dz = 0;
dy = 0;
return (TileEntityLaserMedium) result;
}
result = worldObj.getTileEntity(xCoord, yCoord, zCoord + 1);
if (result != null && result instanceof TileEntityLaserMedium) {
dx = 0;
dz = 1;
dy = 0;
return (TileEntityLaserMedium) result;
}
result = worldObj.getTileEntity(xCoord, yCoord, zCoord - 1);
if (result != null && result instanceof TileEntityLaserMedium) {
dx = 0;
dz = -1;
dy = 0;
return (TileEntityLaserMedium) result;
}
result = worldObj.getTileEntity(xCoord, yCoord + 1, zCoord);
if (result != null && result instanceof TileEntityLaserMedium) {
dx = 0;
dz = 0;
dy = 1;
return (TileEntityLaserMedium) result;
}
return null;
}
@Override
public void readFromNBT(NBTTagCompound tag) {
super.readFromNBT(tag);
@ -632,7 +576,7 @@ public class TileEntityMiningLaser extends TileEntityAbstractInterfaced {
}
private Object[] state(Object[] arguments) {
int energy = getEnergyLevel();
int energy = getEnergyStored();
String status = getStatus();
Integer retValuablesInLayer, retValuablesMined;
if (isMining()) {
@ -659,35 +603,33 @@ public class TileEntityMiningLaser extends TileEntityAbstractInterfaced {
@Override
@Optional.Method(modid = "ComputerCraft")
public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments) {
String methodName = methodsArray[method];
String methodName = getMethodName(method);
if (methodName.equals("mine")) {
return mine(arguments);
} else if (methodName.equals("stop")) {
stop();
} else if (methodName.equals("isMining")) {
return new Boolean[] { isMining() };
} else if (methodName.equals("quarry")) {
return quarry(arguments);
} else if (methodName.equals("state")) { // State is: state, energy,
// currentLayer,
// valuablesMined,
// valuablesInLayer =
// getMinerState()
// currentLayer, valuablesMined, valuablesInLayer = getMinerState()
return state(arguments);
} else if (methodName.equals("offset")) {
return offset(arguments);
}
return null;
return super.callMethod(computer, context, method, arguments);
}
public String getStatus() {
int energy = 0;
energy = getEnergyLevel();
int energy = getEnergyStored();
String state = "IDLE (not mining)";
if (currentState == STATE_IDLE) {
state = "IDLE (not mining)";