Improved cloaking usability
- coil linking is visible before finishing the setup - central prism is slightly larger - LUA API gives explicit missing coils Reduced lag induced from poorly written LUA scripts Removed concurrent access to the world Fixed an edge case where some areas wouldn't refresh after uncloaking
This commit is contained in:
parent
417c43489b
commit
3dbbf302a6
9 changed files with 288 additions and 217 deletions
|
@ -9,6 +9,7 @@ import net.minecraft.block.material.Material;
|
|||
import net.minecraft.client.renderer.texture.IIconRegister;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
@ -16,6 +17,14 @@ import net.minecraftforge.common.util.ForgeDirection;
|
|||
|
||||
public class BlockCloakingCoil extends Block {
|
||||
|
||||
// Metadata values
|
||||
// 0 = not linked
|
||||
// 1 = inner coil passive
|
||||
// 2-7 = outer coil passive
|
||||
// 8 = (not used)
|
||||
// 9 = inner coil active
|
||||
// 10-15 = outer coil active
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
private IIcon[] iconBuffer;
|
||||
|
||||
|
@ -27,85 +36,55 @@ public class BlockCloakingCoil extends Block {
|
|||
setBlockName("warpdrive.detection.CloakingCoil");
|
||||
}
|
||||
|
||||
static final boolean oldTextures = true;
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public void registerBlockIcons(IIconRegister iconRegister) {
|
||||
iconBuffer = new IIcon[4];
|
||||
if (oldTextures) {
|
||||
iconBuffer[0] = iconRegister.registerIcon("warpdrive:detection/cloakingCoilSide");
|
||||
iconBuffer[1] = iconRegister.registerIcon("warpdrive:detection/cloakingCoilSideActive");
|
||||
iconBuffer[2] = iconRegister.registerIcon("warpdrive:detection/cloakingCoilTop");
|
||||
iconBuffer[0] = iconRegister.registerIcon("warpdrive:detection/cloaking_coil-channeling_inactive");
|
||||
iconBuffer[1] = iconRegister.registerIcon("warpdrive:detection/cloaking_coil-projecting_inactive");
|
||||
iconBuffer[2] = iconRegister.registerIcon("warpdrive:detection/cloaking_coil-channeling_active");
|
||||
iconBuffer[3] = iconRegister.registerIcon("warpdrive:detection/cloaking_coil-projecting_active");
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public IIcon getIcon(final IBlockAccess blockAccess, final int x, final int y, final int z, final int side) {
|
||||
final int metadata = blockAccess.getBlockMetadata(x, y, z);
|
||||
|
||||
// not linked or in inventory
|
||||
if (metadata == 0) {
|
||||
return iconBuffer[1];
|
||||
}
|
||||
|
||||
// inner coils
|
||||
if (metadata == 1) {
|
||||
return iconBuffer[0];
|
||||
} else if (metadata == 9) {
|
||||
return iconBuffer[2];
|
||||
}
|
||||
|
||||
// outer coils
|
||||
final int direction = (metadata & 7) - 2;
|
||||
final int activeOffset = (metadata < 8) ? 0 : 2;
|
||||
if (ForgeDirection.OPPOSITES[direction] == side) {
|
||||
return iconBuffer[ activeOffset];
|
||||
} else {
|
||||
iconBuffer[0] = iconRegister.registerIcon("warpdrive:detection/cloakingCoilInPassive");
|
||||
iconBuffer[1] = iconRegister.registerIcon("warpdrive:detection/cloakingCoilOutPassive");
|
||||
iconBuffer[2] = iconRegister.registerIcon("warpdrive:detection/cloakingCoilInActive");
|
||||
iconBuffer[3] = iconRegister.registerIcon("warpdrive:detection/cloakingCoilOutActive");
|
||||
return iconBuffer[1 + activeOffset];
|
||||
}
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public IIcon getIcon(int side, int metadata) {
|
||||
// Metadata values
|
||||
// 0 = not linked
|
||||
// 1 = inner coil passive
|
||||
// 2-7 = outer coil passive
|
||||
// 8 = (not used)
|
||||
// 9 = inner coil active
|
||||
// 10-15 = outer coil active
|
||||
if (oldTextures) {
|
||||
if (side == 0) {
|
||||
return iconBuffer[2];
|
||||
} else if (side == 1) {
|
||||
return iconBuffer[2];
|
||||
}
|
||||
if (metadata < 8) {
|
||||
return iconBuffer[0];
|
||||
} else {
|
||||
return iconBuffer[1];
|
||||
}
|
||||
public IIcon getIcon(final int side, final int metadata) {
|
||||
if (side == 3) {
|
||||
return iconBuffer[0];
|
||||
} else {
|
||||
// not linked or in inventory
|
||||
if (metadata == 0) {
|
||||
if (side == 2) {
|
||||
return iconBuffer[0];
|
||||
} else {
|
||||
return iconBuffer[1];
|
||||
}
|
||||
}
|
||||
|
||||
// inner coils
|
||||
if (metadata == 1) {
|
||||
return iconBuffer[0];
|
||||
} else if (metadata == 9) {
|
||||
return iconBuffer[2];
|
||||
}
|
||||
|
||||
// outer coils
|
||||
int direction = (metadata & 7) - 2;
|
||||
int activeOffset = (metadata < 8) ? 0 : 2;
|
||||
if (ForgeDirection.OPPOSITES[direction] == side) {
|
||||
return iconBuffer[0 + activeOffset];
|
||||
} else {
|
||||
return iconBuffer[1 + activeOffset];
|
||||
}
|
||||
return iconBuffer[1];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quantity of items to drop on block destruction.
|
||||
*/
|
||||
@Override
|
||||
public int quantityDropped(Random par1Random) {
|
||||
public int quantityDropped(final Random random) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of the items to drop on destruction.
|
||||
*/
|
||||
@Override
|
||||
public Item getItemDropped(int par1, Random par2Random, int par3) {
|
||||
return Item.getItemFromBlock(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,14 +97,14 @@ public class BlockCloakingCore extends BlockAbstractContainer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void breakBlock(World par1World, int par2, int par3, int par4, Block par5, int par6) {
|
||||
TileEntity te = par1World.getTileEntity(par2, par3, par4);
|
||||
public void breakBlock(final World world, final int x, final int y, final int z, final Block block, final int metadata) {
|
||||
final TileEntity tileEntity = world.getTileEntity(x, y, z);
|
||||
|
||||
if (te != null && te instanceof TileEntityCloakingCore) {
|
||||
((TileEntityCloakingCore)te).isEnabled = false;
|
||||
((TileEntityCloakingCore)te).disableCloakingField();
|
||||
if (tileEntity != null && tileEntity instanceof TileEntityCloakingCore) {
|
||||
((TileEntityCloakingCore) tileEntity).isEnabled = false;
|
||||
((TileEntityCloakingCore) tileEntity).disableCloakingField();
|
||||
}
|
||||
|
||||
super.breakBlock(par1World, par2, par3, par4, par5, par6);
|
||||
super.breakBlock(world, x, y, z, block, metadata);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,9 @@ import net.minecraftforge.common.util.ForgeDirection;
|
|||
public class TileEntityCloakingCore extends TileEntityAbstractEnergy {
|
||||
|
||||
private static final int CLOAKING_CORE_SOUND_UPDATE_TICKS = 40;
|
||||
private static final int DISTANCE_INNER_COILS_BLOCKS = 2;
|
||||
private static final int LASER_REFRESH_TICKS = 100;
|
||||
private static final int LASER_DURATION_TICKS = 110;
|
||||
|
||||
public boolean isEnabled = false;
|
||||
public byte tier = 1; // cloaking field tier, 1 or 2
|
||||
|
@ -36,18 +39,20 @@ public class TileEntityCloakingCore extends TileEntityAbstractEnergy {
|
|||
final float[] innerCoilColor_b = { 0.25f, 0.00f, 0.00f, 0.00f, 0.00f, 0.00f, 0.50f, 1.00f, 1.00f, 1.00f, 1.00f, 0.75f };
|
||||
|
||||
// Spatial cloaking field parameters
|
||||
private static final int innerCoilsDistance = 2; // Step length from core block to main coils
|
||||
private final int[] outerCoilsDistance = {0, 0, 0, 0, 0, 0};
|
||||
public int minX = 0;
|
||||
public int minY = 0;
|
||||
public int minZ = 0;
|
||||
public int maxX = 0;
|
||||
public int maxY = 0;
|
||||
public int maxZ = 0;
|
||||
private final boolean[] isValidInnerCoils = { false, false, false, false, false, false };
|
||||
private final int[] distanceOuterCoils_blocks = { 0, 0, 0, 0, 0, 0 }; // 0 means invalid
|
||||
private int minX = 0;
|
||||
private int minY = 0;
|
||||
private int minZ = 0;
|
||||
private int maxX = 0;
|
||||
private int maxY = 0;
|
||||
private int maxZ = 0;
|
||||
|
||||
public boolean isValid = false;
|
||||
public boolean isCloaking = false;
|
||||
public int volume = 0;
|
||||
private boolean isValid = false;
|
||||
private String messageValidityIssues = "";
|
||||
private boolean isCloaking = false;
|
||||
private int volume = 0;
|
||||
private int energyRequired = 0;
|
||||
private int updateTicks = 0;
|
||||
private int laserDrawingTicks = 0;
|
||||
|
||||
|
@ -80,6 +85,8 @@ public class TileEntityCloakingCore extends TileEntityAbstractEnergy {
|
|||
soundPlayed = false;
|
||||
}
|
||||
|
||||
boolean isRefreshNeeded = false;
|
||||
|
||||
updateTicks--;
|
||||
if (updateTicks <= 0) {
|
||||
if (WarpDriveConfig.LOGGING_CLOAKING) {
|
||||
|
@ -87,7 +94,8 @@ public class TileEntityCloakingCore extends TileEntityAbstractEnergy {
|
|||
}
|
||||
updateTicks = ((tier == 1) ? 20 : (tier == 2) ? 10 : 20) * WarpDriveConfig.CLOAKING_FIELD_REFRESH_INTERVAL_SECONDS; // resetting timer
|
||||
|
||||
isValid = validateAssembly();
|
||||
isRefreshNeeded = validateAssembly();
|
||||
|
||||
isCloaking = WarpDrive.cloaks.isAreaExists(worldObj, xCoord, yCoord, zCoord);
|
||||
if (!isEnabled) {// disabled
|
||||
if (isCloaking) {// disabled, cloaking => stop cloaking
|
||||
|
@ -95,14 +103,21 @@ public class TileEntityCloakingCore extends TileEntityAbstractEnergy {
|
|||
WarpDrive.logger.info(this + " Disabled, cloak field going down...");
|
||||
}
|
||||
disableCloakingField();
|
||||
} else {// disabled, no cloaking
|
||||
isRefreshNeeded = true;
|
||||
} else {// disabled, not cloaking
|
||||
// IDLE
|
||||
if (isRefreshNeeded) {
|
||||
setCoilsState(false);
|
||||
}
|
||||
}
|
||||
|
||||
} else {// isEnabled
|
||||
boolean hasEnoughPower = countBlocksAndConsumeEnergy();
|
||||
updateVolumeAndEnergyRequired();
|
||||
final boolean hasEnoughPower = energy_consume(energyRequired, false);
|
||||
if (!isCloaking) {// enabled, not cloaking
|
||||
if (hasEnoughPower && isValid) {// enabled, can cloak and able to
|
||||
setCoilsState(true);
|
||||
isRefreshNeeded = true;
|
||||
|
||||
// Register cloak
|
||||
WarpDrive.cloaks.updateCloakedArea(worldObj,
|
||||
|
@ -122,16 +137,21 @@ public class TileEntityCloakingCore extends TileEntityAbstractEnergy {
|
|||
WarpDrive.logger.info("getCloakedArea1 returned null for " + worldObj + " " + xCoord + "," + yCoord + "," + zCoord);
|
||||
}
|
||||
}
|
||||
} else {// enabled, not cloaking but not able to
|
||||
|
||||
} else {// enabled, not cloaking and not able to
|
||||
// IDLE
|
||||
setCoilsState(false);
|
||||
}
|
||||
} else {// enabled & cloaked
|
||||
|
||||
} else {// enabled & cloaking
|
||||
if (!isValid) {// enabled, cloaking but invalid
|
||||
if (WarpDriveConfig.LOGGING_CLOAKING) {
|
||||
WarpDrive.logger.info(this + " Coil(s) lost, cloak field is collapsing...");
|
||||
}
|
||||
energy_consume(energy_getEnergyStored());
|
||||
disableCloakingField();
|
||||
disableCloakingField();
|
||||
isRefreshNeeded = true;
|
||||
|
||||
} else {// enabled, cloaking and valid
|
||||
if (hasEnoughPower) {// enabled, cloaking and able to
|
||||
// IDLE
|
||||
|
@ -145,19 +165,22 @@ public class TileEntityCloakingCore extends TileEntityAbstractEnergy {
|
|||
}
|
||||
}
|
||||
setCoilsState(true);
|
||||
|
||||
} else {// loosing power
|
||||
if (WarpDriveConfig.LOGGING_CLOAKING) {
|
||||
WarpDrive.logger.info(this + " Low power, cloak field is collapsing...");
|
||||
}
|
||||
disableCloakingField();
|
||||
isRefreshNeeded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (laserDrawingTicks++ > 100) {
|
||||
laserDrawingTicks = 0;
|
||||
laserDrawingTicks--;
|
||||
if (isRefreshNeeded || laserDrawingTicks < 0) {
|
||||
laserDrawingTicks = LASER_REFRESH_TICKS;
|
||||
|
||||
if (isEnabled && isValid) {
|
||||
drawLasers();
|
||||
|
@ -169,20 +192,29 @@ public class TileEntityCloakingCore extends TileEntityAbstractEnergy {
|
|||
worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, (enabled) ? 1 : 0, 2);
|
||||
|
||||
for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) {
|
||||
setCoilState(innerCoilsDistance, direction, enabled);
|
||||
setCoilState(outerCoilsDistance[direction.ordinal()], direction, enabled);
|
||||
if (isValidInnerCoils[direction.ordinal()]) {
|
||||
setCoilState(DISTANCE_INNER_COILS_BLOCKS, direction, enabled);
|
||||
}
|
||||
if (distanceOuterCoils_blocks[direction.ordinal()] > 0) {
|
||||
setCoilState(distanceOuterCoils_blocks[direction.ordinal()], direction, enabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setCoilState(final int distance, final ForgeDirection direction, final boolean enabled) {
|
||||
int x = xCoord + distance * direction.offsetX;
|
||||
int y = yCoord + distance * direction.offsetY;
|
||||
int z = zCoord + distance * direction.offsetZ;
|
||||
final int x = xCoord + distance * direction.offsetX;
|
||||
final int y = yCoord + distance * direction.offsetY;
|
||||
final int z = zCoord + distance * direction.offsetZ;
|
||||
if (worldObj.getBlock(x, y, z).isAssociatedBlock(WarpDrive.blockCloakingCoil)) {
|
||||
if (distance == innerCoilsDistance) {
|
||||
worldObj.setBlockMetadataWithNotify(x, y, z, ((enabled) ? 9 : 1), 2);
|
||||
final int metadata_current = worldObj.getBlockMetadata(x, y, z);
|
||||
final int metadata_new;
|
||||
if (distance == DISTANCE_INNER_COILS_BLOCKS) {
|
||||
metadata_new = (enabled ? 9 : 1);
|
||||
} else {
|
||||
worldObj.setBlockMetadataWithNotify(x, y, z, ((enabled) ? 10 : 2) + direction.ordinal(), 2);
|
||||
metadata_new = (enabled ? 10 : 2) + direction.ordinal();
|
||||
}
|
||||
if (metadata_current != metadata_new) {
|
||||
worldObj.setBlockMetadataWithNotify(x, y, z, metadata_new, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -196,9 +228,9 @@ public class TileEntityCloakingCore extends TileEntityAbstractEnergy {
|
|||
g = 0.50f;
|
||||
b = 0.50f;
|
||||
} else if (tier == 1) {
|
||||
r = 0.25f;
|
||||
r = 0.00f;
|
||||
g = 1.00f;
|
||||
b = 0.00f;
|
||||
b = 0.25f;
|
||||
} else if (tier == 2) {
|
||||
r = 0.00f;
|
||||
g = 0.25f;
|
||||
|
@ -207,24 +239,27 @@ public class TileEntityCloakingCore extends TileEntityAbstractEnergy {
|
|||
|
||||
// Directions to check (all six directions: left, right, up, down, front, back)
|
||||
for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) {
|
||||
PacketHandler.sendBeamPacketToPlayersInArea(worldObj,
|
||||
new Vector3(
|
||||
xCoord + innerCoilsDistance * direction.offsetX,
|
||||
yCoord + innerCoilsDistance * direction.offsetY,
|
||||
zCoord + innerCoilsDistance * direction.offsetZ).translate(0.5),
|
||||
new Vector3(
|
||||
xCoord + outerCoilsDistance[direction.ordinal()] * direction.offsetX,
|
||||
yCoord + outerCoilsDistance[direction.ordinal()] * direction.offsetY,
|
||||
zCoord + outerCoilsDistance[direction.ordinal()] * direction.offsetZ).translate(0.5),
|
||||
r, g, b, 110, 0,
|
||||
AxisAlignedBB.getBoundingBox(minX, minY, minZ, maxX, maxY, maxZ));
|
||||
if ( isValidInnerCoils[direction.ordinal()]
|
||||
&& distanceOuterCoils_blocks[direction.ordinal()] > 0) {
|
||||
PacketHandler.sendBeamPacketToPlayersInArea(worldObj,
|
||||
new Vector3(
|
||||
xCoord + 0.5D + (DISTANCE_INNER_COILS_BLOCKS + 0.3D) * direction.offsetX,
|
||||
yCoord + 0.5D + (DISTANCE_INNER_COILS_BLOCKS + 0.3D) * direction.offsetY,
|
||||
zCoord + 0.5D + (DISTANCE_INNER_COILS_BLOCKS + 0.3D) * direction.offsetZ),
|
||||
new Vector3(
|
||||
xCoord + 0.5D + distanceOuterCoils_blocks[direction.ordinal()] * direction.offsetX,
|
||||
yCoord + 0.5D + distanceOuterCoils_blocks[direction.ordinal()] * direction.offsetY,
|
||||
zCoord + 0.5D + distanceOuterCoils_blocks[direction.ordinal()] * direction.offsetZ),
|
||||
r, g, b, LASER_DURATION_TICKS, 0,
|
||||
AxisAlignedBB.getBoundingBox(minX, minY, minZ, maxX, maxY, maxZ));
|
||||
}
|
||||
}
|
||||
|
||||
// draw connecting coils
|
||||
for (int i = 0; i < 5; i++) {
|
||||
ForgeDirection start = ForgeDirection.VALID_DIRECTIONS[i];
|
||||
final ForgeDirection start = ForgeDirection.VALID_DIRECTIONS[i];
|
||||
for (int j = i + 1; j < 6; j++) {
|
||||
ForgeDirection stop = ForgeDirection.VALID_DIRECTIONS[j];
|
||||
final ForgeDirection stop = ForgeDirection.VALID_DIRECTIONS[j];
|
||||
// skip mirrored coils (removing the inner lines)
|
||||
if (start.getOpposite() == stop) {
|
||||
continue;
|
||||
|
@ -237,9 +272,15 @@ public class TileEntityCloakingCore extends TileEntityAbstractEnergy {
|
|||
b = innerCoilColor_b[mapIndex];
|
||||
|
||||
PacketHandler.sendBeamPacketToPlayersInArea(worldObj,
|
||||
new Vector3(xCoord + innerCoilsDistance * start.offsetX, yCoord + innerCoilsDistance * start.offsetY, zCoord + innerCoilsDistance * start.offsetZ).translate(0.5),
|
||||
new Vector3(xCoord + innerCoilsDistance * stop .offsetX, yCoord + innerCoilsDistance * stop .offsetY, zCoord + innerCoilsDistance * stop .offsetZ).translate(0.5),
|
||||
r, g, b, 110, 0,
|
||||
new Vector3(
|
||||
xCoord + 0.5D + (DISTANCE_INNER_COILS_BLOCKS + 0.3D) * start.offsetX + 0.2D * stop .offsetX,
|
||||
yCoord + 0.5D + (DISTANCE_INNER_COILS_BLOCKS + 0.3D) * start.offsetY + 0.2D * stop .offsetY,
|
||||
zCoord + 0.5D + (DISTANCE_INNER_COILS_BLOCKS + 0.3D) * start.offsetZ + 0.2D * stop .offsetZ),
|
||||
new Vector3(
|
||||
xCoord + 0.5D + (DISTANCE_INNER_COILS_BLOCKS + 0.3D) * stop .offsetX + 0.2D * start.offsetX,
|
||||
yCoord + 0.5D + (DISTANCE_INNER_COILS_BLOCKS + 0.3D) * stop .offsetY + 0.2D * start.offsetY,
|
||||
zCoord + 0.5D + (DISTANCE_INNER_COILS_BLOCKS + 0.3D) * stop .offsetZ + 0.2D * start.offsetZ),
|
||||
r, g, b, LASER_DURATION_TICKS, 0,
|
||||
AxisAlignedBB.getBoundingBox(minX, minY, minZ, maxX, maxY, maxZ));
|
||||
}
|
||||
}
|
||||
|
@ -257,35 +298,41 @@ public class TileEntityCloakingCore extends TileEntityAbstractEnergy {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean countBlocksAndConsumeEnergy() {
|
||||
int x, y, z, energyToConsume;
|
||||
volume = 0;
|
||||
public void updateVolumeAndEnergyRequired() {
|
||||
int x, y, z;
|
||||
int energyRequired_new;
|
||||
int volume_new = 0;
|
||||
if (tier == 1) {// tier1 = gaz and air blocks don't count
|
||||
for (y = minY; y <= maxY; y++) {
|
||||
for (x = minX; x <= maxX; x++) {
|
||||
for(z = minZ; z <= maxZ; z++) {
|
||||
if (!worldObj.isAirBlock(x, y, z)) {
|
||||
volume++;
|
||||
volume_new++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
energyToConsume = volume * WarpDriveConfig.CLOAKING_TIER1_ENERGY_PER_BLOCK;
|
||||
energyRequired_new = volume_new * WarpDriveConfig.CLOAKING_TIER1_ENERGY_PER_BLOCK;
|
||||
} else {// tier2 = everything counts
|
||||
for (y = minY; y <= maxY; y++) {
|
||||
for (x = minX; x <= maxX; x++) {
|
||||
for(z = minZ; z <= maxZ; z++) {
|
||||
if (!worldObj.getBlock(x, y, z) .isAssociatedBlock(Blocks.air)) {
|
||||
volume++;
|
||||
if (worldObj.getBlock(x, y, z) != Blocks.air) {
|
||||
volume_new++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
energyToConsume = volume * WarpDriveConfig.CLOAKING_TIER2_ENERGY_PER_BLOCK;
|
||||
energyRequired_new = volume_new * WarpDriveConfig.CLOAKING_TIER2_ENERGY_PER_BLOCK;
|
||||
}
|
||||
|
||||
// WarpDrive.logger.info(this + " Consuming " + energyToConsume + " EU for " + blocksCount + " blocks");
|
||||
return energy_consume(energyToConsume, false);
|
||||
volume = volume_new;
|
||||
energyRequired = energyRequired_new;
|
||||
|
||||
if (WarpDriveConfig.LOGGING_ENERGY) {
|
||||
WarpDrive.logger.info(String.format("%s Requiring %d EU for %d blocks",
|
||||
this, energyRequired, volume));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -303,65 +350,101 @@ public class TileEntityCloakingCore extends TileEntityAbstractEnergy {
|
|||
}
|
||||
|
||||
public boolean validateAssembly() {
|
||||
final int maxOuterCoilDistance = WarpDriveConfig.CLOAKING_MAX_FIELD_RADIUS - WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS;
|
||||
final int maxOuterCoilDistance = WarpDriveConfig.CLOAKING_MAX_FIELD_RADIUS - WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS;
|
||||
boolean isRefreshNeeded = false;
|
||||
int countIntegrity = 1; // 1 for the core + 1 per coil
|
||||
final StringBuilder messageInnerCoils = new StringBuilder();
|
||||
final StringBuilder messageOuterCoils = new StringBuilder();
|
||||
|
||||
// Directions to check (all six directions: left, right, up, down, front, back)
|
||||
for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) {
|
||||
|
||||
// check validity of inner coil
|
||||
int x = xCoord + innerCoilsDistance * direction.offsetX;
|
||||
int y = yCoord + innerCoilsDistance * direction.offsetY;
|
||||
int z = zCoord + innerCoilsDistance * direction.offsetZ;
|
||||
if (worldObj.getBlock(x, y, z).isAssociatedBlock(WarpDrive.blockCloakingCoil)) {
|
||||
worldObj.setBlockMetadataWithNotify(x, y, z, 1, 2);
|
||||
int x = xCoord + DISTANCE_INNER_COILS_BLOCKS * direction.offsetX;
|
||||
int y = yCoord + DISTANCE_INNER_COILS_BLOCKS * direction.offsetY;
|
||||
int z = zCoord + DISTANCE_INNER_COILS_BLOCKS * direction.offsetZ;
|
||||
final boolean isInnerValid = (worldObj.getBlock(x, y, z) == WarpDrive.blockCloakingCoil);
|
||||
|
||||
// whenever a change is detected, force a laser redraw
|
||||
if (isInnerValid != isValidInnerCoils[direction.ordinal()]) {
|
||||
isRefreshNeeded = true;
|
||||
isValidInnerCoils[direction.ordinal()] = isInnerValid;
|
||||
}
|
||||
|
||||
// update validity results
|
||||
if (isValidInnerCoils[direction.ordinal()]) {
|
||||
countIntegrity++;
|
||||
} else {
|
||||
return false;
|
||||
if (messageInnerCoils.length() != 0) {
|
||||
messageInnerCoils.append(", ");
|
||||
}
|
||||
messageInnerCoils.append(direction.name());
|
||||
}
|
||||
|
||||
// find closest outer coil
|
||||
int newCoilDistance = 0;
|
||||
for (int distance = 3; distance < maxOuterCoilDistance; distance++) {
|
||||
for (int distance = DISTANCE_INNER_COILS_BLOCKS + 1; distance < maxOuterCoilDistance; distance++) {
|
||||
x += direction.offsetX;
|
||||
y += direction.offsetY;
|
||||
z += direction.offsetZ;
|
||||
|
||||
if (worldObj.getBlock(x, y, z).isAssociatedBlock(WarpDrive.blockCloakingCoil)) {
|
||||
worldObj.setBlockMetadataWithNotify(x, y, z, 2 + direction.ordinal(), 2);
|
||||
if (worldObj.getBlock(x, y, z) == WarpDrive.blockCloakingCoil) {
|
||||
newCoilDistance = distance;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// disable previous outer coil, in case a different one was found
|
||||
int oldCoilDistance = outerCoilsDistance[direction.ordinal()];
|
||||
if ( newCoilDistance != oldCoilDistance && oldCoilDistance > 0) {
|
||||
int oldX = xCoord + oldCoilDistance * direction.offsetX;
|
||||
int oldY = yCoord + oldCoilDistance * direction.offsetY;
|
||||
int oldZ = zCoord + oldCoilDistance * direction.offsetZ;
|
||||
if (worldObj.getBlock(oldX, oldY, oldZ).isAssociatedBlock(WarpDrive.blockCloakingCoil)) {
|
||||
worldObj.setBlockMetadataWithNotify(oldX, oldY, oldZ, 0, 2);
|
||||
// whenever a change is detected, disable previous outer coil if it was valid and force a laser redraw
|
||||
final int oldCoilDistance = distanceOuterCoils_blocks[direction.ordinal()];
|
||||
if (newCoilDistance != oldCoilDistance) {
|
||||
if (oldCoilDistance > 0) {
|
||||
final int oldX = xCoord + oldCoilDistance * direction.offsetX;
|
||||
final int oldY = yCoord + oldCoilDistance * direction.offsetY;
|
||||
final int oldZ = zCoord + oldCoilDistance * direction.offsetZ;
|
||||
if (worldObj.getBlock(oldX, oldY, oldZ) == WarpDrive.blockCloakingCoil) {
|
||||
worldObj.setBlockMetadataWithNotify(oldX, oldY, oldZ, 0, 2);
|
||||
}
|
||||
}
|
||||
isRefreshNeeded = true;
|
||||
distanceOuterCoils_blocks[direction.ordinal()] = Math.max(0, newCoilDistance);
|
||||
}
|
||||
|
||||
// check validity and save new coil position
|
||||
if (newCoilDistance <= 0) {
|
||||
outerCoilsDistance[direction.ordinal()] = 0;
|
||||
if (WarpDriveConfig.LOGGING_CLOAKING) {
|
||||
WarpDrive.logger.info("Invalid outer coil assembly at " + direction);
|
||||
// update validity results
|
||||
if (newCoilDistance > 0) {
|
||||
countIntegrity++;
|
||||
} else {
|
||||
if (messageOuterCoils.length() != 0) {
|
||||
messageOuterCoils.append(", ");
|
||||
}
|
||||
return false;
|
||||
messageOuterCoils.append(direction.name());
|
||||
}
|
||||
outerCoilsDistance[direction.ordinal()] = newCoilDistance;
|
||||
}
|
||||
|
||||
// Update cloaking field parameters defined by coils
|
||||
minX = xCoord - outerCoilsDistance[4] - WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS;
|
||||
maxX = xCoord + outerCoilsDistance[5] + WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS;
|
||||
minY = Math.max( 0, yCoord - outerCoilsDistance[0] - WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS);
|
||||
maxY = Math.min(255, yCoord + outerCoilsDistance[1] + WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS);
|
||||
minZ = zCoord - outerCoilsDistance[2] - WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS;
|
||||
maxZ = zCoord + outerCoilsDistance[3] + WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS;
|
||||
return true;
|
||||
// build status message
|
||||
final float integrity = countIntegrity / 13.0F;
|
||||
if (messageInnerCoils.length() > 0 && messageOuterCoils.length() > 0) {
|
||||
messageValidityIssues = StatCollector.translateToLocalFormatted("warpdrive.cloakingCore.missingInnerAndOuter",
|
||||
Math.round(100.0F * integrity), messageInnerCoils, messageOuterCoils);
|
||||
} else if (messageInnerCoils.length() > 0) {
|
||||
messageValidityIssues = StatCollector.translateToLocalFormatted("warpdrive.cloakingCore.missingInner",
|
||||
Math.round(100.0F * integrity), messageInnerCoils);
|
||||
} else if (messageOuterCoils.length() > 0) {
|
||||
messageValidityIssues = StatCollector.translateToLocalFormatted("warpdrive.cloakingCore.missingOuter",
|
||||
Math.round(100.0F * integrity), messageOuterCoils);
|
||||
} else {
|
||||
messageValidityIssues = StatCollector.translateToLocalFormatted("warpdrive.cloakingCore.valid");
|
||||
}
|
||||
|
||||
// Update cloaking field parameters defined by coils
|
||||
isValid = countIntegrity >= 13;
|
||||
minX = xCoord - distanceOuterCoils_blocks[4] - WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS;
|
||||
maxX = xCoord + distanceOuterCoils_blocks[5] + WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS;
|
||||
minY = Math.max( 0, yCoord - distanceOuterCoils_blocks[0] - WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS);
|
||||
maxY = Math.min(255, yCoord + distanceOuterCoils_blocks[1] + WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS);
|
||||
minZ = zCoord - distanceOuterCoils_blocks[2] - WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS;
|
||||
maxZ = zCoord + distanceOuterCoils_blocks[3] + WarpDriveConfig.CLOAKING_COIL_CAPTURE_BLOCKS;
|
||||
|
||||
return isRefreshNeeded;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -372,7 +455,7 @@ public class TileEntityCloakingCore extends TileEntityAbstractEnergy {
|
|||
|
||||
final String unlocalizedStatus;
|
||||
if (!isValid) {
|
||||
unlocalizedStatus = "warpdrive.cloakingCore.invalidAssembly";
|
||||
unlocalizedStatus = messageValidityIssues;
|
||||
} else if (!isEnabled) {
|
||||
unlocalizedStatus = "warpdrive.cloakingCore.disabled";
|
||||
} else if (!isCloaking) {
|
||||
|
@ -386,64 +469,71 @@ public class TileEntityCloakingCore extends TileEntityAbstractEnergy {
|
|||
volume);
|
||||
}
|
||||
|
||||
// OpenComputer callback methods
|
||||
@Callback
|
||||
@Optional.Method(modid = "OpenComputers")
|
||||
public Object[] tier(Context context, Arguments arguments) {
|
||||
if (arguments.count() == 1) {
|
||||
if (arguments.checkInteger(0) == 2) {
|
||||
// Common OC/CC methods
|
||||
public Object[] tier(Object[] arguments) {
|
||||
if (arguments.length == 1) {
|
||||
int tier_new;
|
||||
try {
|
||||
tier_new = Commons.toInt(arguments[0]);
|
||||
} catch(Exception exception) {
|
||||
return new Integer[] { (int) tier };
|
||||
}
|
||||
if (tier_new == 2) {
|
||||
tier = 2;
|
||||
} else {
|
||||
tier = 1;
|
||||
}
|
||||
markDirty();
|
||||
}
|
||||
return new Integer[] { (int)tier };
|
||||
return new Integer[] { (int) tier };
|
||||
}
|
||||
|
||||
public Object[] isAssemblyValid() {
|
||||
return new Object[] { isValid, Commons.removeFormatting(messageValidityIssues) };
|
||||
}
|
||||
|
||||
public Object[] enable(Object[] arguments) {
|
||||
if (arguments.length == 1) {
|
||||
isEnabled = Commons.toBool(arguments[0]);
|
||||
markDirty();
|
||||
}
|
||||
return new Object[] { isEnabled };
|
||||
}
|
||||
|
||||
// OpenComputer callback methods
|
||||
@Callback
|
||||
@Optional.Method(modid = "OpenComputers")
|
||||
public Object[] tier(Context context, Arguments arguments) {
|
||||
return tier(argumentsOCtoCC(arguments));
|
||||
}
|
||||
|
||||
@Callback
|
||||
@Optional.Method(modid = "OpenComputers")
|
||||
public Object[] isAssemblyValid(Context context, Arguments arguments) {
|
||||
return new Object[] { validateAssembly() };
|
||||
return isAssemblyValid();
|
||||
}
|
||||
|
||||
@Callback
|
||||
@Optional.Method(modid = "OpenComputers")
|
||||
public Object[] enable(Context context, Arguments arguments) {
|
||||
if (arguments.count() == 1) {
|
||||
isEnabled = arguments.checkBoolean(0);
|
||||
markDirty();
|
||||
}
|
||||
return new Object[] { isEnabled };
|
||||
return enable(argumentsOCtoCC(arguments));
|
||||
}
|
||||
|
||||
// ComputerCraft IPeripheral methods implementation
|
||||
@Override
|
||||
@Optional.Method(modid = "ComputerCraft")
|
||||
public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments) {
|
||||
String methodName = getMethodName(method);
|
||||
final String methodName = getMethodName(method);
|
||||
|
||||
switch (methodName) {
|
||||
case "tier":
|
||||
if (arguments.length == 1) {
|
||||
if (Commons.toInt(arguments[0]) == 2) {
|
||||
tier = 2;
|
||||
} else {
|
||||
tier = 1;
|
||||
}
|
||||
markDirty();
|
||||
}
|
||||
return new Integer[] { (int) tier };
|
||||
|
||||
case "isAssemblyValid":
|
||||
return new Object[] { validateAssembly() };
|
||||
|
||||
case "enable":
|
||||
if (arguments.length == 1) {
|
||||
isEnabled = Commons.toBool(arguments[0]);
|
||||
markDirty();
|
||||
}
|
||||
return new Object[] { isEnabled };
|
||||
case "tier":
|
||||
return tier(arguments);
|
||||
|
||||
case "isAssemblyValid":
|
||||
return isAssemblyValid();
|
||||
|
||||
case "enable":
|
||||
return enable(arguments);
|
||||
}
|
||||
|
||||
return super.callMethod(computer, context, method, arguments);
|
||||
|
|
|
@ -135,14 +135,11 @@ public class CloakedArea {
|
|||
|
||||
if (Math.abs(dX) < RADIUS && Math.abs(dY) < RADIUS && Math.abs(dZ) < RADIUS) {
|
||||
if (decloak) {
|
||||
PacketHandler.sendCloakPacket(entityPlayerMP, this, true);
|
||||
revealChunksToPlayer(entityPlayerMP);
|
||||
revealEntitiesToPlayer(entityPlayerMP);
|
||||
}
|
||||
|
||||
if (!isEntityWithinArea(entityPlayerMP) && !decloak) {
|
||||
} else if (!isEntityWithinArea(entityPlayerMP)) {
|
||||
PacketHandler.sendCloakPacket(entityPlayerMP, this, false);
|
||||
} else if (decloak) {
|
||||
PacketHandler.sendCloakPacket(entityPlayerMP, this, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,14 +21,15 @@ if cloakingCore == nil then
|
|||
else
|
||||
cloakingCore.tier(1)
|
||||
cloakingCore.enable(true)
|
||||
if cloakingCore.isAssemblyValid() then
|
||||
local isValid, message = cloakingCore.isAssemblyValid()
|
||||
if isValid then
|
||||
term.setBackgroundColor(colors.lime)
|
||||
term.setTextColor(colors.blue)
|
||||
term.write("Tier 1 cloaking is enabled")
|
||||
else
|
||||
term.setBackgroundColor(colors.red)
|
||||
term.setTextColor(colors.white)
|
||||
term.write("Invalid cloaking assembly!")
|
||||
print(message)
|
||||
term.setBackgroundColor(colors.black)
|
||||
term.setTextColor(colors.white)
|
||||
print()
|
||||
|
|
|
@ -21,14 +21,15 @@ if cloakingCore == nil then
|
|||
else
|
||||
cloakingCore.tier(2)
|
||||
cloakingCore.enable(true)
|
||||
if cloakingCore.isAssemblyValid() then
|
||||
local isValid, message = cloakingCore.isAssemblyValid()
|
||||
if isValid then
|
||||
term.setBackgroundColor(colors.lime)
|
||||
term.setTextColor(colors.red)
|
||||
term.write("Tier 2 cloaking is enabled")
|
||||
else
|
||||
term.setBackgroundColor(colors.red)
|
||||
term.setTextColor(colors.white)
|
||||
term.write("Invalid cloaking assembly!")
|
||||
print(message)
|
||||
term.setBackgroundColor(colors.black)
|
||||
term.setTextColor(colors.white)
|
||||
print()
|
||||
|
|
|
@ -4,13 +4,14 @@ local term = require("term")
|
|||
if not component.isAvailable("warpdriveCloakingCore") then
|
||||
print("No cloaking core detected")
|
||||
else
|
||||
local cloakingcore = component.warpdriveCloakingCore
|
||||
cloakingcore.tier(1)
|
||||
cloakingcore.enable(true)
|
||||
if cloakingcore.isAssemblyValid() then
|
||||
local cloakingCore = component.warpdriveCloakingCore
|
||||
cloakingCore.tier(1)
|
||||
cloakingCore.enable(true)
|
||||
local isValid, message = cloakingCore.isAssemblyValid()
|
||||
if isValid then
|
||||
print("Tier 1 cloaking is enabled")
|
||||
else
|
||||
print("Invalid cloaking assembly")
|
||||
print(message)
|
||||
print()
|
||||
print("In each of the 6 directions, you need to place exactly 2 Cloaking coils, for a total of 12 coils.")
|
||||
print("The 6 inner coils shall be exactly one block away from the core.")
|
||||
|
|
|
@ -4,13 +4,14 @@ local term = require("term")
|
|||
if not component.isAvailable("warpdriveCloakingCore") then
|
||||
print("No cloaking core detected")
|
||||
else
|
||||
local cloakingcore = component.warpdriveCloakingCore
|
||||
cloakingcore.tier(2)
|
||||
cloakingcore.enable(true)
|
||||
if cloakingcore.isAssemblyValid() then
|
||||
local cloakingCore = component.warpdriveCloakingCore
|
||||
cloakingCore.tier(2)
|
||||
cloakingCore.enable(true)
|
||||
local isValid, message = cloakingCore.isAssemblyValid()
|
||||
if isValid then
|
||||
print("Tier 2 cloaking is enabled")
|
||||
else
|
||||
print("Invalid cloaking assembly")
|
||||
print(message)
|
||||
print()
|
||||
print("In each of the 6 directions, you need to place exactly 2 Cloaking coils, for a total of 12 coils.")
|
||||
print("The 6 inner coils shall be exactly one block away from the core.")
|
||||
|
|
|
@ -3,13 +3,14 @@ local component = require("component")
|
|||
if not component.isAvailable("warpdriveCloakingCore") then
|
||||
print("No cloaking core detected")
|
||||
else
|
||||
local cloakingcore = component.warpdriveCloakingCore
|
||||
cloakingcore.tier(2)
|
||||
cloakingcore.enable(true)
|
||||
if cloakingcore.isAssemblyValid() then
|
||||
local cloakingCore = component.warpdriveCloakingCore
|
||||
cloakingCore.tier(2)
|
||||
cloakingCore.enable(true)
|
||||
local isValid, message = cloakingCore.isAssemblyValid()
|
||||
if isValid then
|
||||
print("Cloaking is disabled")
|
||||
else
|
||||
print("Invalid assembly")
|
||||
print(message)
|
||||
print()
|
||||
print("In each of the 6 directions, you need to place exactly 2 Cloaking device coils, for a total of 12 coils.")
|
||||
print("The 6 inner coils shall be exactly one block away from the core.")
|
||||
|
|
Loading…
Reference in a new issue